Abstract Sequential Stephanie Hobson's abstract thoughts in the sequence she has them.

How To Debug CSS

Some quick notes and links for the talk I gave at WordCamp Vancouver about Debugging CSS.

Edit: You can now watch a recording of Debugging CSS. Spot the three projector failures!


  1. Is the HTML valid?
  2. Is the CSS valid?
  3. Is the right CSS being applied?
    1. Is what you typed being applied?
    2. Is other stuff being applied?
    3. Is what’s being applied right?
  4. Does CSS support what you’re doing?
  5. Does the browser support it?
  6. Can you isolate the problem?
  7. Ask for help


Other resources

Mobile First Is Performance First

Tonight I spoke at Vancouver Web Performance Meetup and I promised to share my slides so here they are:

Mobile First Is Performance First from Stephanie Hobson

If what you’re really after are the links, let me save you a bit of time:

Conference Debrief: Smashing Conference Whistler 2014

A few weeks ago Smashing Conference came to Whistler. This caliber of conference comes to Canada infrequently so I couldn’t not go ;)

The conference

As good as I hoped it would be. A mix of strategy and near future technology examples.

My Favourite Talk

Talk Summaries

Marcin Wichary
Good is the enemy of great: On designing, and then undesigning, a perfect link underline
200 years of typographic history was lost when we moved from printing presses to the typewriter, Marcin Took us through some of what he did in his attempt to re-create the perfect underline.His ultimate point was that it’s important to find a balance between shipping and creating good code. Perfectionism is not the right balance but we should strive to make things good and not just improve the status quo.

Susan Robertson
Style Guides: Why bother?
Susan walked us through a long list of benefits to using a style guide. Highlights included: front-end speed, consistency, and performance. Lots of good resources here: styleguides.io

Yoav Weiss
Responsive Images are Coming to a Browser Near You
I have been hearing a lot about new picture element and srcset attributes but Yoav was the first to really get me excited about them. The potential image management problems these additions could create are huge but there is a lot of potential to be really neat things with them. is a solution for providing art direction of images on different screen sizes and srcset gets added to if you just want to provide a smaller/larger version of an identical image.

Marcy Sutton
A Web for Everybody
Accessibility is easier if you build it you build it in from the start. Ask, does it work: With the keyboard only? In a screen reader? Without sound? Without colour? In high contrast mode? “This stuff is not that hard.”

Jenn Lukas
The Developer’s Ampersandwich
Things to consider when implementing type on a website: if you haven’t been given design direction you can find the type by looking at what’s popular and already in use, separate presentation from content, be aware of performance issues with web fonts, add accessible fallbacks for a icon fonts, use tools like typecast to communicate with designers about general styles rather than content specific styles.

Zach Leatherman
Better @font-face with Font Load Events
Web fonts are rendered blocking. Zach proposes a JavaScript fix which prioritizes a FOIT for icon fonts and a FOUT for content fonts. Lots of good stuff from this excellent article of his.

Stephen Hay
Easing the Pain of Designing in the Browser
We need to stop thinking about layout first, we need to start thinking about structured content first. Begin by focusing on the small screen, and then focus on type and color.

John Allsopp
The Web’s future is offline
“We can’t keep building apps with the desktop mindset of permanent, fast connectivity, where a temporary disconnection or slow service is regarded as a problem and communicated as an error.”

Dave Shea
Rolling Your Own CSS Methodology
A CSS framework is not about syntax. It’s about discipline and optimizing for people. Ideals Mobify uses when building theirs: classes for everything, no IDs, no nesting, no !important.

That was one day. It was a really long day.

Johnathan Snook
Jonathan gave a very personal talk about the development of his career overtime and the importance of empathy. It touched a lot of people, but it is difficult to summarize in two sentences.

Brad Frost
Atomic Design
If we all use the same framework we all look alike. We should be building “Tiny Bootstraps, for every client.” – Dave Rupert. Brad demoed patternlab.io which is a really cool tool for breaking designs down into component parts.

Lyza D. Gardner
Soothing Web Weariness: Saving the Web by Doing as Little as Possible
Make projects smaller to begin with – increase your constraints – improve them iteratively and systematically instead of accepting complexity as the status quo.

