Within the question "mobile-first or desktop-first?" there's an area that we need to cover about legacy browsers. Each project, each client, and their corresponding analytics (if they have any, which they should) have different requirements that affect how we are supposed to deal with those older browsers.
If you're building with a desktop-first approach, your current workflow should remain the same as this is pretty much what we've been doing since before RWD became practically mandatory.
This means that you would still use something like this:
header {
//Desktop-first declaration
width: 50%;
@include forSmallScreens(768) {
//Target small screens (mobile devices)
width: 100%; }
}This compiles to the following:
header {
width: 50%;
}
@media (max-width: 48em) {
header {
width: 100%;
}
}IE7 and IE8 do not support media queries, but the preceding code will work just fine because the header { width: 50%; } rule is not inside a media query.
However, if you're doing mobile-first, then header { width: 50%; } is going to be inside a media query so that IE7 and IE8 won't be able to see that rule:
.article {
//Mobile-first declaration
width: 100%;
//IE7 and IE8 won't be able to see this rule.
@include forLargeScreens(768) {
width: 50%;
}
}This compiles to the following:
header {
width: 100%;
}
@media (min-width: 48em) {
header {
width: 50%;
}
}What do you do then? The solution is quite simple: use the Respond.js script.
Respond.js is a type of script called a polyfill. A polyfill, according to the one who coined the term in the first place, Remy Sharp, is a piece of code that provides the technology that we, web developers, expect browsers to provide natively.
In web design and development, polyfills are more abundant as JavaScript implementations, in our case, Scott Jehl's Respond.js. But we could also say that there are polyfills in CSS too, for example, the well-known reset.css from Eric Meyer and Normalize.css from Nicolas Gallagher and Jonathan Neal.
The Respond.js script is a polyfill that makes legacy browsers (IE6/7/8) support a particular CSS feature they were never made to support: media queries.
You can download Respond.js from https://github.com/scottjehl/Respond.
Although I'm suggesting the use of a polyfill, we need to be mindful of the additional HTTP request the site/app needs to make in order to fetch this JavaScript file. The fewer requests our sites/apps make, the faster they are going to be creating many benefits such as improved user experience and positive SEO impact.
So, here's what you need to do:
Respond.js is after the call to your CSS file(s) (hopefully it is just one CSS file).Respond.js script.Performance best practices recommend placing nonessential scripts at the bottom of the markup right before the closing </body> tag. Since Respond.js is aimed at legacy browsers, let's go ahead and do that. Another benefit of placing scripts at the bottom of the markup is that it helps to avoid blocking the rendering of the page.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Mastering RWD with HTML5 & CSS3</title>
<link href="styles.css" rel="stylesheet">
</head>
<body>
<header>Logo goes here…</header>
<article>Content goes here…</article>
<script src="js/respond.min.js"></script>
</body>
</html>In our styles.scss file, we type the following lines:
//Mobile-first declaration
article { background: red;
//Target screens 640px wide and larger
@include forLargeScreens(640) {
& { background: green; }
}
}This compiles to the following:
article {
background: red;
}
@media (min-width: 40em) {
article {
background: green;
}
}So, when you resize an IE7 or IE8 browser window, it will be able to display a red background if the window width is 640 pixels or less, and a green background if the window is 641 pixels or more.
I've avoided creating IE-specific style sheets since I started writing CSS. The reasons for this are simple:
In legacy browsers, page rendering is not blocked when they try to download the IE-specific style sheet. Also, troubleshooting is easier. So what do we use then?
There are several ways to deal with IE by keeping everything in one style sheet:
Modernizr.js.<html> tag.Let's talk a bit more about a popular method, using conditional classes.
Paul Irish's 2008 article (http://www.paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/) specifies a method that I recommend for several reasons:
This is the one I use:
<!--[if IE 8]> <html class="no-js ie8" lang="en"> <![endif]--> <!--[if IE 9]> <html class="no-js ie9" lang="en"> <![endif]--> <!--[if gt IE 9]><!--><html class="no-js" lang="en"><!--<![endif]-->
With the preceding conditional classes in place, targeting a specific IE (IE7 in this example) looks like this:
.ie7 nav li {
float: left;
}If we need to target all IEs, we would do this:
.ie7, .ie8, .ie9 {
nav li {
float: left;
}
}This compiles to the following:
.ie7 nav li, .ie8 nav li, .ie9 nav li {
float: left;
}For all other browsers, we would do this:
nav {
display: flex;
}It doesn't matter which of the methods you use, Modernizr.js or conditional classes, it's all personal preference. You'll be doing the right thing by using either of those two methods.
Remember, avoid CSS hacks at all costs. As web designers and web developers, we have a moral responsibility of creating a better web for everyone.