« Back

Liferay.com, mobile sites and responsive layouts

Staff Blogs May 22, 2011 By Nate Cavanaugh Staff

Bryan recently blogged about the new site design and how Liferay.com is displaying a mobile formatted website for different types of devices (go ahead and test it out, hop into any browser and resize the page as small as it can go). Today I want to discuss a bit how we achieved this from a technical level. This is one of the most common questions I not only got from people who attended our East Coast Symposium, but also inside of Liferay from other devs.

Liferay.com can resize from desktop to mobile dynamically

Because we like to keep our ear to the ground on all things front end, we’ve actually been following the discussion/debate about responsive web design since Ethan Marcotte published his article on the subject last year. If you haven’t read the article, the tl;dr version is that using CSS media queries, it’s possible to pass a different set of CSS styles to different devices and have a design that’s customized for a specific browser/device size.

As far as mobile strategies go, it’s probably the easiest to implement, and there are a lot of quick wins with it. However, Jon Neal pointed out to me when we were first discussing this idea that there’s very little difference between using CSS media queries and just using Javascript to simulate the same thing.

I’ve since read other people bring up a similar point, and it’s a fair one. In fact, there are multiple issues with CSS media queries that make them cumbersome. For instance, let’s say we want to share some styling across two specific devices. It’s possible using the logical operators but even then, you end up with duplicate CSS (and it becomes much harder to read). And the fact that IE doesn’t support media queries was another major impediment to us using it, so we were going to need to use JavaScript anyways (either to add the CSS classnames or to parse mediaqueries).

So Jon wrote up a script that would handle this logic for us. Here’s how the script works: When the page is loaded or resized, the script checks the width of the window and it looks into an object of 4 major size specifications; 960, 720, 480, and 320.

What do those numbers mean? 960px is based on the uber-popular 960 grids which is a layout width that looks great on most desktop computers, and the iPad in landscape mode. 720px is a layout width that looks great when the iPad is in portrait mode. 480px is the width of the window of most smart phones in landscape mode. 320px is the width of the window of most smart phones in portrait mode.

The other great thing Jon came up with was to add greater-than and less-than css classes. I’ll show how this works in a second, but the idea is basically, you can not only target a specific device width, but also if it’s greater than or less than any of those above widths.

If your target device is 600x800, you can still target that device with the css classes.

With what Jon prototyped, I’ve created an Alloy module that codifies this so that it’s super easy to use (while at the same time, staying out of the way for users who don’t wish to use it).

For a quick and simple demo, open up the viewport demo (if you view it in Chrome or Safari, Firefox or Opera, you’ll see some cool CSS3 generated content/animation, but the demo works in any browser).

To get the module to run, all you need to do is call: AUI().use('aui-viewport') in a script tag anywhere on your page.

Now you can target your site design to specific device sizes. Let’s say we want to give our navigation items to sit side by side when we view on the ipad or larger, but that we want to have them stack on smart phones:

#navigation li {
    display: inline;
    float: left;
}
.aui-view-lt720 #navigation li {
    display: block;
    float: none;
}

or let’s say we don’t want to make sure our images don’t exceed a certain width on the iPad in portrait mode

.aui-view-720 img {
    max-width: 300px
}

Or perhaps we want to target just portrait mode of smartphones and tablets:

.aui-view-720 body, .aui-view-320 body {
    background: #ccc;
}

You can even combine this with our other browser selectors to target very specific browsers:

.touch.aui-view-lt720 {} /* Touch based smartphones */
.webkit.aui-view-lt960 {} /* Webkit based tablets and smartphones */
.win.aui-view-720 {} /* Smaller browser views on just Windows */

Now, how is the logic applied? If the screen is equal to or between any of our defined widths, it will get this CSS class: aui-view-{WIDTH}. And, if the screen is greater than any of our widths, it will also get: aui-view-gt{WIDTH}. Lastly, if the screen is less than any of our widths, it will also get: aui-view-lt{WIDTH}.