Val Head
All the Right Moves: Putting your UIs in Motion
Animations needs to be designed with intent the same way you would design any other part of the site. Prototype animations. Test that they match your site’s style and feel fast.

Kyle Simpson
#CSS {Yawn: Yay!}
Kyle talked about some high-level concepts he’d like to see implemented in CSS templating. It was very much a talk about the next generation of CSS informed by some complex computing science principles. I can’t do it justice, his slides are here

Tim Kadlec
In Between
Like Val, Tim talked about designing animations with intent. He had lots of great examples and data.

Paul Irish
Getting to Fast
Not all pixels are created equal. Paul talked about why the first 14KB transferred are the most important to performance.

It was a great conference. I left feeling super excited about my job, which is how I always want to leave conferences :)

I also gave a ‘jam session’ talk on accessibility. They hosted it in a pub and I highly recommend pub audiences, they laugh at all your jokes! Accessibility was a theme running through all of the talks at Smashing and I am glad to see it being spoken about and incorporated into examples again I feel that, as an industry, we’ve sort of forgotten about it for a few years.

Making Websites Better for Everyone

There’s a few different versions of my talk floating around now. I’m really excited and humbled to hear that people have been making changes to the way the work in response to something I said.

The most detailed (and longest) version of my talk is available to watch on WordPress TV.

My first slide deck and links to the resources I recommend are part of an earlier blog post.

In the most recent version of my talk I used a demo of a fictional hosting company’s server status page. Follow these thinks to see the bad and good examples and I encourage you to compare the two right now using some assistive technology, or at the very least, using your nose or elbow on your mouse or trackpad.

Intro to Google Tag Manager

Google Tag Manager (GTM) is still pretty new as I write this. Stuff is still changing so I’m going to try to focus on techniques rather than step by step instructions (but I have some of those too).

What is GTM

You include a code snippet from GTM on your site which, among other things, includes a file. Then you use the GTM interface to configure what goes in that file.

This is intended to replace any scripts you’d normally have to write yourself to track stuff that isn’t a regular page view (example: tracking a file download as a page view). Say good bye to code like this: pageTracker._trackPageview(fileurl);

Why do we care?

One snippet to rule them all. All your tracking scripts and pixels can be moved off the page and into GTM. Smaller pages, faster loading! They have some already supported services (AdWords, DoubleClick, Remarketing, Mediaplex…) and you can theoretically code support for others in yourself.

Theoretically, it means non-technical people will be able to do the set up for this kind of tracking. Less work for us! But let’s face it, the interface was written by devs, it still needs some technical knowledge.

It cuts down on the amount of code writing and maintenance we have to do in the future. Also less work for us!

Is it a trap?

Could be. Yup.

A javascript error in GTM code can break all the javascript on the page and anyone with access to your GTM account can add javascript.

GTM seems to insist on following the href on <a> elements. So if you are hijaxing any links GMT could break your code. For example: if you are using a lightbox style plugin which opens links in overlays.

Some GTM features can add query strings or hash tags to URLs, depending on the system on the other end of the link, this could cause problems too.

So test, and limit the publishing permissions on your account to people who know how to test.

Creating an account

Remember how we all went out and got personal Google Analytics accounts and added our clients to them and then stopped working for those clients and it got awkward? Google remembers too.

You hook an existing personal login up to GTM and then have the option to create accounts. One per business is ideal here. Then you get to set up what Google is calling a container. A container contains all the code snippets you are going to want to run. Google suggests you should create a different container for each website associated with the business that owns the account.

(This seems like sound advice if you’re just getting started but will lead to some code duplication in the long run if you have multiple domains, I have complicated thoughts on this that belong in a separate blog post).

Once you’ve set up a container you get the code snippet. Place the code snippet on the page after the opening <body> tag.

What’s all this?

Your container contains 3 things: tags, rules, and macros.

Tags are individual things to do. Things like “listen for links being clicked on”, “track this page view”, “listen for form submissions”, “track this conversion”, “track pressing play”. They’re individual tasks so listening for form submissions and tracking a conversion takes two separate tags.

Rules are when to apply tags. The basic one is “on every page”. Each rule can have multiple conditions so you can combine them to create rules like “if this event is a click and it happened on an element that does not link to this website”.

