JIBE

Death of the Internet Explorer Stylesheet

0 min read

Leah Wagner

The original motivation in writing this post was to alleviate any tension for developers moving from the Drupal 7 to the Drupal 8 version of the Basic theme (Basic is a grid based starter theme for Drupal). In the new Drupal 8 version of Basic, you will see we have completely removed Internet Explorer specific stylesheets. Instead, we wanted to encourage a preferred development approach that uses feature detection over browser detection. While this was the original purpose, I hope this post will be helpful to all who wish to pursue this approach regardless of which technology you are using.

History of the Internet Explorer Stylesheet

Before the web standards movement in the early 2000’s, web developers had to constantly battle how different browsers would render the same code in very different ways. This sometimes meant building and maintaining completely different codebases for different browsers. This is because certain markup and styles would work, yet behave very differently from browser to browser.

Today as browser manufactures collaborate on standards instead of compete on proprietary features, our code typically behaves consistently. However, what we have seen in the past 5 - 10 years, as Firefox and Chrome have entered the market, is that browsers are releasing features in different development cycles. In particular, Internet Explorer has been slower to implement certain features that Firefox and Chrome have supported for a while. While Internet Explorer 11 and Microsoft Edge are mostly up to speed, depending on the website’s traffic, we also have to consider legacy browsers like Internet Explorer 8 through 10 that are still widely used and no longer updated. Thus, historically, we would address the limited feature set in these browsers with specific stylesheets for Internet Explorer.

Present Day Browsers

Modern browsers are no longer releasing new features on a yearly basis. It’s more likely on a monthly or even weekly basis. We see browser features getting released faster than a website is redeveloped. And then there is the mobile space, which is where we have seen the most growth in the past 5 years. We have countless device sizes running off of countless operating systems.

It is also important to remember that this isn’t just about supporting older browsers. There is a modern browser, Opera Mini, that intentionally runs with stripped down feature support. It’s goal is to provide improve page load speeds to parts of the world that have slow and/or expensive internet connections.

Coding for Feature Detection

With those considerations, using a feature detection approach is best because of the countless browser options. Not to mention, if a browser is updated, it would be nice if the improved style you apply with that feature would become available.

With feature detection in place, we can now implement a Progressive Enhancement approach in our code. As you begin to build your website, you keep the lowest level of feature support in mind. This will depend on the browser support defined in your current project’s requirements. Once that lowest level of feature support is in place, you can then layer in complexity to improve the display as you detect features. Read more about Progressive Enhancement, and the opposite approach, Graceful Degradation.

But how do we detect these features?

Modernizr.js

Modernizr is a small JavaScript library, sometimes referred to as a shim, that will test for features on page load and apply classes to your <html> element. For example, this Modernizr script will generate these classes with Chrome on a desktop computer.

*.html (on Desktop using Chrome)

<html class=”no-touchevents details js applicationcache geolocation history postmessage svg websockets localstorage sessionstorage websqldatabase webworkers hashchange audio canvas canvastext video webgl multiplebgs opacity rgba inlinesvg hsla supports svgclippaths smil fontface generatedcontent textshadow cssanimations backgroundsize borderimage boxshadow csscolumns csscolumns-width csscolumns-span no-csscolumns-fill csscolumns-gap csscolumns-rule csscolumns-rulecolor csscolumns-rulestyle csscolumns-rulewidth csscolumns-breakbefore csscolumns-breakafter csscolumns-breakinside flexbox flexboxlegacy cssreflections csstransforms csstransforms3d csstransitions indexeddb indexeddb-deletedatabase">

Compare this to how this script will render on an iPhone:

*.html (on iPhone)

<html class=”touchevents details js applicationcache geolocation history postmessage svg websockets localstorage sessionstorage websqldatabase webworkers hashchange audio canvas canvastext video webgl multiplebgs opacity rgba inlinesvg hsla supports svgclippaths smil fontface generatedcontent textshadow cssanimations backgroundsize borderimage boxshadow csscolumns csscolumns-width csscolumns-span no-csscolumns-fill csscolumns-gap csscolumns-rule csscolumns-rulecolor csscolumns-rulestyle csscolumns-rulewidth csscolumns-breakbefore csscolumns-breakafter csscolumns-breakinside flexbox flexboxlegacy cssreflections csstransforms csstransforms3d csstransitions indexeddb indexeddb-deletedatabase”>

You will see the difference in the first class. While the iPhone supports touch events, you can see Chrome on this desktop computer does not. This very helpful when designing hover styles for desktop computers. You can provide a default layout for mobile devices that does not support hover styles and then further target the no-touchevents class to enhance your layout for desktop computers.

Code Customization & Optimization