So a window size of 1900x1200 would get:

aui-view-gt320
aui-view-gt480
aui-view-gt720
aui-view-gt960
aui-view-960

whereas a window size of 800x600 would get:

aui-view-gt320
aui-view-gt480
aui-view-gt720
aui-view-720
aui-view-lt960

Notice that the classes represent the width rounded down to the nearest division. This is to guarantee that your styled layout won’t exceed the current width. Because of that the css class doesn’t exactly represent the current width, but rather enforces you to think about the layout at specified sizes and devices.

Caveats

Life is not all cheese and bananas with this system, as there are some caveats to be aware of:

  • You are delivering the same content to all devices.

    Depending on the project, this could either seal the deal or break it. There’s an added cost to shipping down different images for the same page, and some mobile websites may wish to send only a very limited set of content to mobile devices (or perhaps very targeted content). The answer to this then is decide which of the 2 strategies you wish to use for your specific project: same content for all devices, but dimension specific designs, or redirect to a mobile/touch specific community that serves a targeted set of content and design.

  • Designs can require more planning for each of the design layouts

    You’ll notice that the design now has to accommodate basically 4 different views: desktop, tablet(portrait), and smartphone (portrait and landscape). This of course means thinking about a different set of design compromises and layouts for how the same content should fit (or which content should be hidden) for different types of views. Of course, this caveat extends to both content strategies, but having the same content automatically in every view often requires a bit more forethought during the design process.

How can you get this module?

If you’re an Enterprise Edition customer, this module will be available in the 6.0 SP2 service pack (and the great part is, if you don’t want to use it, it will have 0 affect on your application). If you’re running Community Edition, this will be in Liferay 6.1 or if you’re running trunk of Liferay you can see it today. We’ll also be releasing another version of AlloyUI soon that will have it included.

Conclusions

Overall, the response has been great, and the design/development process was surprisingly smooth. I would recommend it as a general principle for your design, as it helps our designs fit the fluid nature of the web.

More information

Responsive Web Design by Ethan Marcotte
MediaQueri.es
The practicalities of CSS Media Queries, lessons learned.

