Using Modernizr with Flexbox

Last week, Modernizr was updated to version 3, and with that upgrade gained some useful new tests for flexbox support. You now get four separate flexbox tests, producing eight different classes on your <html> tag that you can use to target browsers with different levels of flexbox support.

Test Supporting class Non-supporting class Useful for
Flexbox flexbox no-flexbox Targeting browsers that support the current syntax
Flexbox (legacy) flexboxlegacy no-flexboxlegacy Targeting/excluding browsers that support the old 2009 syntax, such as Safari 6 or Android 4.3
Flexbox (tweener) flexboxtweener no-flexboxtweener Targeting/excluding IE 10
Flex line wrapping flexwrap no-flexwrap Targeting browsers that support flex-wrap, or excluding browsers that support flexbox but don’t support flex-wrap
The four flexbox tests you can include in your Modernizr 3 build.

The four flexbox tests you can include in your Modernizr 3 build.

The most notable change is that you can now test whether the browser supports the flex-wrap property specifically. This is useful because some browsers supported the up-to-date flexbox spec without any browser prefix, but didn’t support the flex-wrap property within that spec. This was problematic because it meant that you couldn’t exclude these browsers by simply not including their browser-prefixed properties. They would get the same flexbox code you provided to full-featured browsers, but if you used flex-wrap in that code, the layout had the potential to break horribly.

The Modernizr site states that it’s Firefox that suffers from this limitation, but this is inaccurate. It’s only old versions of Firefox, specifically 22 through 27. Firefox is currently (as of September 2015) at version 40, so it’s unlikely that you still have a significant number of users on your site using version 27. However, the flex-wrap test is still useful as a safeguard for the small number of users that might be affected by a catastrophic layout failure that might occur if you write a layout that depends on the flex-wrap property.
(more…)

We need more moms in web design and development

Last year in one of my conference talks, I mentioned that I have kids. After my talk, a woman came up to me and asked me how I do it. How I have a full-time job and do conferences and write and be a mom. She was interested in this because she was planning to start a family soon and wanted to know how other working moms in our industry manage it.

This got me thinking about moms in web design and development. And I realized that out of the 40-ish conferences I have spoken at over the last 8 years, there has been only one other speaker at a conference with me who was a mom. Maybe two. In both cases, their kids were grown or nearly grown, not babies or little kids that can’t fend for themselves for a couple days while mom is away.

It’s not that I haven’t spoken with lots of great women. I’ve been fortunate that most of the conferences I’ve spoken at have had women well represented in the speaker line-up. But all of these women, bar one or two, are not mothers. I’m sure there are other mom speakers out there like me, but the point is that they’re very rare.

(more…)

Enhancing Responsiveness with Flexbox presentation at RWD Summit

My latest talk is called “Enhancing Responsiveness With Flexbox.” I talked about how to actually put flexbox to use in the real world—today. I demonstrated a bunch of practical ideas for how to use flexbox as progressive enhancement to improve sizing, spacing, and order in responsive web design, while still ensuring non-supporting browsers get an acceptable fallback experience. I’ve just given this talk at CSS DaySmashing Conference, and the RWD Summit.

You can view my presentation on Slideshare or download the slides directly here:

Enhancing Responsiveness with Flexbox (PDF, 2.6 mb)

The demos

To demonstrate the flexbox features, I’m still using my S’mores Builder page. Check it out (in a browser with good flexbox support, of course) to see what flexbox can do.

I also created a few additional, standalone demos, of which I have these two ready to share:

I hope to have time to prepare and post the other demos here soon.

(more…)

Full-width pinned layouts with flexbox

One good way to learn a new technology is to take something made with the existing methods and try to recreate it with the new thing. Take flexbox, for example. Philip Walton showed us with his “Solved by Flexbox” demos that flexbox can make a lot of the layouts that were possible but painful with traditional CSS2 methods a lot easier to create and more flexible to different content and user scenarios. I want to walk you through a similar sort of design challenge: taking an existing layout, converting it to flexbox, and then seeing how flexbox can take it to the next level.