Macros are just a way to store stuff you’re likely to re-use (mostly text or javascript). There’s some pre-populated ones and you can write your own. Stuff I’ve been keeping in macros: our analytics tracking number, a line of javascript that retrieves the page title, and a complex regex that checks if the href of a link takes the user off the current site. You reference macros inside tags, rules, and other macros by writing its name in {{double curly braces}}.

Example: Tracking page views and external link clicks with Universal Analytics

My examples are all for Universal Analytics but if you’re still using Classic the concept is the same where I pick Universal Analytics from the Tag Type menu pick Google Analytics Classic and do your best with the slightly different options that follow from there.

This is, more or less, what we’ll be setting up, in an order that makes sense to me:

  1. Macro: your Analytics tracking number.
  2. Tag: track a pageview in Analytics.
  3. Tag: listen for clicked links.
  4. Rule: if link does not lead to current site.
  5. Tag: create event in Analytics for outbound link click.
  6. Create version
  7. Preview
  8. Publish

I found the actual order somewhat more headache inducing, and that’s why I’m writing a blog post about it. Hopefully you end up at the end of this list with link tracking and no headache.

Once you’ve followed these steps once hopefully you will understand how the pieces fit together and you can go on to work in the way that makes the most sense to you :)

This is the part where I list actual steps, this part might change as the product develops.

  1. Macro: your Analytics tracking number.
    1. In Analytics get your tracking ID from Admin > Property Settings
    2. In GTM go to your container’s overview page.
    3. Click the big red “new” button and pick “macro” out of the list.
    4. Configure the macro like this:
      Macro Name:
      tracking ID (well you can name it whatever you want)
      Macro Type:
      Constant String
      Your tracking ID

      Or, if prefer a screen shot:

    5. Save it.
  2. Tag: track a pageview in Analytics.
    1. Click the big red “new” button and pick “tag” out of the list.
    2. Configure the macro like this:
      Tag Name:
      Tag Type:
      Google Analytics & gt; Universal Analytics
      Tracking ID:
      {{tracking ID}}
      This is the macro we just created. You can either type it yourself or click the little lego block to pick it out of a list.
      Track Type:
      Page View
      Firing Rules:
      Add All pages
      You don’t have to create this rule, GTM creates it automatically.

      Or, if you prefer a screen shot:

    3. Save it.
  3. Tag: listen for clicked links.
    1. Click the big red “new” button and pick “tag” out of the list.
    2. Configure the macro like this:
      Tag Name:
      Listener - linkClick
      Tag Type:
      Link Click Listener
      Firing Rules:
      Add All pages

      Leave everything else on the defaults.

    3. Save it.
  4. Rule: if link does not lead to current site.
    • Click on the big red “new” button and pick “rule” out of the list.
    • Configure the rule like this:
      Rule Name:
      on - outbound link click
      {{event}} equals gtm.linkClick
      {{element url}} starts with your site URL
    • Save it.

    I actually use a complex regex in a macro for the conditions to catch a few edge cases like: urls missing the www, relative links, mailto/tel/ftp etc. but for this example and basic sites this will get what we want.

  5. Tag: create event in Analytics for outbound link click.
    • Click on the big red “new” button and pick “tag” out of the list.
    • Configure the rule like this:
      Tag Name:
      UA event - outbound link
      Tag Type:
      Universal Analytics
      Tracking ID:
      {{tracking id}}
      Track Type:
      {{element url}}
      {{element text}}
    • Save it.

    If you have an existing implementation you are trying to match so your stats aren’t disrupted you should look in Google Analytics to see what you are currently using for the event category, action and label and match those values instead :)

  6. Create version
    • On the Container Draft > Overview page the Create Version button is in the top right.
    • If you really want to be on the ball you can amend the name or add notes to describe what you added in this version, handy in case you want to roll back.
  7. Preview
    • The Preview button is also on the top right of the Container Draft > Overview screen.
    • Click Debug in the popover
    • In the next popover click on the url of your site. This will open a new window with your site and a Tag Manager window at the bottom.
    • In the window at the bottom check that:
      • “Page View – Page” and “Listener – linkClick” have the status “Fired on Tag Manager Load”
      • Click on a link and check that “UA event – outbound link” gets added with the status “Fired on Event “gtm.linkClick”. You can usually see it flash to the top before the other page loads but if it’s too fast find (or create) a link with the attribute target=”_blank” to click.
    • If something is not working check your rules and try again.
    • Also important, check that the javascript on your own pages is working properly. In an ideal world you have a list of features you can test.
    • Exit preview mode
  8. Publish (blue button in top right of Container Draft > Overview page)