Threaded Replies Author Date
Thanks Nate! Your blogs are always packed with... Deb Troxel May 23, 2011 7:45 AM
Nice article Nate. One question - does mobile... Szymon Gołębiewski May 24, 2011 1:30 AM
Thanks nate, nice article. Is there any YUI... Wasim Shaikh May 24, 2011 3:15 AM
@Szymon: In this case, it can work with any of... Nate Cavanaugh May 24, 2011 7:49 AM
Nice article Nate..Thanks for sharing... Jay Patel May 25, 2011 5:05 AM
Thanks Nate. This is a great step. I guess... Shagul Khajamohideen June 2, 2011 3:28 AM
Very Nice Demo and Article Nate !!!! Thanks Jignesh Vachhani June 12, 2011 10:15 PM
This is a great feature and I got it to work... Gem E August 3, 2011 4:51 PM
Dear Nate, <br> I want to use my own... Hossein Oloomi November 13, 2011 7:15 AM
Thanks for providing this helpful tutorial on... Suraj Bihari November 15, 2011 1:25 PM
Really gr8 stuff :) Nagendra Kumar Busam December 12, 2011 11:14 PM
Nate, Thanks very much for this; however, I... Ben Chapman December 16, 2011 6:42 AM
Hi Ben, Thanks for reaching out. The only thing... Nate Cavanaugh December 16, 2011 12:10 PM
[...] Override  ServicePre() in... Anonymous February 9, 2012 3:52 AM
Has this been carried over to 6.1? I do not see... Dave Weitzel March 8, 2012 8:02 AM
Nate this is really great stuff. Have you run... Steve C Groninga March 13, 2012 3:44 PM
Hi Steve, I have run into an issue on Retina... Nate Cavanaugh March 13, 2012 3:50 PM
And Dave, yes this module is inside of 6.1 as... Nate Cavanaugh March 13, 2012 3:51 PM
Nate, Thanks for this tip! My initial tests... Steve C Groninga March 16, 2012 10:33 AM
[...] Hi, I've been asked to research the... Anonymous May 24, 2012 6:05 AM
[...] Here is exactly what you need:... Anonymous May 24, 2012 1:35 PM
[...] Here is exactly what you need:... Anonymous May 25, 2012 1:00 AM
Hi , We have been trying to build a mobile... Md Mohiuddin July 10, 2012 11:41 PM
Hi, What would I need to do to have my theme... Mathon Gijsbers van Wijk July 11, 2012 12:31 AM
[...] Sokat hallani mostanában a Responsive Web... Anonymous August 7, 2012 5:23 AM
Hi, sorry for bothering but i don't know where... Rui Maciel August 27, 2012 9:43 AM
Hi Rui, If you place it in your theme's main.js... Nate Cavanaugh August 27, 2012 10:06 AM
Many thanks!! I will try that =D Rui Maciel August 27, 2012 10:08 AM
Sorry to bother again Nate but in the forum,... Rui Maciel August 27, 2012 6:09 PM
Nate, I resolved my issue, i just change the... Rui Maciel August 28, 2012 9:19 AM
I have found a BIG problem with responsive... Dave Weitzel August 28, 2012 12:56 PM
Hi Dave, This is something on CKEditor's side.... Nate Cavanaugh August 29, 2012 10:07 AM
Great Work Nate Cavanaugh !! Useful Article... Subhash Pavuskar September 23, 2012 9:57 PM
This is a great feature. Could we get sample... M. Ahamed Maqbool October 1, 2012 2:13 AM
where say for two levels of nav, I envision ... Jack Bakker November 6, 2012 7:38 AM
this is cool ;... Jack Bakker November 6, 2012 8:04 AM
This is so cool! Thanks for your post and for... Mario Grimaldi November 8, 2012 12:55 PM
Hey Nate Cavanaugh, Impressive article! Is... Kushal Jayswal November 19, 2012 12:02 AM
[...] Another approach is to use responsive... Anonymous March 12, 2013 1:58 AM
Hi Nate, is it possible to create a responsive... Juan Antonio Girón July 22, 2013 1:12 AM
Yes. It's possible Juan. You need to overwrite... Kushal Jayswal July 22, 2013 1:16 AM
Thanks Kushal, could you give me an example or... Juan Antonio Girón July 22, 2013 1:30 AM
Sorry I cannot let you know the site name. But... Kushal Jayswal July 22, 2013 1:39 AM
Many thanks Kushal, I'll try it. Juan Antonio Girón July 22, 2013 1:44 AM

Thanks Nate! Your blogs are always packed with great info.
Posted on 5/23/11 7:45 AM.
Nice article Nate. One question - does mobile theme works with all portlet or am I limited to just some of them?
Posted on 5/24/11 1:30 AM.
Thanks nate, nice article.
Is there any YUI plugin availale for this? I want to use it in simple htmls.

Thanks,
Wasim Shaikh,
http://microblog.wasimshaikh.com
Posted on 5/24/11 3:15 AM.
@Szymon:
In this case, it can work with any of them. Basically, it just depends on what portlets you'll style in which view. For some mobile devices, some portlets might make less sense (for instance, a flash portlet wouldn't work so well on most smart phones these days). But since its just CSS, the possibilities are pretty wide emoticon

@wasim:
Not yet, but I'll be pushing this one over to the YUI Gallery, so as soon as it's up, I can let you know emoticon

