Category Archives: Web

Nesting media queries

In my presentation at Mobilism 2011 (slides) I talked about using logical and and or in media queries. Most of us use and, but I found that not as many people knew about the logical or, which in the case of media queries is the comma. In comma-separated media queries, like this one:

@media screen and (min-resolution: 300dpi), screen and (-webkit-min-device-pixel-ratio: 2) { }

the comma is an or. The first query will be evaluated. If not true, the second one will be evaluated. If one of these is true, the styles will be applied.

Another thing I mentioned (which is on the video but unfortunately not in the slides) is that it is possible to nest media queries. Since we can use media queries in the link element as well as in a CSS file itself, I found that doing both allows you some simple nesting. Whenever you want to apply styles based on two conditions which cannot be fulfilled within a single query, this could be useful.

I couldn’t think of any other use cases at the time other than my typical use case of using min-width queries and having specific page components which need to change at a certain max-width. That works just fine. But then just yesterday Ben Callahan provided us all a new use case: working with logical not.

As I discussed at Mobilism, it is possible to create a media query like so:

@media not screen and (min-width: 600px) { }

This might look like it means “if it’s not a screen but it is at least 600px wide, then apply these styles.” In fact, the not negates the entire query. This is according to spec. So this query actually says, “if it’s not a screen which is at least 600px wide, apply these styles.” That’s a huge difference.

Ben sent an article which he and Matt Griffin wrote in which they describe this problem, as in one key example they wanted to target all media types which are not print. You can’t do:

@media not print and (min-width: 60em)

and expect the min-width to still apply, since the not negates the entire query. So, glad with another possible use case for nesting media queries, I suggested the idea to Ben, who promptly added some nesting tests to the slew of media query tests he’d done for the article. As far as I can tell, Ben’s tests work as expected. By linking to a style sheet like so:

<link … media="not print">

and then in that style sheet creating another query like so:

@media all and (min-width: 60em)

you have created a nice little nested conditional, saying, “as long as the media type is not print, if the minimum width is 60em, apply these styles”. Of course, the only styles that will be applied are those in that particular query block in your style sheet.

While I could confirm Ben’s tests worked in a couple of modern browsers (and an actual printer, of course), it obviously will not work in any browser which doesn’t support the not keyword. And as always, I’m sure there are several other caveats to be found. Nevertheless, it’s a useful trick to know.

Hats off to Ben and Matt for their explorations. Great stuff!

NOTE (2012-10-17): As Bruce Lawson pointed out to me, browsers will most likely support nesting of media blocks in the future.

Great Works of Fiction Presents: The Mobile Context

I love fiction. UFOs, unicorns, faith healing, the Mobile Web, the Mobile Context, psychics. Speaking of which…

I’m sure many of you have heard of cold reading. Cold reading is one of many toolkits used by psychics to convince others (and often themselves) that they know more about a person than they actually do. One of the more well-known and obvious cold reading techniques is the use of simple, broad-stroke statistics. There are lots of people in the world named John. Chances are, if I looked you in the eye, contorted my face, feigned mind-agony and said, “I see a J. Someone in your life… James? John? Someone is having some serious financial trouble,” I’d have a good chance of being technically correct. And that’s not even a good read. But the thing that makes ruses like this work is that you, the user, are filling in the blanks for me. You search your brain and you find John. Or James. Oh you mean Jason, my cousin’s sister’s boyfriend, who does have financial trouble.” Two weeks later, you’ll swear I knew about Jason’s stolen credit card.

In the Mobile Context—you know, that magical fairy-tale place we go whenever we use the Web on our tablets or phones—users apparently don’t need to fill in the blanks. The People Who Make Websites make these decisions. In the Mobile Context, you see, people change. The slide lock on their phone transforms them into beings with different needs. And I use an Android phone, which means my needs are different than an iOS user, because the user experience is obviously not as important to me. Cough.

Cold reading happens in the Mobile Context. Some might find the above sarcasm a rehash of Mark Kirby’s wonderful mind reading assertion. But it’s not, because if I could really mind-read, I would really know what you’re thinking. But I don’t. So I’m not mind-reading, I’m cold reading. And you’re not able to fill in the blanks for me, because a web page is mostly a one-way thing. I can’t quickly change my story by watching your face for signs that I’m on the right track. So when I decide to make decisions for you, I’m potentially sabotaging the experience for the both of us.

So what do we Web-makers do? We infer things based on the device you’re using. And statistics. Analytics. Which means we’ll probably be right much of the time, or some of the time. But there is someone who is right all of the time when it comes to knowing which task a user wants to do in a given situation, even in pretend-universes like Mobile Context: the user, right? If I walk into a coffee shop where they also sell sandwiches, you might be wrong to assume I want a coffee. But if you ask me what I want, and I say, “I’d like a sandwich,” there’s a pretty decent chance that I want a sandwich, yes? And you didn’t get distracted by the fact that 87% of your clients order coffee. And the most beautiful part is this: you didn’t have to put up new menus and change the furniture because I’m a sandwich person. You just need to offer me the choice of a sandwich or a coffee and guess what? I’ll make the choice and order my sandwich.

At Mobilism this year I met Christiaan Lustig, a nice guy and web professional who’s doing a lot of research into responsive design related subjects. He recently wrote an article about top task analysis. The article was actually about many things and it seems so fair to each point of view that I may be missing a single defined argument, but prioritizing top tasks based on user’s needs seems to be the gist of the article. I can agree with that. However, the article also used some examples that really show some current industry thinking I strongly disagree with. Here’s an excerpt from an example about a bank site (go take a look) that just kills me:

“More than 50 per cent of their website visitors are on a mobile device. And 98 per cent of those users go directly to the online banking login.”