You also have the ability to customize and optimize as needed. If you have no intention of using flexbox, there is no point in checking if a browser supports it. When you build and save your Modernizer file, it comes with a link that saves the current settings you have selected. For example, the example above was generated from this link. If you decide you need to be checking for another feature in the future, simply copy the url in your original Modernizr file and paste it in your browser. This will take you to page that shows the current state of your Modernizr configuration. Here you can make your changes and then click the Build button to generate your new file.

Exceptions to Progressive Enhancement

Many unsupported CSS styles will not typically break anything in your layout. With this in mind, you do not have to detect every single CSS property you plan on using. An example is the border-radius attribute. This is not supported in IE8 but the browser will simply ignore this style and render your box with square corners. There is no need to have Modernizr looking for this feature unless you need to implement a different approach when it is not supported.

A Practical Application of Progressive Enhancement

First, we start with a simple search button that has a search icon added through a background image.

button.sass

.button--search a display: inline-block border-radius: 3px background-color: black background-image: url('../images/icon-search.png') background-position: left top background-repeat: no-repeat padding: 10px 30px 10px 10px color: white

There are situations where you may want to enhance this display to use an SVG background image instead. The SVG image will provide a crisper image -- especially on retina screens. However, Internet Explorer 8 does not support SVGs. Using a Graceful Degradation approach with an Internet Explorer stylesheet, you may have done something like this:

Example: Graceful Degradation

button.sass

.button--search a display: inline-block border-radius: 3px background-color: black background-image: url('../images/icon-search.svg') background-position: left top background-repeat: no-repeat padding: 10px 30px 10px 10px color: white

ie8.sass

.button--search a background-image: url('../images/icon-search.png')

We would define our SVG image in our default stylesheet and then define a PNG fallback in our IE8 stylesheet. This uses the Graceful Degradation approach. Instead, let’s use feature detection and implement the Progressive Enhancement approach.

Example: Progressive Enhancement

button.sass

.button--search a display: inline-block border-radius: 3px background-color: black background-image: url('../images/icon-search.png') background-position: left top background-repeat: no-repeat padding: 10px 30px 10px 10px color: white html.svg & background-image: url('../images/icon-search.svg')

Note: This example is using Sass. This markup could compile to css as: html.svg .button--search a

We would define the PNG image as the default and then override this value if Modernizr has added the svg class the the html element. Some older Android browsers don’t support SVG either so with this code, the PNG image will load for those devices where the previous implementation would not. Hypothetically, if those older Android browsers later added support for SVG, with this approach, that browser would start to use the SVG image as soon as Modernizr validated it as a supported feature. No code update needed!

There is also an added benefit of improved code clarity to consider. With our styles all in one place for this element, applying updates in the future will be easier. You won’t have to try and remember or write documentation for Internet Explorer overrides that sit in another file.

When Internet Explorer Browser detection is necessary

After (hopefully) convincing you of the greatness of Progressive Enhancement, I can honestly say that I do occasionally need an Internet Explorer specific style. However, the circumstances are usually really specific and unique.

A hypothetical situation could be that your website has a button that launches an external service or links to another website. This website or service does not support IE8. So perhaps we want to hide this button completely if someone is using IE8.

Instead of adding a specific stylesheet as we have in the past, let’s simply add a class the the <html> element so we can continue to keep our styles grouped nicely. Add the following code would do the trick.

<!--[if lt IE 7]><html{{ html_attributes.addClass('no-js', 'lt-ie9', 'lt-ie8', 'lt-ie7') }}><![endif]--> <!--[if IE 7]><html{{ html_attributes.removeClass('lt-ie7') }}><![endif]--> <!--[if IE 8]><html{{ html_attributes.removeClass('lt-ie8') }}><![endif]--> <!--[if gt IE 8]><!--><html{{ html_attributes.removeClass('lt-ie9') }}><!--<![endif]-->

Note: ‘lt’ stands for later than.

Continuing with our example above, our code would now look like this if we wanted to hide this button for Internet Explorer 8 browsers.

button.sass

.button--search a display: inline-block border-radius: 3px background-color: black background-image: url('../images/icon-search.png') background-position: left top background-repeat: no-repeat padding: 10px 30px 10px 10px color: white html.svg & background-image: url('../images/icon-search.svg') html.lt-ie9 & display: none

Support in Basic 8.x for Drupal

When using the Basic theme for Drupal 8, there is a setting available to add these classes to the html element at: /admin/appearance/settings/basic.

Stylesheets for Today and Beyond…

This approach gives you is code stability for the browsers of yesterday, today and tomorrow. Your biggest decisions will have to be made before you write your first style -- how far back into yesterday will you go?

Maybe the biggest hurdle to this approach is that it needs to be applied from the beginning. However, that does not necessarily mean the beginning of a brand new project or site. If your projects are enforcing a componentized/decoupled style structure, Progressive Enhancement can be applied to a new feature in the same way.