Thanks all!
Posted on 5/24/11 7:49 AM in reply to wasim shaikh.
Nice article Nate..Thanks for sharing...
Posted on 5/25/11 5:05 AM.
Thanks Nate. This is a great step. I guess Jorge and team are addressing the different content for different devices part.
Posted on 6/2/11 3:28 AM.
Very Nice Demo and Article Nate !!!! Thanks
Posted on 6/12/11 10:15 PM.
This is a great feature and I got it to work nicely on my liferay except that it isn't getting picked up on the iphone (haven't tried it on an ipad yet). I noticed the viewport demo doesn't work correctly on the iphone either (it's being treated as desktop size 960px) - do you know why this may be?
Posted on 8/3/11 4:51 PM.
Dear Nate,
<br>
I want to use my own JavaScript calendar and date picker instead of aui-calendar and aui-datepicker all over Liferay. I want to replace my js files with those of aui, but clearly this will not work; what functions should my files have and what should they return?
<br>
Thanks in advance
Posted on 11/13/11 7:15 AM.
Thanks for providing this helpful tutorial on responsive layouts. Olaf tipped this during the developer course!
Posted on 11/15/11 1:25 PM.
Really gr8 stuff emoticon
Posted on 12/12/11 11:14 PM.
Nate,

Thanks very much for this; however, I must not be doing something quite right as it doesn't seem to have any effect on our pages.

Where would I put the call to AUI().use('aui-viewport')? I've tried doing it in the script section of the page (Manage>Page>Script), but that does not result in generating the expected classes in the HTML. We are EE customers and I can see that AUI().use... is inserted in the source of the HTML, but that's it.

Can you provide a pointer to further information?

Many thanks and sorry for the very basic question!
Posted on 12/16/11 6:42 AM.
Hi Ben,
Thanks for reaching out. The only thing I can think of that would cause this not to work is perhaps the version of EE you have isn't the latest service pack? This component was included in a service pack, so it's not available in earlier ones.
If you get in touch with your account rep, they can probably get you a patch that would include just the files you need for this feature.

If you are on the latest service pack and it's still no go, you can either get in touch with support to help debug your specific case, or you can create a forum thread and paste the link here and I'll take a look at it and see if I can spot anything.

Thanks Ben,
Posted on 12/16/11 12:10 PM in reply to Ben Chapman.
[...] Override  ServicePre() in ServicePreAction.java to incorporate check for the isMobile() and if found true use Wap theme. Override html/../layout/view/portlet.jsp to include check for isMobile() and if... [...] Read More
Posted on 2/9/12 3:52 AM.
Has this been carried over to 6.1? I do not see anything in CE 6.1 GA1. If not can someone write a log about the mobile device rules and what they are how to use them and examples?
Would prefer the view-port was there so we don't have to do much with more guidance on how to use in custom themes
Posted on 3/8/12 8:02 AM.
Nate this is really great stuff. Have you run into the following: works great on the desktop monitor (able to minimize browser window and the alternate css is used), but fails on an actual handheld device... ( iPhone, android, etc....)
Posted on 3/13/12 3:44 PM.
Hi Steve,
I have run into an issue on Retina screens where the reported size wasn't being properly handled.
In those cases, I had to set something like the following in the head of the document:
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;" />

Let me know if that helps.

Thanks,
Posted on 3/13/12 3:50 PM in reply to Steve C Groninga.
And Dave, yes this module is inside of 6.1 as well. As long as you call AUI().use('aui-viewport') in your theme, you should be good to go.

HTH,
Posted on 3/13/12 3:51 PM in reply to Nate Cavanaugh.
Nate, Thanks for this tip! My initial tests seem to work perfectly! Now on to redesigning for these devices/smaller screens! Well Done! This certainly has a far reaching impact!

Steve