You can see some changes applied immediately in Analytics on the Real-Time > Overview page. Other events which don’t seem to be working on Real-Time occasionally start showing up in the stats a day later. I have no insight to offer here, sorry.


So we create tags to do things, rules to govern when we do the things in the tags, and macros to save ourselves time when creating tags and rules.

Accessibility with CSS: Making Websites Better for Everyone

Last night I spoke at the Style & Class Meetup about Accessibility and CSS. Posting the slides here for posterity:

Accessibility with CSS: Making Website Better for Everyone


A Matter of Semantics

Adapted from a blog post on Web Services’ blog at BCIT, the audience was our content community: people who contribute content using the CMS, with little to no technical experience.

Once, as part of a “getting to know you” activity at summer camp, I played a game where I was given a drawing and another camper was given a paper and pencil. Without her seeing the drawing, and without me seeing her paper, I had to try to get her to draw what I could see.

“In the top left hand corner there’s a square, in the bottom right there’s a circle, big enough that it overlaps the square. Inside the circle is a triangle.”

It was impossible to end up with an exact copy of the drawing. Usually the original and new drawings were hilariously different.

Every time you visit a web site, your computer is playing this game with another computer on the other end of the internet. In order to avoid ending up with a hilariously different web site, the computers speak a few really precise languages to each other.

A CMS (Content Management System) lets you make updates to a website without learning those languages. So you’re telling the CMS what you want to do and the CMS is translating your intention into one of those really precise languages – HTML.

HTML doesn’t tell the computer how to make things look. HTML tells the computer what things are: “this text is a link to another page”, “this text is a heading”, “this text a list of related stuff.” This is called semantic markup: the content is “marked up” with HTML to indicate its “semantics” or meaning.

When users view your website, their browser combines your HTML with files the developers have written in two other languages – CSS and JavaScript – to create the web page that they see.

CSS tells the computer how things should look: “links are blue,” “headings are bold,” “list items have bullets.”

JavaScript tells the computer how things should work: “When the user clicks this button, show the user that paragraph.”

With just the HTML a computer can do all kinds of interesting things with your content. It can read it out loud, translate it into a different language, put it on a really big screen (or a really little one), or search through it.

Sometimes things get misinterpreted.

When we edit pages in a CMS we see a visual metaphor instead of the plain HTML. We’re also playing the drawing game with the CMS. This means something that looks right might still not have the right HTML. Just because there are dots before that text doesn’t mean it’s a list. Just because this text is bold doesn’t mean it’s a heading.

With the wrong HTML the other computers will make mistakes.

When a screen reader comes to a list it will tell the user that there’s a list and how long it is, if the user has been to the page before and knows they need item number eight they can skip straight to it. With the wrong HTML the user has to skip past all the other items one at a time.

When a search engine is trying to identify what a page is about it looks for headings. Text that is marked up as an HTML heading is considered a better summary.

When the CSS (the way the website looks) changes the HTML doesn’t. In 2010 we changed how much space is between paragraphs on the website. Before we did this some editors had decided they wanted more space between their paragraphs and inserted it themselves by adding empty paragraphs, using markup to create visual formatting. After we made changes to the CSS their pages had huge spaces between paragraphs and it looked like something was wrong with them.

The mobile version of a website will often use the same HTML as a desktop version but different CSS. This is a very visual example of why separation of content and presentation matter.

From time to time, we see people use tables to impose a specific visual layout on their content, something that should really be done with CSS instead. Tables are hard for mobile browsers to handle because they are so wide. To avoid distorting content in them the tables could be re-arranged. This will make tables with data in them easier to read on a mobile phone but if the HTML says “this is a table” and what is inside is not data, just an image we wanted in a different position, things could end up looking like one of our drawing game pictures gone wrong.

How to avoid errors.

There are some simple things that can be done to avoid problems:

