Prerequisite knowledge
 
  • Intermediate HTML/CSS/JS skills
  • Basic knowledge of web development responsive design
  • Working knowledge of AEM, AEM Authoring, and AEM Components
  • Working knowledge of using Maven to build and deploy AEM packages
User level: Intermediate
 
Required products (retail)
 
Additional requirements
 
  • AEM Server (running in Author Mode)
  • Devices/Emulators you want to test on.
  • Adobe ID
Sample files
 
By downloading software from the Adobe Web site you agree to the terms of our license agreement. Please read it before downloading.
 

 
Note: If you have questions about this article, use the DPS forum. Please don’t contact technical support with questions about Adobe Developer Connection articles.
 
 
Introduction

When developing our CMO.com app we had to think about responsive design for both our web property and how it would translate to our DPS app. This article covers basic to intermediate design and coding principles to maximize the platforms and devices you can target with digital magazines created with AEM. I will not go deep into how CSS media queries, media breakpoints, or existing responsive frameworks work, but I will cover how you can practically use them in an AEM solution to have a single code base target multiple platforms.
 
 
The Sample Code
The sample code provided has some basic examples of all the moving parts you will need for this article. The package can be imported into your preferred IDE and deployed to an AEM instance through Maven. Maven is a software project management tool which, among other things, is used to build and deploy packages to the AEM environment. For more information specifically on how to use Maven and AEM together, check out [http://dev.day.com/docs/en/cq/aem-how-tos/development/how-to-build-aem-projects-using-apache-maven.html]. For more general information on Maven and what it can do, check out http://maven.apache.org/.
 

 
Responsive Design – for Magazines. What’s different?

In short, not much. If you are familiar with the concepts of responsive design, that is to say, having your standard desktop website re-layout as it hits certain resolutions or screen sizes to provide an enjoyable browsing experience, then you are ahead of the curve. Below, I will touch on some concepts that made my life easier and hopefully yours.
 
 
Before you Start
Figure out which platforms and which layouts you are targetting.
 
Seriously, take a look at what you want to target. It will not be impossible (or really too difficult) to add in additional CSS to target additional platforms after the fact, but having a concrete place to start from both a design and coding point of view helps immensely.
 
When we started designing the CMO.com magazine, we chose to start out with iPhone 4S, iPhone 5, iPad(non-retina) and iPad(retina). Once the devices were determined, the next step is to determine which orientations you want to support. For smaller devices, we chose to target only portrait layout and opted for both landscape and portrait layout on the iPad devices.
 
 
CSS Media Queries and iPad Non-Retina vs iPad Retina
There are many articles out there that go into far more detail than I am about to regarding CSS pixel density vs Screen resolution (http://demosthenes.info/blog/564/Understanding-Pixel-Density-Resolution-and-Retina-Displays), but I am going to cover the basics of it. The  iPhone 4s (960x640) and iPhone 5 (1136x640) have similar resolutions in portrait, except for a height difference. These equate to 480x320 and 568x320 CSS pixel density.
 
iPad Non-Retina (1024x768) with a pixel ratio of 1 and iPad Retina(2048x1536) with a pixel ratio of 2 equate to the same CSS pixel density of 1024x768. This makes layout on both retina and non-retina iPads practically the same. A media query breakpoint that targets a resolution of 1024x768 will be applied to both iPads. There is an additional flag, min-device-pixel-ratio, that can be added to the media query that can be used to separate non-retina vs retina versions. To achieve a great experience, you really need to leverage these specific media queries to use high resolution versions of embedded images in your magazine.
 
If you have a style that embeds a 1024x768 image as the background of an article, this will look as you expect on your non-retina iPad, but will appear blurry on your retina iPad. To allieviate this, you can specify the same style in your min-device-pixel-ratio:2 media query and override the property to use a high resolution version of this image.
 
In short, layout properties can be pretty much the same across the board, however, images and video content should be specific.
 
 
Start Small, Go Big
A typical multiple CSS file breakdown will have a default style sheet that gets applied to everything, then additional media queries to apply specific styles and layouts to specific resolution/devices. The approach I like to take is to start with the smallest device you are targetting and then work your way up. I mean this from a UX/UI design, as well as a coding/styling perspective.
 
The components and templates that I build all start off with the default style sheet that gets applied to everything from laying out the content to target the smallest design we have. From there, all additional media queries only apply/override styles to lay the content out specifically for that resolution. This seems like one of those “it shouldn’t be a big deal”  things, but after a lot of experimentation, I found this one to work best and to have the least amount of unnessecary style overriding.
 

 
Building Responsive Templates and Components

Now we have some of the basics laid out. We know which devices and orientations we are targeting and we have some standard guidelines to follow, so we are going to move on to building a responsive template. The actual process for building a responsive template versus building a responsive component is very similar. There are many different ways to go about doing this, but the following is my preferred method after a lot of research, trial, and error.
 
 
Separating a Template Layout from Component Layout
I find there is a balance between building AEM templates that give the author enough flexibility to create what they need but not restricting them into building the same thing over and over. I find there is a similar balance separating template layout from component layout and determining who is in charge of what. For the most part, I prefer to look at components as entities that should adapt regardless of the page they are in. Templates should simply move the components around and control their overall container as required. This is an architectural principal that has been defined from the start of our project and is taken into account when new templates or components are being developed.
 
 
Looking At The ClientLib
The ClientLib function is a powerful part of AEM for keeping your code organized. When you are targeting several different orientations and resolutions, it is pretty easy for your CSS to get out of hand. Fortunately, the ClientLib functionality lets you divide the CSS into named files and then it will wrap them all together into one include. The naming convention that I like to go with is having a default style.css that contains the lowest common denominator styles; styles that pretty much apply across the board to all resolutions. From there, the files are divided up and named specifically for the platform they are targeting. You can see in the example, there are iphone-4.css, iphone-5.css, ipad-2.css and ipad-3.css files in the ClientLib folder. As you would expect, specific styles that I need to target iPhone 4 are in the iphone-4.css, the iPhone 5 styles are in iphone-5 and so on. ipad-2.css contains all the iPad specific layout CSS, whereas ipad-3.css contains only the retina specific styles that I would need to overwrite (for example, embedded images and videos).
 
Alternatively, you can rename these to a more generic approach, such as 1024x768.css and 768x1024.css. The idea here is really just to help keep the code clean and make troubleshooting styles a lot easier.
 
 
A Responsive Template Example
If we take a look at a simple article based on the example code provided, we define a few static items in the template that every article will follow, like an article title, a hero image, maybe some information about the author and then a section for content components to be placed. These static items are where I draw the line in the sand between template layout and component layout and what styles should control what.
 
The overall padding whitespace around the article is controlled by the template as well as the general spacing between elements. Since the hero image is one of those static “always there” elements of the article, the template is responsible for controlling the scale of the image as it moves between the iPad and iPhone resolutions.
 
Also, for design consistency, there is a style that gets applied to all non-hero images within the article template so they have the same look and feel. The font and decorations applied to the title and author sections of the article are defined in the template design. As the resolution changes, the template provides additional media queries to control all of these elements and the general container within the article where content components can be placed. It does not override any of the specific properties of the content components the author may drag into it.
 
Sometimes I like to set general styles in the template that will be inherited by the content components. For example, I would set a style in the template to add a 20px padding on all content components inserted by the author. This is opposite to what I just said where the template does not control the styles on the content components, but they are applied in a way where the content component can choose to override it, if it wants to.
 
 
A Responsive Component Example
One of the components the author has the ability to drop in to the article is the Quick Read component. The component is pretty basic: it has three sections of text and a different layout and some style changes for the iPad and iPhone.
 
Going back to the previous concept that the component should be responsible for how it’s laid out, the template container is expecting to have a component take up 100% of the width given, and in this case, however much height it needs. The template controls how much padding is on either side and if the content needs to be centered in the page. The components are designed with this as an understanding, so it is up to the component to determine if it should display inline and horizontally or vertically, and if the text should be center aligned or left, and everything in between. The component also is responsible for its own resolution-specific layout. The component has its own ClientLib where all this takes place and its own set of corresponding CSS files for each of the resolutions (as you can imagine, they follow the same naming convention as in the template).
 
On the iPad there is plenty of room to lay these three text boxes side by side, whereas on the iPhone, there clearly is not. Using the “Start Small, Go Big” concept earlier outlined in this article, the main style.css that has the styles applicable to everything. It lays the content out in a vertical fashion where the text boxes sit one above the other with some padding and a horizontal spacer in between (for a little design flair). There are no specific iPhone 4 or 5 styles that need to be added here, so these remain blank. The only changes I have to make for this to look like the design for the iPad is some padding; to hide the horizontal dividers and to have the text boxes stack horizontally rather than vertically. These are all straightforward layout changes and the required styles are overridden in the respective media queries.
 
The Quick Read component as it looks on the iPhone 4/5 :
 
Quick Read
The Quick Read component as it looks on an iPad:
 
Quick Read
There is a caveat here - the ‘ipad-2.css’ has two separate media queries, one for landscape and one for portrait. The styles that need to be overridden to have the Quick Read component layout correctly are identical in both of these media queries. This is not the most efficient way to have this coded. The media queries defined in the ipad-2.css are extremely narrow and specific. You can however combine these media queries to a generic iPad media query that combines the two using the following:
 
@media only screen and (min-device-width : 768px) and (max-device-height : 1024px) and (orientation : portrait), only screen and (min-device-width : 768px) and (max-device-height : 1024px) and (orientation : landscape) { .both-orientation-styles-here { } }
This can easily start to get out of hand when you start bringing in more and more platforms and sizes. I am calling this out since I know I would be asking the same question if I was reading this article and because I find myself starting to move in that direction. However, I have not quite decided on how to break up the naming conventions and organization. For the purposes of this sample it gives a starting point by simply copying and pasting the styles to both the landscape and portrait media queries. I encourage you to try things out to see what works best for you.
 
Although not 100% related to responsive design, but while we are at it, AEM does support using LESS  (more info on LESS: http://lesscss.org/) for CSS pre-processing in combination with the ClientLib concept. There are plenty of awesome articles on LESS and is a little out of scope for this article.
 

 
Conclusion

This article just touches on some of the things you can do and some of the things that I have found worked well for our design. You may find yourself having two completely different template designs for iPhone, iPad, or other mobile and tablet devices where responsive design does not make sense. In these situations it is best to go back to where I started with the article and seriously take a look at your target platforms, resolutions, and orientations and make sure your design makes sense across what you want to target.
 

Comments are currently closed as we migrate to a new commenting system. In the interim, please provide any feedback using our feedback form. Thank you for your patience.