<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;" />
Posted on 3/16/12 10:33 AM in reply to Nate Cavanaugh.
[...] Hi, I've been asked to research the feasibility of creating a responsive layout ( a la Liferay.com ) for our existing Liferay installation. For info currently we use: Liferay Portal Standard Edition... [...] Read More
Posted on 5/24/12 6:05 AM.
[...] Here is exactly what you need: http://www.liferay.com/web/nathan.cavanaugh/blog/-/blogs/liferay-com-mobile-site­s-and-responsive-layouts Marcar como inapropiado Por favor, identifíquese para poder... [...] Read More
Posted on 5/24/12 1:35 PM.
[...] Here is exactly what you need: http://www.liferay.com/web/nathan.cavanaugh/blog/-/blogs/liferay-com-mobile-site­s-and-responsive-layouts Flag Please sign in to flag this as inappropriate. Mark as an... [...] Read More
Posted on 5/25/12 1:00 AM.
Hi ,

We have been trying to build a mobile theme in Liferay using repsonsive web design.
We have included the line : AUI().use('aui-viewport'); within script tags and also included : <meta name="viewport" content="target-densitydpi=160dpi, width=device-width, minimum-scale=1, maximum-scale=1"> within the <head> tags of portal_normal.vm
The theme is working fine on Android , Nokia ,Apple mobiles but gives issues on Blackberry (OS 4).We have tested it on firefox browser for BB 8520 and the problem is that the web site rendered as a full site on Blackberry Firefox and does not use responsive layout.The client's major requirement is that the mobile theme should open up on Blackberry.

Any suggestions in this regard will be highly welcome.Need urgent help on this.


Regards,
Md. Mohiuddin
Posted on 7/10/12 11:41 PM in reply to .
Hi,

What would I need to do to have my theme support a width of 240 px?

Thanks, Mathon
Posted on 7/11/12 12:31 AM in reply to Md Mohiuddin.
[...] Sokat hallani mostanában a Responsive Web Design-ról. Aki esetleg nem tudja, mit is jelent, annak röviden megfogalmazva, különböző felbontásokhoz egyedi stíluslapokat, stílusbejegyzéseket rendelünk,... [...] Read More
Posted on 8/7/12 5:23 AM.
Hi, sorry for bothering but i don't know where to put the AUI().use('aui-viewport') declaration (i have already tried to put in a script inside a custom portlet but nothing happens). I just want my portal to adjust it size to the browser window. I have the liferay-portal-6.1.0-ce-ga1 version. Please can somebody help me?
Posted on 8/27/12 9:43 AM.
Hi Rui,
If you place it in your theme's main.js it should work.

However, as mentioned above, what this does is add CSS classes to the HTML element. For the styling to actually change, you'll need to add CSS for those sizes to determine how it should look.

I hope that helps emoticon
Posted on 8/27/12 10:06 AM in reply to Rui Maciel.
Many thanks!! I will try that =D
Posted on 8/27/12 10:08 AM in reply to Nate Cavanaugh.
Sorry to bother again Nate but in the forum, they told me that the classic theme from the liferay portal has already this feature. I have the liferay portal CE 6.1.0 version but in my case that's not true. Is there any theme with this feature that i could download? Many thanks
Posted on 8/27/12 6:09 PM.
Nate, I resolved my issue, i just change the custom.css file in the ROOT of the portal.
in "wrapper"
i change the
min-width: 960px;
to
min-width: 320px;

Thanks for all!
Posted on 8/28/12 9:19 AM in reply to Rui Maciel.
I have found a BIG problem with responsive design with OOTB Liferay 6.1 GA1 not sure if in GA2.

the WYSIWYG editor puts full style conditions for images - it sets height and width styles (generally a no no anyway). As these are at the element level they cannot be overridden by say aui-view-lt720 img {max-width:50%"} definitions in a css file.

How can we get the WYSWYG to behave in a responsive friendly manner, otherwise we have to edit the source of all our content!
Posted on 8/28/12 12:56 PM.
Hi Dave,
This is something on CKEditor's side. I'm not sure if there are any out there that are responsive friendly per-se, but if you ever find one, Liferay allows you to swap out the editor.

However, there are a couple of different ways to handle this without changing the editor:
1. In your CSS, setting max-width actually should be respected, because the inline style is being set to width, not to max-width. When I test that scenario, max-width works fine.
However, the issue with it is that the height is still set, so it will squish the image.
What you can do is:
.aui-view-lt720 img { height: auto !important; max-width: 50%; }

This should make it so that the inline style is overwritten, but the image proportions are still maintained.

2. The other option you have is to discourage or not allow images to be embedded in the editor, and instead, add a field for the image into the structure.
This is what we a lot for the Liferay.com website. Usually, there are blocks where we want a paragraph of text and some accompanying image or any number of those. We'll create a repeatable structure, and allow those to be uploaded.
In the template then we have more control over how that image is displayed with the text for the different breakpoints.

The easiest of these approaches is probably #1 as it requires the least amount of change, but #2 provides you with ultimate control.

I hope that helps emoticon
Posted on 8/29/12 10:07 AM in reply to Dave Weitzel.
Great Work Nate Cavanaugh !! Useful Article !! emoticon
Posted on 9/23/12 9:57 PM in reply to Nate Cavanaugh.
This is a great feature.
Could we get sample theme war file or in market place? its will help us.

Thank's
Posted on 10/1/12 2:13 AM.
where say for two levels of nav, I envision

for browser: show nav as usual (on mouseover of navItemLevel1 show navItemLevel2s)

for tablet portrait and less: show only navItemLevel1s where onclick/touch of navitem; go to targetted page where then only show navItemLevel2s (under the navItemLevel1 u just went to)

possible ? do themes need to be jsp for this or can this be done with velocity ?
Posted on 11/6/12 7:38 AM in reply to M. Ahamed Maqbool.
this is cool ; http://codepen.io/JasonAGross/full/kEhHm#

but not what I am thinking in my last comment as I question menus being too tall...

I think I should be posting in forum not hijacking this wiki
Posted on 11/6/12 8:04 AM in reply to Jack Bakker.
This is so cool!
Thanks for your post and for this AUI module!
Posted on 11/8/12 12:55 PM.
Hey Nate Cavanaugh,
Impressive article!

Is there any way we can use the same with less efforts, manually?

-regards:
Kushal Jayswal
http://kutec.co.in
http://teckstack.com
Posted on 11/19/12 12:02 AM.
[...] Another approach is to use responsive design Sign in to vote. Flag Please sign in to flag this as inappropriate. Mark as an Answer [...] Read More
Posted on 3/12/13 1:58 AM.
Hi Nate, is it possible to create a responsive theme in Liferay 6.0.5 CE?
Posted on 7/22/13 1:12 AM.
Yes. It's possible Juan.
You need to overwrite some default Liferay CSS and all will work fine with @media query.
Posted on 7/22/13 1:16 AM in reply to Juan Antonio Girón.
Thanks Kushal, could you give me an example or article on how to implement it?, Please.
Posted on 7/22/13 1:30 AM in reply to Kushal Jayswal.
Sorry I cannot let you know the site name.
But I can share CSS.

CSS:
-------------------------------------------------
/* common behaviour */
.portlet-layout { display: table; width: 100%; }
.portlet-column-first { padding-left: 0 !important; }
.portlet-column-last { padding-right: 0 !important; }
.portlet-column { padding: 0 1%; display: table-cell; vertical-align: top; }

/* tablet behaviour */
@media all and (min-width: 768px) and (max-width: 1024px) {
.portlet-column { padding: 0 3% 0 0; display: table-cell; }
.home .portlet-column { padding: 0 0 0 0; }
}

/* tablet behaviour - viewport change */
@media all and (max-width: 767px) {
.portlet-layout { display: block; }
.portlet-column { display: block !important; padding: 0 !important; }
}
/* smartphone behaviour */
@media all and (max-width : 480px) {
.portlet-layout { display: block; }
.portlet-column { display: block; padding: 0 !important; }
}
Posted on 7/22/13 1:39 AM in reply to Juan Antonio Girón.
Many thanks Kushal, I'll try it.
Posted on 7/22/13 1:44 AM in reply to Kushal Jayswal.