Don’t fight the default styles. The designer made careful decisions about how the HTML should be styled by the CSS using principles of graphic design and interface design and did user testing to refine them. This should make your job easier, you don’t have to make these decisions yourself instead focus on the purpose of each part of your content instead of how it should look.

If you are experienced enough to be writing your own HTML pay attention to what the meaning of the elements are.


I spoke at an HTML5 Code Camp the other day on HTML5 forms because HTML5 forms are cool! They’re so cool you can use most of them today anywhere you have a text field to increase functionality for your users!

HTML5 Forms OF DOOM from stephaniehobson

Download the slides.

Sample form.
Finished form (no peeking).


Basic Introductions


Compatibility Specifics



I’m taking a one year leave of absence from my job at BCIT beginning June 1st, 2012.

Right now it kind of feels like I’m doing this because I’m crazy.

I’m really doing it because there’s stuff I want to do.

I want to build something cool. I want to learn something new. I want to live in London. I want to live in San Francisco. I want to hang out with the dear friends who live in each city who I have been apart from for way to long. I want to get to know the friends that I’ve made in my travels but never lived near.

Along the way I’d going to have to do a bit of work. Contract/sub-contract work I can do remotely while I’m travelling or job offers in San Francisco and London that will help me with the paperwork to work there.

Work that will let me do what I do really well1, work that will let me do things I enjoy but don’t do enough of2, and work that will give me a chance to learn what I don’t do at all yet3.

  1. HTML, CSS, JavaScript, jQuery, brainstorming and problem solving.
  2. Responsive design, user experience testing, information architecture, interface design.
  3. SVG, SASS, ePub.

I’m also looking for cheap places to say – friend of a friends who need house sitters or subletters, empty guest rooms and comfy couches. In London or Brighton in Aug and Sept and San Francisco or Berkeley from Oct-Dec.

If you have some work, a place to stay, or some advice for me I can be contacted on LinkedIn, or Twitter.

An Invocation for Beginnings

Print Styles Are Responsive Design

Print styles are the original responsive designs. Using media queries we pare down the content, focus on readability, and design with different device capabilities in mind but when was the last time you took a good look at your print styles?

Yes, people still print web pages. Extrapolating from these numbers about 10,000 pages are printed from bcit.ca every month. The print experience is an important part of a good site and relying on your screen styles to print properly is foolish:

Printing can really screw up a web page.

Avoid common problems

One of the most common problems I saw when doing my survey of print styles was white text printing on a white page. To save ink the browsers will strip all background colours and background images before printing so in your print style sheet be sure to over-ride any light coloured fonts. I also add a thin border to elements where the background colour is used on the screen to differentiate the content and reinforce the grid.

There’s a variety of common layout bugs everything from floats to absolute, fixed, fixed-width, and semi-opaque elements can get cut off, misplaced, or disappeared entirely especially when the element flows across a page break. If it’s too wide some browsers will shrink your page until it fits and others will crop it. Where possible do away with your layout and make your content linear and fluid.

Web fonts introduce a new quandary to the world of print styles. FireFox and Chrome don’t print web fonts. Have you ever seen a site with the word-spacing, line-height, and font-size picked for one font displaying its fallback font? It’s not usually a pretty picture. I recommend over-riding web fonts in favour of a common font, especially for body copy.

Focus on content and save paper

While you’re stripping your web fonts out, consider the readability of the rest of your typography. How does it look printed? If your page is being printed chances are someone is going to spend some time reading it – more time than they’d spend on your site. Do what you can to make that pleasant.

Layout elements like headers, footers, banners, ads, and menus distract from the information the user is trying consume, are un-usable on a printed page, and take up extra paper. It’s very common to remove these elements when printing. A three-column page layout doesn’t look so bad on one short page but if your site has a substantial amount of content those columns will likely be empty from the second page onward leaving large fields of empty space or worse your columns will spread onto a second page when your content only filled the first. What’s your user going to do with that printed navigation menu anyway – click on it? How does that logo in your header look in black and white? Removing layout elements makes it much easier to make your remaining content fluid to avoid common print bugs and fit the page. Think about a better way to communicate the other information – more on this in a bit.

Provide a better print experience

Print doesn’t work like a web page. The user can’t interact with it anymore all they can do is read it. Consider what that means for content on your page that you can’t normally see.