My inspiration for a layout to convert came from Dan Mall’s write-up of his Crayola web site redesign—specifically, the responsive screenshots stretching across the full-width of the viewport, displaying how the layout could adapt from tiny to huge.

Dan Mall's full-screen layout of a mobile phone pinned to the left and a desktop monitor pinned to the right.

Dan Mall’s full-screen layout of a mobile phone pinned to the left and a desktop monitor pinned to the right, both bottom aligned, with text in between.

Seeing a full-width layout with chunks pinned to each side and another block in the middle made me think of flexbox’s justify-content:space-between, so I decided to try to see if I could recreate this layout with flexbox. Again, I took this as a challenge and learning experience for myself—not because there was anything wrong with Dan’s implementation. How many ways could I create this layout, and what pros and cons did each method have?

The display:table version

Dan was using absolute positioning, so no need for me to try that route. That option is covered!

Another option I wanted to compare with flexbox was a display:table layout, often a good fallback for flexbox layouts, particularly full-width ones. To make display:table work, I needed to put the left-most column first in the source, then the middle one, then the last one.

<div class="layout-table">
    <figure class="stretch-photo small">
        <img src="img/flexbox_stretch_small.png" width="58" height="127" alt="mobile"/>
    </figure>
    <h2 class="stretch-title"><span>looks great from here to there</span></h2>
    <figure class="stretch-photo big">
        <img src="img/flexbox_stretch_big.png" width="361" height="294" alt="desktop"/>
    </figure>
</div>

I don’t consider this source order ideal, as the middle text is, semantically speaking, a heading for the two images; this source order won’t result in the best reading order for users of assistive technologies like screen readers. Unfortunately, that’s sometimes what you’re stuck with when using display:table. But, if you can’t have perfect HTML, at least you can have nice, simple CSS!

.layout-table {
    display: table;
    width: 100%;
}
.layout-table > * {
    display: table-cell;
    vertical-align: bottom;
}
.layout-table .stretch-title {
    width: 100%;
    padding-bottom: 4rem;
}
.layout-table .stretch-title span {
    display: block;
    border-bottom: 1px solid #ccc;
}

Below is what my table-layout version looks like. I wasn’t going for identical with Dan’s version, just the same basic layout pattern. One difference you’ll notice is that in my version the text is centered between the two images, while in Dan’s version the text is not centered between the images but rather is centered with the blocks of text above and below it. This is not a pro or con for either version, in my opinion, just a difference. It depends on what alignment you want.

My version of the here-to-there layout pattern, using display:table-cell.

My version of the here-to-there layout pattern, using display:table-cell.

The flexbox version

So, with the display:table version as my point of comparison, I first set out to fix the source order.

<div class="layout-flex-basic">
    <h2 class="stretch-title">looks great from here to there</h2>
    <figure class="stretch-photo small">
        <img src="img/flexbox_stretch_small.png" width="58" height="127" alt="mobile"/>
    </figure>
    <figure class="stretch-photo big">
        <img src="img/flexbox_stretch_big.png" width="361" height="294" alt="desktop"/>
    </figure>
</div>

So similar, and yet so much better!

To use flexbox on this beautiful HTML, first set display:flex on the container for the three chunks. (If you want to use the browser-specific variants of the flexbox CSS too, go for it.) I also set align-items:flex-end to vertically align the three chunks, now “flex items,” along their bottoms.

.layout-flex-basic {
    display: flex;
    align-items: flex-end;
}

This gets me the three chunks lined up in a row, but of course the heading text is first in the line since it’s first in the HTML. I can move the mobile phone image in front of it by using the order property. All flex items have order set to 0 by default, so -1 moves the mobile phone image before all its siblings, leaving the heading to now take up the middle position.

.layout-flex-basic .small {
    order: -1;
}

