A proposal for context aware CSS selectors

Ian Storm Taylor is right, media queries are a hack; they’re just one tool that we need to make the web and our sites as universal as possible. We can’t afford to let ourselves or our clients think that they are a silver bullet, they’re only the start. We need smarter tools to enable us to create truly modular, interoperable CSS components. Making heavy-handed adjustments based on the viewport size works for page layout and components that fill the viewport but it’s not robust enough to handle re-usable modules used in different contexts.

From an authoring point of view it’s clear that using media queries for content-level micro-breakpoints is wrong because we must adjust to a global scope to use them. Tools like Sass get around this syntactically by allowing nestable media queries which is more author-friendly but still icky.

/* Plain CSS */
.foo {  }

@media all and screen(max-width: 640px) {
	.foo {  }
}

/* SCSS nested media queries */
.foo {
	@media all and screen(max-width: 640px) {  }
}

I don’t think it’s a huge jump to make selectors context-aware (Edit: Tab Atkins explains why it is). Level 3 CSS selectors already supports a range of functional pseudo-classes such as :not() and level 4 is proposing extended functionality plus a new :matches() selector. There have been similar ideas for adding media queries as selectors—which is neat—but I propose that the existing pseudo-classes be extended to support media query-like expressions, the only difference being that we are not checking media features but the space available for the matching element.

/* Extending :matches() */
.module:matches(min-width: 300px) {  }

/* Extendending :not() */
.module:not(min-width: 1280px) {  }

As has been the case with web development from the start, we’ve re-appropriated the tools we have (think table layouts, floats etc.) to suit our needs and extending existing functional selectors to accept property expressions (to me) seems like a neat step forwards.