That means 49 per cent of all visitors go directly to the online banking login.[…]

First, take a minute to recover from the shock that a majority of banking customers actually plan to do some banking on a bank website. Then notice that we’re provided with only the mobile side of the statistics. 49 percent of all visitors is just plain wrong, unless none of the desktop users go directly to the banking login. We can’t learn from conclusions unless we know what led to them. What do the desktop users do on the site?

To be clear, I’m not criticizing the author of the article at all. I am criticizing the thinking and assumptions behind what many organizations are doing in and around content and responsive web design.

Looking at the screenshots next to the article’s bank example, you can’t help but agree with the author that the mobile rendering of the site seems to be more task oriented. But is that because desktop users really want stupid fluff over tasks? Or is the mobile version of the page the only one for which the Web People seriously considered the needs of the user? In other words, does content really need to change for a mobile context, or do we simply need better content all across the board? I bet the desktop site would be better if they just chucked it and used the “mobile” site for everything. Is the mobile view better because it’s better? Or is it simply better in contrast to a sucky desktop view with irrelevant content?

This example whittles existing content down to a small series of possible tasks on the mobile view. If these are all the tasks a user can do on the site, great. If not, why not? Is it cold in here? Is it cold reading in here?

Let me make a long story short: just make quality, relevant content with appropriate tasks, and offer all of these to all users, unless said content or functionality is dependent upon device capabilities (such as a camera). Then make it easy for the user to decide what it is they want to do. It’s like… web development all over again, isn’t it?

I really don’t see any reasons for the content of a page to change completely under any device-related circumstances. In fact, for purposes of clarity and findability, why not go out on a limb and actually use URLs to refer to specific content or functionality, instead of trying to morph homepage content into something different on a phone and hoping you get the assumptions right? example.com/login, example.com/plan, example.com/status. You’re allowed to have a page which simply contains the tasks and content it contains. Really, it’s okay. It’s responsive design; we’re not making shapeshifters.

Alter the design as you will. Visually, content order is most likely linear on phones, so you’ll account for that. Text size, link and button size, image (file) size… there are plenty of things to consider. Of course you might not be able to have that Really Important Canvas Animation. Of course you’ll want to be able to use some device capabilities like your phone’s camera if that’s available. That’s logical and fine. But if something is essential content, functionality, or common sense on all platforms and you’re only providing it on some, you’re doing it wrong, unless your site or app is unavailable on other platforms.

Users are ultimately the experts in deciding what they want to do on your site. Make it possible, make it easy, then get out of the way and let them fill in the blanks. They’ll attribute the good experience to you.

Multi-column confusion

tl;dr: Be careful when using multi-column layout.

Today I was finishing up a small portion of a project which involves generating PDFs with a multi-column layout from web content. Since we’re using the Prince formatter for the PDFs, there are no worries there, as Prince is one of the finest rendering engines out there, especially for this kind of thing.

But since I also created a live preview so the client can see their text in the intended layout while typing, I tested in some major desktop browsers. I was in in for a big surprise.

For anyone familiar with CSS Multi-column layout, the spec says basically—if I understand it correctly—that if no height is specified on the element containing the text columns, then the text should be distributed amongst these columns so that they are of (roughly) equal height. The value for this behavior is balance. If a height is specified, then the browser should use the value of the column-fill property, if it has been specified. If there is no column-fill property, then the browser should still balance the columns. Go ahead and read that again. I’ll wait.

I had set a height on my container. So I was confused about the fact that Chrome/Safari and Firefox were applying auto where they should have been applying balance.

A column-fill value of auto means that the browser should fill the columns in sequence, starting with the first column and filling it, then column two, etc. until there is no remaining text. The browser can do this because it knows the height of the column container. So the spec makes perfect sense, but I was scratching my head at this point. I had specified a height, but not column-fill. Every browser should have used balance, but only Opera did.

Well, I’m thinking it’s me, then I’m thinking it’s not me, so I tweet about it. Fellow CSS layout fan (and author of The Book of CSS3) Peter Gasston and I started chatting about it and tonight we jumped on GTalk and starting testing. Turns out the answer is quite simple: Peter starts off by telling me how Firefox and the Webkit browsers haven’t fully implemented the spec yet. I should have known that, but I didn’t, like an idiot. And it’s logical because the spec is obviously not finished yet.

But even after knowing that, it’s still pretty confusing, because which behavior conforms to the spec right now and which doesn’t? What’s supposed to happen when? I mapped my tests out in the form of two small comparison tables. They might look confusing, but they really aren’t. It’s pretty easy to figure out what you’d need to do to get either balance or auto. Even when the spec is implemented, it’s still useful to know under what conditions each of these values will be acted upon.

Multi-column column-fill defaults, when column-fill is not explicitly specified.
  Opera Firefox Chrome/Safari
No explicit height on container balance balance balance
Explicit height on container balance auto * auto *
Multi-column column-fill behavior when column-fill property is explicitly specified.
  Opera Firefox Chrome/Safari
column-fill: balance;
(container height specified)
balance auto * auto *
column-fill: balance;
(No container height specified)
balance balance balance
column-fill: auto;
(container height specified)
auto auto auto
column-fill: auto;
(No container height specified)
balance balance balance

As far as Peter and I can tell, the only behavior which does not conform to the spec is marked in red and with an asterisk. The rest seems (to me) to conform to the spec.

Again, I’ve run into this kind of thing because I’m knowingly using a spec which is not fully implemented. If you do the same, please realize that things can go wrong, and that you’re basically working with a work-in-progress. It might change, and you might have to change your code in the future. If you do use Multi-column now, please use it as a progressive enhancement. And don’t forget to use all the necessary vendor prefixes so that we all may live in peace and harmony.

As always, have fun!