There’s some pretty fancy CSS tricks you can use to add the URL of links to the page in brackets after the link. I think I’ve seen it done best by the HTML5 boilerplate but I prefer to add footnotes with javascript. This is much less disruptive for readers. Either way make sure you consider how you’ll handle links that aren’t URLs: javascript hooks, in page anchors, mailto or tel. These same tricks can be applied to abbreviation titles and other attributes.

Not all interactive content can be exposed. There’s no CSS trick to print a video or Flash file and frequently this missing content will just leave a big white gap in your page. Your options are pretty much: hide it, provide a place holder, include a short summary, or include a full transcript. I’ll leave the method up to you.

For content revealed by javascript my suggestion is to do your best to print the content that the user sees. If they’ve toggled open two out of ten of your FAQs, just print the full text of those two and leave the others closed. I’ve seen several sites which don’t include their global styles when printing but forget to include the styles their pages are dependant on in print stylesheets (this is most common with javascript). I can only imagine how frustrating that would be to a user.

Provide a better brand experience

The most basic print styles make a page more readable at the expense of some of its character but we don’t just have to take away. You can include a print specific header and footer hidden in your HTML or add them later with javascript. This gives you a chance to include a black and white version of your logo and any other brand cues you feel are important. You might already be using a grid to maintain visual consistency between desktop and mobile, here’s your chance to do it in print too.

Other information you might consider adding in a print header or footer is: way-finding clues like a section or category name, general contact information like a 1-800 number (more useful than a link to a contact us page), and a short URL to help the user get back to that page. Some sites even include a QR code but use your best judgement.

Speed up your pages

It boggles my mind that browsers will still delay rendering a page until it has loaded a style sheet with the media type of print. #seriously #testyours. This article on Browser Performance Problem with CSS “print” Media Type outlines the problem really well.

If you’re just trying to avoid the extra http request and your print styles are very small you can always just add them into your main CSS file.

@media screen {
/* screen styles here */
@media print {
/* print styles here */

Otherwise you can look at techniques to load them asynchronously. There’s a couple ways to do this.

Seeing it in action

Original page.Without a print stylesheet.With a print stylesheet.

On the left is our site on a screen, on the right how it looks formatted for print. In the middle, without any print styles, you can see it goes boom:

Did you see what happens to the Bebas font we used on our section names? You caught me, this is a screen cap not a scan of a printed page. Bebas wouldn’t actually print and the 6 pixels of word spacing we have to apply to it to get it to play nice looks kind of silly on Arial Narrow.

Our print style sheet is loaded asynchronously after the rest of the page and at the same time I run functions to add a print header, print footer and the URLs of the links on the page as footnotes.

The screen header, sidebars, banners, and footer are hidden from display and I force the main content to become fluid again. Other than that the actual body of the page needs only minor work because these styles are layered over our global styles. I darken up some text, remove videos and Flash elements, and on pages which don’t already have outdented headings I outdent the headings. If this page had javascript elements everything would print as the user left it before printing.

The print header includes a black and white version of our logo which prints nice and crisp compared to a colour one and uses a few thin lines to re-establish the grid creating a visual tie back the way the website looks on a monitor. It also includes the name of which section of the site the page is from and a shortened URL to return to the page.

The footnote function is complex enough to re-use a footnote if there are multiple links to the same page, provided a shortened URL if it’s an internal link, include fallback text for javascript links, and skip footnoting an email address if the address itself is all that’s included between the anchor tags (our style guide mandates this but the odd one slips through the cracks).

The very basic footer was a victim of time constraints. We couldn’t include our 1-800 number on all pages because it’s specific to Student Enrolment and wouldn’t be appropriate on business services pages, for example.

Code tips

If you have a large constantly evolving site I recommend making your global style sheets apply to both screen and print. It saves you the trouble of keeping two sets of stylesheets up to date when changes are made. That leaves you the task of over-riding some of the screen styles in the print style sheet. This will be much easier if you’re already avoiding IDs for styling. If you’re not it seems to be acceptable to sprinkle your print styles with !important declarations.

“Print preview lied to me.” – @hicksdesign

Test until it’s perfect in print preview.
Then test until it’s perfect when you print to PDF.
Then test until it’s perfect when you print it out on paper.
There is no other way to be sure you’ve got it right.

More information

← Before After →