We recently had the task of refactoring an existing Magento-based site from a traditional fixed layout to a responsive web design. The site we were refactoring was one of four sites that shared the same code base, a key feature of Magento. In fact, because the site was using theme inheritance, it depended on assets from a parent site. The other sites, including the parent, were not being refactored and were to remain as they were, which required us to be cautious and deliberate with any changes that might affect the other sites.
The site itself, its parent and its siblings, were all built on Magento’s enterprise default theme. In the past, we allowed Magento’s theme inheritance to cover the base styles and simply wrote new styles to each theme to make the sites match the approved layouts.
The refactor had the following requirements:
- The desktop view was to remain the same whenever possible.
- The updates for responsive design could not affect the other sites or assets on that shared theme.
- We should change the markup as little as possible to allow for future updates.
- We must support Internet Explorer 7 and up, Google Chrome, and Mozilla Firefox on Desktop. In addition, we had to support a range of tablets and phones as mobile devices.
The Default Theme
Perhaps the biggest hurdle to implementing responsive design in Magento is the base Magento theme. While the base theme and accompanying enterprise theme have all the necessary styles to present Magento’s many features, the styles are coded for static layouts. The styles also frequently declare colors and theme specific settings, and suffer from high specificity, which means a lot of work overwriting the default styles to the theme specific styles.
As such, the first step was to recreate a new base style sheet. This gave us an opportunity to base this and future projects on a responsive platform free of theme specific colors and styles which would just need deleted or overwritten later. It also let take a mobile first approach to our base styles, meaning we spent less time simplifying and hiding styles for mobile.
We could not, however, take the same approach with our markup (HTML and PHP). While Magento allows you to change template files (equivalent to views) on a per-theme basis, we had already highly leveraged theme inheritance in the parent site. This matters because template updates override the base and parent theme files. When Magento provides a patch or update, or when our developers add a feature or fix, the changes to these templates can easily overwrite the fixes. The fewer templates we overwrite, the fewer points of failure and less time spent applying updates.
Style Sheets and Partials
In keeping with the responsive design principles we developed and adopted while building DEG’s responsive site, we started by bringing SASS, a style sheet scripting compiler, and Compass, a set of utilities for SASS, into the project – a first for us when developing a Magento theme. These tools increase the development speed by simplifying monotonous tasks, providing automatic vendor prefixing and allowing access to variables and custom scripts. The best part is that the output is a 100% compatible style sheet.
Using these tools, we created our own set of theme partials arranged like this:
- A Responsive Base Theme: Contained all the base responsive styles for the whole site. It was built to be reusable in nearly any theme.
- Responsive Base Widget Styles: Contained styles specifically for widgets created and managed in Magento’s backend CMS. This was also designed to be reusable.
- A Theme Partial: Includes styles that are consistent across pages, such as headers, footers, backgrounds and colors. These styles were theme specific.
- Several Page Partials: For instance, styles that are only included on the home page, checkout page, etc. When necessary, these partials could be namespaced based on a class Magento specifies in each page’s body tag.
- Feature Specific Partials such as forms or modal windows that were used across multiple pages, but which had theme specific styles. This was done to isolate these styles during development.
The benefit to this approach is that while there are many individual sheets, it is very easy to tell where a style should be when something needs changed. We then leveraged Compass to compile and compress the partials into one, drastically reducing the number of requests made to the server, as well as the download size of the sheet.
Ems and Rems
Pixels are the traditional unit of sizing fonts, graphics and objects in CSS. With responsive design, designers needed a more flexible approach. Most developers adopted the Em, which is sized based on the width of the uppercase “M” character. An Em is also based on the size of its immediate parent. If the parent has a font size of 1em (in this case, let’s say it is equal to 10 pixels), and its child has a font size of 0.5em, the child would be equivalent to 5px. If that child had a child which is 0.5em, the resultant size is equivalent to 2.5px. This behavior is often desirable when designing a site from the ground up, but in a refactor it can cause frustrations when adapting old styles, where pixel values were specified but did not cascade in the same way.
As stated above, we were required to keep the desktop views as they were, which was actually the most time-consuming part of the process. The new base theme at times clashed with the old, fixed-size styles. Often, the only solution was line by line adaption of the layout; we did manage to save time when adapting certain aspects by leveraging REMs. A Relative Em (Rem) behaves like an Em but is calculated relative to the <html> tag. By setting the <html> tag’s font size, you can know the Rem’s value at any point in the cascade. Further, by setting its value as a %, it can flex with system settings.
Unfortunately, not all browsers support Rems yet, but creating a fallback was simple with SASS. We created a custom script (which is available on github) called a mixin that output the Rem value with a pixel fallback. This fallback means that Internet Explorer 7 and 8 read the pixel sizes, while all other browsers read the Rem sizes. By basing the html element on the equivalent of a 10px font size, we were able to quickly and easily adapt the old, pixel-based font sizes to responsive without needing to consider the cascade issues brought by using ems.
While we didn’t have the development budget to get Magento serving different sized images to different screen sizes, we did have several photographic, gradient heavy .png images that had alpha transparency as a requirement. This resulted in several huge (400kb +) files. This time around, we used a free tool called TinyPng to compress these files while maintaining alpha transparency. The resultant files were 50% to 70% smaller, while maintaining quality on desktop and mobile devices.
We chose not to implement sprite sheets for this design because there was very little icon or layout graphic use. On a layout with many icons or small layout images that could be displayed in a fixed size, sprite sheeting would be another way to cut down image download overhead.
Site owner-created content posed another problem. There was little we could do to refactor existing site owner created content that may not be mobile optimized, but we had a few tricks up our sleeves. First, we created mobile-only and desktop-only tags we could apply to specific items within the editor, allowing for a certain amount of flexibility based on device. Next we applied a max width style to all images output by the CMS, insuring that the owners couldn’t accidentally break the responsive design with a large image. Finally, we went through and audited the content to make sure that the site owner was not using tables to control layout.
Our last step (before significant testing) was to use Magento’s built-in style sheet combiner. Magento’s style sheet combiner on occasion introduces CSS-related rendering bugs and must be used with caution. We were already using compass to compress and combine style sheets, but using the built in combiner, we were able to leverage it as a style sheet versioning system. This meant that new users didn’t need to refresh, clear browser cache, or be faced with broken CSS from the old styles. And because we were doing the combination manually outside of Magento, we circumvented many of the potential problems the combiner introduces.