The only thing left is to stretch the heading to take up all the space in the line left over after the two images have taken their shares. Setting flex:1 solves that simply. I also gave it some margin-bottom to move it up from the bottom edge a bit and a border to create the line between the two images.

.layout-flex-basic .stretch-title {
    flex: 1;
    margin-bottom: 4.5rem;
    border-bottom: 1px solid #ccc;
}

And that’s it. Not too bad, right? Apart from the browser-specific variants, which you can get Sass or another tool to add for you, it’s really no more CSS than the display:table version. It looks identical to that version, but has a more accessible and semantic source order.

The advantage to having proper source order on the flexbox version is that I can easily change the layout on narrow screens so that the heading is on top, in its natural source order, with the two images stacked below. Or, I can use order again to instead move the heading below the images.

@media screen and (max-width:50em) {
    .layout-flex-basic {
        flex-wrap: wrap; /* allow two rows */
        justify-content: space-between; /* move the images to opposite ends of their row */
    }
    .layout-flex-basic .stretch-title {
        flex: 1 0 100%; /* make it wrap to its own line */
        order: 1; /* move to the end */
        margin-bottom: 0;
        margin-top: 1em;
        border-bottom: none;
        border-top: 1px solid #ccc;
    }
    .layout-flex-basic .small {
        order: 0; /* move back to its normal spot */
    }
Even though the heading text comes before both of the images, I can use the flexbox order property to move it below them visually on narrow screens.

Even though the heading text comes before both of the images, I can use the flexbox order property to move it below them visually on narrow screens.

I can’t do this with the display:table version. I can change the CSS on narrow screens, sure, but the HTML source order means my heading will still be stuck in the middle of the two images. HTML source order really does matter.

Of course, maybe I want the heading in the middle on really tiny screens, smaller than the combined width of my two images. I can shuffle things around quite easily with flexbox.

@media screen and (max-width:480px) {
    .layout-flex-basic {
        flex-direction: column; /* stack vertically */
        flex-wrap: no-wrap; /* all in one column */
        align-items: center; /* horizontally centered */
    }
    .layout-flex-basic .stretch-title {
        flex: 1 0 auto; /* this now affects its height, not its width */
        order: 0; /* move back to its normal spot */
        width: 100%;
        margin: 1em 0;
        padding: .5em 0;
        border-bottom: 1px solid #ccc;
        border-top: 1px solid #ccc;
    }
    .layout-flex-basic .small {
        order: -1; /* put back on top */
    }
}
Changing the visual order yet again on even narrower screens.

Changing the visual order yet again on even narrower screens.

Extending the flexbox version

The flexbox version can also be extended in more ways that the display:table version. I can add more pieces and place them with more precision and flexibility than with display:table. Let’s say I want to add a caption to each image, but aligned to the side of its image, as shown below.

Adding text captions next to instead of below their images adds an extra layer of complexity. But it's totally doable.

Adding text captions next to instead of below their images adds an extra layer of complexity. But it’s totally doable.

Here’s the logical HTML for that.

<div class="layout-flex-advanced">
    <h2 class="stretch-title">looks great from here to there</h2>
    <figure class="stretch-photo small">
        <img src="img/flexbox_stretch_small.png" width="58" height="127" alt=""/>
        <figcaption>mobile</figcaption>
    </figure>
    <figure class="stretch-photo big">
        <img src="img/flexbox_stretch_big.png" width="361" height="294" alt=""/>
        <figcaption>desktop</figcaption>
    </figure>
</div>

To do this with flexbox, I turned each <figure> into a flex container itself. They’re still flex items, along with their sibling <h2>, but now the <img> and <figcaption> inside each <figure> are flex items too. That means they can be aligned in the various ways that flexbox allows.

.layout-flex-advanced .stretch-photo {
    display: flex;
    align-items: flex-end;
}

I want each caption to hang out the side of its parent <figure>, so I need to hard-code the width of each <figure> (not great, I know) so it doesn’t try to expand to hold its caption. I also need to make sure nothing inside the <figure> flexes, but instead remains at its native width.

.layout-flex-advanced img,
.layout-flex-advanced figcaption {
    flex: 0 0 auto;
}
.layout-flex-advanced .small {
    width: 58px;
}
.layout-flex-advanced .big {
    width: 361px;
}

This will indeed make each caption overflow its <figure>, but both will overflow out the right side, since the content inside each runs from left to right.

Both captions overflow out of their s on the right side by default. This doesn't look so hot on the image on the right.

By default, both captions overflow out of their figure containers on the right side. This doesn’t look so hot on the image on the right, whose caption barely shows in the viewport.

But, I can change this using flexbox’s flex-direction property. You’ve perhaps heard that you can use flex-direction to switch content from row to column layout. But those aren’t the only two values flex-direction has. You can also set it to column-reverse or row-reverse. They work the same as their column and row counterparts, but each starts its stacking from the opposite direction of what you’d normally expect. So, for a left-to-right language like English, flex-direction:row would lay the flex items out from left to right, but flex-direction:row-reverse would lay them out from right to left. That’s exactly what we want to happen on the big <figure>: place the monitor image on the right side of the row (first in the source), then its caption to its left (second in the source).

.layout-flex-advanced .big {
    width: 361px;
    flex-direction: row-reverse;
}

That takes care of it, creating the layout in the screenshot above.

Of course, at narrow screen widths we can instead place the captions back under their images—or on top of them, or really wherever we want, thanks to flexbox.

The first image has its caption below, the second has its caption above, and the heading is sandwiched in between.

The first image has its caption below, the second has its caption above, and the heading is sandwiched in between.

The best part about this is that all of this flexbox stuff can be added as progressive enhancement. I could use absolute positioning, like Dan did, as my base, and build on top of it using flexbox, which offers me additional content placement and alignment options that absolute positioning can’t achieve. (In this demo, I didn’t use absolute position or anything else to support older browsers, simply because this is a demo, not a real-life page, and I just really needed to get this blog post out the door without obsessing too much over it! That’s a bad habit of mine, which my very infrequent blogging indicates. Maybe I can create the progressively enhanced version of this demo as a followup blog post…)

This here-to-there layout pattern doesn’t have to be used just for responsive screenshots, of course. I could see it being used for all sorts of things—anything with a comparison or before-and-after, such as before and after screenshots of a web site you redesigned. Or, what about a hero banner for a craft or construction tutorial showing a photo of the raw materials on one side and a photo of the finished product on the left? Or, a recipe with a photo of the ingredients on the left, name of the dish in the middle, and photo of the completed dish on the right? Or, just show how a cute little baby has gotten so much bigger:

This version uses the same markup structure as the others, just with a little extra visual styling.

This version uses the same markup structure as the others, just with a little extra visual styling. (Isn’t my son cute?)

To see how this last demo was made, go to the demo page for all four versions and check out the CSS. As always, be sure to resize your browser window to see how it adjusts at different widths. And of course, view it in a browser with good flexbox support. As if you smart people would use anything else!

#663399Becca

I didn’t know Becca. I didn’t even know Eric, not really. He was a huge part of my learning CSS and switching to CSS layout around 2003 or 2004, and I worked with him as a moderator of his css-discuss mailing list for a while, but I never had the honor of meeting him. Last year, I was excited to learn that he would be speaking at the same conference as me, but when I got there, I found out he had had to cancel due to his daughter being seriously ill. Later, I found out it was cancer, and like so many others in the web design community I have followed his story of his daughter Becca’s last months of life, hoping the story would have a happy ending. But a few days ago, Eric lost his Little Spark.

Despite not knowing Becca or her family, I am deeply saddened by her passing. I cannot imagine what Eric and Kat are feeling right now. My heart aches for them. I have a daughter close to Becca’s age. The idea of losing my daughter or son is terrifying and incomprehensible.

Sometimes I get discouraged that I can’t be more involved in the web design community than I already am, due to being a mother and wanting to devote as much time as I can to my family. I never resent my children and husband, but rather just wish I had more time in the day to add on to everyone’s normal 24 hours and accomplish more of the professional goals I dream about. Eric’s story of losing Becca is a stark reminder of how precious family is, how important it is to focus on them, live in the moment with them.

I’m at work right now, in the office. I can’t wait to be home and hug my children.

Leveling Up With Flexbox presentation at Smashing Conference

Today I spoke at Smashing Conference in Oxford, England, on “Leveling Up With Flexbox.” The talk was based off my earlier flexbox presentation, but I focused less on the basic syntax, since I think most of us have already read at least a bit about that by now, and dove right into more code examples. I talked about how to actually put it to use in the real world—today. I demonstrated a bunch of practical ideas for how to use flexbox as progressive enhancement, adding it in bits and pieces on individual page components with simple fallbacks.

You can view my presentation on Slideshare or download the slides directly here:

Putting Flexbox into Practice (PDF, 3.84 mb)

You can also check out the video of the talk.

Update 23/09/14: I gave a slightly updated version of this talk at Smart Web Conference in Bucharest. You can download those slides or view them on Slideshare too.

The demos

To demonstrate the flexbox features, I’m still using my S’mores Builder page. Check it out (in a browser with good flexbox support, of course) to see what flexbox can do.

The S'mores Builder page is laid out entirely with flexbox, with some fallbacks for non-supporting browsers in certain places.

The S’mores Builder page is responsive and laid out entirely with flexbox, with some fallbacks for non-supporting browsers in certain places.

(more…)

Help me declutter before I move overseas

I’m excited to announce that I’m about to start a new position as a UX designer for Booking.com. To do so, I’m moving from the US to Amsterdam in the Netherlands! For the past several weeks, my husband and I have been busy preparing for such a big move, and a big part of that has been decluttering. One thing that I have far too much of is copies of my book Stunning CSS3: A Project-based Guide to the Latest in CSS. Books are heavy. I don’t want to move all these books. Plus, it’s silly for me to have these books when someone else could be benefiting from them.

So here’s what I’m going to do: I’m going to give away a bunch of copies of Stunning CSS3 to you guys. All I want in return is for you to donate something to Carolina Tiger Rescue, a big cat sanctuary here in North Carolina that is doing great work and that more people ought to know about. Everyone loves wild cats, right?

If you would like a copy of the book, follow these steps in the next couple days:

  1. Go to the donation page for Carolina Tiger Rescue and make a donation in whatever amount you like.
  2. Tweet at me something like “I just donated to Carolina Tiger Rescue, so @zomigi is going to send me a copy of her book Stunning CSS3″ and add a link to this blog post so others can do it too if they like.
  3. I’ll make sure to follow you, if I’m not already, so you can then send me a direct message with your mailing address.

I’ll send books to up to 10 people, and I’ll update this blog post if I hit that number (or run out of time before my move). For now, I can only send to people in the US, unfortunately. But, perhaps when I get over to Europe I’ll do another giveaway for you non-Americans!

Thanks for helping me clean out my house. 🙂

Putting Flexbox into Practice presentation at Blend Conference

Yesterday I spoke at Blend Conference in Charlotte on Putting Flexbox into Practice. You’ve probably heard about flexbox (the CSS Flexible Box Layout module), since it’s the most fully developed and well supported of CSS3’s wide array of new techniques for creating page layouts, and because it allows you to create fluid, responsive layouts much more easily than current float-based methods. I talked about how to actually put it to use in the real world—today. I covered the syntax you’ll be able to one day use to build an entire multi-column page layout with flexbox, but also demonstrated some practical ideas for how to use flexbox as progressive enhancement, adding it in bits and pieces on individual page components with graceful fallbacks.

You can view the slides on SlideShare, or download the slides here:

Putting Flexbox into Practice (PDF, 900 kb)

The demo

To demonstrate the flexbox features, I created a S’mores Builder page. Some day, I intend to turn it into a functioning site devoted to s’mores. (I really love s’mores. A lot.) But for now, check it out to see what flexbox can do.

The S'mores Builder page is laid out entirely with flexbox, with some fallbacks for non-supporting browsers in certain places.

The S’mores Builder page is responsive and laid out entirely with flexbox, with some fallbacks for non-supporting browsers in certain places.

(more…)

Bookmarklets for accessibility testing

I recently took an introductory JavaScript and jQuery class so I could learn how to write scripts from scratch instead of just blindly using and occasionally fiddling with other people’s scripts and jQuery plugins. To give myself some JavaScript practice, I decided to create two bookmarklets to solve a web accessibility testing dilemma: how to find inaccessible CSS background images.

One bookmarklet outlines elements that have a background image set, and the other removes all background images. The idea is to use either or both of these to see whether any of the informational images on the page have been set as CSS background images instead of foreground images (the <img> element in the HTML). This is an accessibility problem, since CSS background images can’t have alt text to explain the information contained within them. Background images should be reserved for either purely decorative images or informative images that repeat information found elsewhere in the text (like an image of a printer next to the word “print”).
(more…)

CSS3 transitions and z-index

This is just a reminder that you can apply transitions to an element’s z-index (aka, where it lays in the stack), but only by stepping through the layers. The browser has to keep z-index in whole numbers. This makes total sense, but it’s something I forgot about on a recent project.

I was working on an interface with overlapping elements, and I wanted whichever one was hovered to come to the front of the stack. I wanted this move to the front to look smoother, instead of one element just jumping out from behind another one suddenly. “Aha!” my brain said. “I will add a transition!” But my brain hadn’t thought this all the way through, and, of course, it didn’t work.

If you stop to think about it (which I eventually did), this makes perfect sense. If you want to take one element with z-index:1 and transition it to lay on top of another element with z-index:2, how in the world is the browser supposed to create intermediate steps between those two values? You can’t have an element with a z-index value of 1.5. An element can’t kinda overlap another element. Either it’s above or below. The browser can’t create some weird, merged together state where the two elements are on the same level and intermixing, both partially transparent on just the spots that are sharing the same level.*

What the browser can do is increment the z-index value in whole numbers over the course of your transition duration. So, if I have an element with a z-index value of 1 and I want to gradually get to 10, the browser can first set z-index to 2, then 3, then 4, and so on. If you have a short transition duration or a long way to go from your starting value to your ending value (like changing z-index from 1 to 1000), it will step through these changes very quickly.

Here’s a demo of z-index transitioning slowly so you can see how the browser increases the z-index value step by step; hover over the block labeled One to see it happen. Here are some screenshots of the same demo taken along the course of the transition.

The first div is naturally at the bottom of the stack.

The first div is naturally at the bottom of the stack (z-index: 1).

When hovered and the transition begins, it first jumps on top of the Two div.

When hovered and the transition begins, it first jumps completely on top of the Two div as it simultaneously becomes opaque.

Notice that it is never partly on top and partly below any given div. It's entirely above divs Two and Three here, and entirely below divs Four and Five.

Notice that it is never partly on top and partly below any given div. It’s entirely above divs Two and Three here, and entirely below divs Four and Five.

The transition is almost over now. It's worked it's way up to z-index 4 at this point.

The transition is almost over now. It’s worked it’s way up to z-index: 4 at this point.

By the end of the transition, it has z-index of 6 and is on top of all the other divs.

By the end of the transition, it has z-index: 6 and is on top of all the other divs.

So remember: z-index is indeed one of the properties you can apply a transition to, but the transition has to happen in full steps, not necessarily as gradually as you might imagine it in your head.

* If the elements you’re transitioning z-index on are partially transparent (using HSLA for the background color, for instance) to begin with, you can kind of fake this effect. But if you look closely, you can still see the moment the element swaps places with another in the stack. It’s just harder to notice.

View more posts: