At CSS Day last June I introduced, with some trepidation, a peculiar three-character CSS selector. Called the “lobotomized owl selector” for its resemblance to an owl’s vacant stare, it proved to be the most popular section of my talk.
I couldn’t tell you whether the attendees were applauding the thinking behind the invention or were, instead, nervously laughing at my audacity for including such an odd and seemingly useless construct. Perhaps I was unwittingly speaking to a room full of paid-up owl sanctuary supporters. I don’t know.
The lobotomized owl selector looks like this:
* + *
Despite its irreverent name and precarious form, the lobotomized owl selector is no mere thought experiment for me. It is the result of ongoing experimentation into automating the layout of flow content. The owl selector is an “axiomatic” selector with a voracious purview. As such, many will be hesitant to use it, and it will terrify some that I include it in production code. I aim to demonstrate how the selector can reduce bloat, speed up development, and help automate the styling of arbitrary, dynamic content.
Styling by prescription#section2
Almost universally, professional web interface designers (engineers, whatever) have accustomed themselves to styling HTML elements prescriptively. We conceive of an interface object, then author styles for the object that are inscribed manually in the markup as “hooks.”
Despite only pertaining to presentation, not semantic interoperability, the class selector is what we reach for most often. While elements and most attributes are predetermined and standardized, classes are the placeholders that gift us with the freedom of authorship. Classes give us control.
.my-module {
/* ... */
}
CSS frameworks are essentially libraries of non-standard class-based ciphers, intended for forming explicit relationships between styles and their elements. They are vaunted for their ability to help designers produce attractive interfaces quickly, and criticized for the inevitable accessibility shortcomings that result from leading with style (form) rather than content (function).
<a class="ui-button">press me</a>
Whether you use a framework or your own methodology, the prescriptive styling mode also prohibits non-technical content editors. It requires not just knowledge of presentational markup, but also access to that markup to encode the prescribed styles. WYSIWYG editors and tools like Markdown necessarily lack this complexity so that styling does not impede the editorial process.
Bloat#section3
Regardless of whether you can create and maintain presentational markup, the question of whether you should remains. Adding presentational ciphers to your previously terse markup necessarily engorges it, but what’s the tradeoff? Does this allow us to reduce bloat in the stylesheet?
By choosing to style entirely in terms of named elements, we make the mistake of asserting that HTML elements exist in a vacuum, not subject to inheritance or commonality. By treating the element as “this thing that needs to be styled,” we are liable to redundantly set some values for the element in hand that should have already been defined higher in the cascade. Adding new modules to a project invites bloat, which is a hard thing to keep in check.
.module-new {
/* So... what’s actually new here? */
}
From pre-processors with their addition of variables to object-based CSS methodologies and their application of reusable class “objects,” we are grappling with sandbags to stem this tide of bloat. It is our industry’s obsession. However, few remedies actually eschew the prescriptive philosophy that invites bloat in the first place. Some interpretations of object-oriented CSS even insist on a flattened hierarchy of styles, citing specificity as a problem to be overcome—effectively reducing CSS to SS and denying one of its key features.
I am not writing to condemn these approaches and technologies outright, but there are other methods that just may be more effective for certain conditions. Hold onto your hats.
Selector performance#section4
I’m happy to concede that when some of you saw the two asterisks in * + *
at the beginning of this article, you started shaking your head with vigorous disapproval. There is a precedent for that. The universal selector is indeed a powerful tool. But it can be good powerful, not just bad powerful. Before we get into that, though, I want to address the perceived performance issue.
All the studies I’ve read, including Steve Souders’ and Ben Frain’s, have concluded that the comparative performance of different CSS selector types is negligible. In fact, Frain concludes that “sweating over the selectors used in modern browsers is futile.” I’ve yet to read any compelling evidence to counter these findings.
According to Frain, it is, instead, the quantity of CSS selectors—the bloat—that may cause issues; he mentions unused declarations specifically. In other words, embracing class selectors for their “speed” is of little use when their proliferation is causing the real performance issue. Well, that and the giant JPEGs and un-subsetted web fonts.
Contrariwise, the * selector’s simultaneous control of multiple elements increases brevity, helping to reduce file size and improve performance.
The real trouble with the universal sector is that it alone doesn’t represent a very compelling axiom—nothing more intelligent than “style whatever,” anyway. The trick is in harnessing this basic selector and forming more complex expressions that are context-aware.
Dispensing with margins#section5
The trouble with confining styles to objects is that not everything should be considered a property of an object per se. Take margins: margins are something that exist between elements. Simply giving an element a top margin makes no sense, no matter how few or how many times you do it. It’s like applying glue to one side of an object before you’ve determined whether you actually want to stick it to something or what that something might be.
.module-new {
margin-bottom: 3em; /* what, all the time? */
}
What we need is an expression (a selector) that matches elements only in need of margin. That is, only elements in a contextual relationship with other sibling elements. The adjacent sibling combinator does just this: using the form x + n, we can add a top margin to any n where x has come before it.
This would, as with standard prescriptive styling, become verbose very quickly if we were to create rules for each different element pairing within the interface. Hence, we adopt the aforementioned universal selector, creating our owl face. The axiom is as follows: “All elements in the flow of the document that proceed other elements must receive a top margin of one line.”
* + * {
margin-top: 1.5em;
}
Completeness#section6
Assuming that your paragraphs’ font-size is 1 em
and its line-height is 1.5, we just set a default margin of one line between all successive flow elements of all varieties occurring in any order. Neither we developers nor the folks building content for the project have to worry about any elements being forgotten and not adopting at least a standard margin when rendered one after the other. To achieve this the prescriptive way, we’d have to anticipate specific elements and give them individual margin values. Boring, verbose, and liable to be incomplete.
Instead of writing styles, we’ve created a style axiom: an overarching principle for the layout of flow content. It’s highly maintainable, too; if you change the line-height, just change this singular margin-top value to match.
Contextual awareness#section7
It’s better than that, though. By applying margin between elements only, we don’t generate any redundant margin (exposed glue) destined to combine with the padding of parent elements. Compare solution (a), which adds a top margin to all elements, with solution (b), which uses the owl selector.

Now consider how this behaves in regard to nesting. As illustrated, using the owl selector and just a margin-top value, no first or last element of a set will ever present redundant margin. Whenever you create a subset of these elements, by wrapping them in a nested parent, the same rules that apply to the superset will apply to the subset. No margin, regardless of nesting level, will ever meet padding. With a sort of algorithmic elegance, we protect against compound whitespace throughout our interface.

This is eminently less verbose and more robust than approaching the problem unaxiomatically and removing the leftover glue after the fact, as Chris Coyier reluctantly proposed in “Spacing The Bottom of Modules”. It was this article, I should point out, that helped give me the idea for the lobotomized owl.
.module > *:last-child,
.module > *:last-child > *:last-child,
.module > *:last-child > *:last-child > *:last-child {
margin: 0;
}
Note that this only works having defined a “module” context (a big ask of a content editor), and requires estimating possible nesting levels. Here, it supports up to three.
Exception-driven design#section8
So far, we’ve not named a single element. We’ve simply written a rule. Now we can take advantage of the owl selector’s low specificity and start judiciously building in exceptions, taking advantage of the cascade rather than condemning it as other methods do.
Book-like, justified paragraphs#section9
p {
text-align: justify;
}
p + p {
margin-top: 0;
text-indent: 2em;
}
Note that only successive paragraphs are indented, which is conventional—another win for the adjacent sibling combinator.
Compact modules#section10
.compact * + * {
margin-top: 0.75em;
}
You can employ a little class-based object orientation if you like, to create a reusable style for more compact modules. In this example, all elements that need margin receive a margin of only half a line.
Widgets with positioning#section11
.margins-off > * {
margin-top: 0;
}
The owl selector is an expressive selector and will affect widgets like maps, where everything is positioned exactly. This is a simple off switch. Increasingly, widgets like these will occur as web components where our margin algorithm will not be inherited anyway. This is thanks to the style encapsulation feature of Shadow DOM.
The beauty of em
s#section12
Although a few exceptions are inevitable, by harnessing the em
unit in our margin value, margins already adjust automatically according to another property: font-size. In any instances that we adjust font-size, the margin will adapt to it: one-line spaces remain one-line spaces. This is especially helpful when setting an increased or reduced body font-size via a @media
query.
When it comes to headings, there’s still more good fortune. Having set heading font sizes in your stylesheet in em
s, appropriate margin (leading whitespace) for each heading has been set without you writing a single line of additional code.

Phrasing elements#section13
This style declaration is intended to be inherited. That is how it, and CSS in general, is designed to work. However, I appreciate that some will be uncomfortable with just how voracious this selector is, especially after they have become accustomed to avoiding inheritance wherever possible.
I have already covered the few exceptions you may wish to employ, but, if it helps further, remember that phrasing elements with a typical display value of inline
will inherit the top margin but be unaffected in terms of layout. Inline elements only respect horizontal margin, which is as specified and standard behavior across all browsers.

If you find yourself overriding the owl selector frequently, there may be deeper systemic issues with the design. The owl selector deals with flow content, and flow content should make up the majority of your content. I don’t advise depending heavily on positioned content in most interfaces because they break implicit flow relationships. Even grid systems, with their floated columns, should require no more than a simple .row > *
selector applying margin-top: 0
to reset them.

Conclusion#section14
I am a very poor mathematician, but I have a great fondness for Euclid’s postulates: a set of irreducible rules, or axioms, that form the basis for complex and beautiful geometries. Thanks to Euclid, I understand that even the most complex systems must depend on foundational rules, and CSS is no different. Although modularization of a complex interface is a necessary step in its maturation, any interface that does not follow basic governing tenets is going to lack clarity.
The owl selector allows you to control flow content, but it is also a way of relinquishing control. By styling elements according to context and circumstance, we accept that the structure of content is—and should be—mutable. Instead of prescribing the appearance of individual items, we build systems to anticipate them. Instead of prescribing the appearance of the interface as a whole, we let the content determine it. We give control back to the people who would make it.
When turning off CSS for a webpage altogether, you should notice two things. First, the page is unfalteringly flexible: the content fits the viewport regardless of its dimensions. Second—provided you have written standard, accessible markup—you should see that the content is already styled in a way that is, if not highly attractive, then reasonably traversable. The browser’s user agent styles take care of that, too.
Our endeavors to reclaim and enhance the innate device independence offered by user agents are ongoing. It’s time we worked on reinstating content independence as well.
The lobotomized owl selector just completely blew up every style sheet I’m currently working on. Brilliant.
This just changed my life. It’s THE solution I didn’t know I was looking for. You have permanently changed the way I approach CSS. Brilliant.
@Steve Hurst
Sorry to hear that 😛
It’s probably not something you should add late in a project’s maturity. That’ll mess things up.
It’s something you might consider as a starting point.
Wow. This is so simple and elegant. It’s 3 characters (not counting spaces, of course), but seems like the kind of thing that can subtly affect one’s entire approach to writing and architecting CSS.
I can see it being very useful for a simple vertical rhythm system.
Off to see where it leads me…thanks!
I’ve written a long and rambly reply to this article on my blog (way too long for a comment): “On class names, semantics and accessibility”
To summarize that post: I think the “lobotomized owl” technique is pretty cool, and I’m all for clever stuff we can do with selectors. However, when it goes into a critique of “OOCSS”-ish patterns, you bring up an example where broken markup (an unfocusable link, missing an href) somehow is associated with naming conventions and the use of presentational classes.
Personally, I currently think that the benefits of these types of class names outweigh the cons – as do many other people. I try to argue some of your points in my post. Where ever one might land in that particular discussion, arguments against need to do better than to drag accessibility into it. Good HTML structure and choosing a particular naming convention are not mutually exclusive.
Makes a lot of sense. Anything to keep CSS simple…
It’s not just the owls that need lobotomies.
The notion that HTML is an instrument to implement design is one of the key things that people need to unlearn. IMHO.
We need more articles like this one to illuminate this. @ThatEmil also has some good points 😉
As for the lobotomized owl – I think cases where I would be able to get away with using it would be few and far between. But at work we have been using its more sane cousins (p + p, etc) for the last 3 or so years 🙂
@Emil Björklund
> “you bring up an example where broken markup (an unfocusable link, missing an href) somehow is associated with naming conventions and the use of presentational classes. ”
Yes. Yes it is ‘somehow associated’ with naming conventions. Here is the conventional (broadly accepted and ratified) convention for marking up buttons:
This selector pertains directly to the correct markup for a button, ensuring that the appearance of the button correctly signifies an interoperable object, accessible to a maximal number of users.
No, using a presentational class does not make the markup inaccessible in and of itself. You are quite right. However, it would be naive to suppose that styling practices which are agnostic to markup practices are conducive to accessible interface design.
Classes allow us to meet presentational/aesthetic needs quickly and without recourse to semantic differences that could and should be felt by users who hear and/or touch interfaces as well as users who see them. This is why class methodologies can, and demonstrably do, precipitate poor accessibility: They let us be lazy.
So, no, classes do not break accessibility. But they allow us to eschew it; to dance around it. We pretend we’re only doing it for now, and that we’ll build in the accessibility later, but it doesn’t happen until an audit comes along. Then we’re screwed, because structure and surface are different things.
> ” Good HTML structure and choosing a particular naming convention are not mutually exclusive.”
To build accessible interfaces, accessibility has to be part of the process from the beginning and throughout, which means it has to be connected with the design that we see. Choosing naming conventions should not be separate from HTML structure, no. That’s why it is important to refer to the dictionary: http://www.w3.org/html/wg/drafts/html/master/
There is recursiveness in * + *.
This is damned elegant, and one of the freshest things I’ve seen in CSS for a while. I’m curious—what are some of your other favorite uses for the * + * beyond top-margins?
@Jeremy Carlson To be honest, the `top-margin` property is the only one I use. It’s a normalization rule, used to make all objects adhere to a basic vertical rhythm. There are many more handy uses for the adjacent sibling combinator, though. I often use something like
`section + section { border-top: 0.25em; padding-top: 3em; margin-top:
3em; }’
to divide up sections of content without leaving a pesky trailing border / padding / margin. You can see sort of thing on the geekmentalhelp.com website I’ve been working on with Andrew Clarke. The border is only applied to successive `.submission` blocks, so when I merge a pull request with a new submission, everything stays neat.
@Heydon: You missed the part where I said the following:
You and me both agree that using something like a
span
element with a truckload of JavaScript attached to create a button-like things is bad practice. To say that anything that is made to look like a button should be abutton
element is taking that too far.Links are interactive elements. You click on them and something happens. It’s not unreasonable that from a design standpoint, it may be desirable to have them look button-y. Using a class name to gather that styling information in one place makes a lot of sense, and doesn’t prevent you from also applying a sensible default styling to
button
elements.Consider the example of a page where we want to highlight the action of creating a new item. The form for the new item is on a separate page. Should we be forbidden to style that link as a button? I certainly don’t think so.
I get what you’re saying regarding the affordances of tech: if we focus too much on style and ignore accessibility until the last minute, we’re screwed, and there’s definitely plenty of examples of frameworks and plugins out there that do that.
But you said it yourself: classes are where we as authors are free to bring our own naming schemes. Elements are standardized (and should be used correctly), classes are not. I don’t understand why you point me towards the HTML5 spec for that.
@Emil I like your example of the link that looks like a button but takes you to another form page. Indeed, that should probably look like a button but be announced as a link in AT. Good point.
But my grievance with classes emerges where they are vaunted as a UI construction tool, when they are really a UI decoration tool. I used the a:not(href) example because it exemplifies the misapprehension that putting the class of `.button` on the link _makes_ it a button; that our name of `.button` is semantic in any real sense.
The framework “Semantic UI”, for instance, defines buttons as
Making a link look like a button is fine in certain circumstances, like the one you suggest, but one does this with deliberation: “This should be a link, but the appearance should suggest the action is somewhat button-like”.
That’s not what my example is about. It’s more like “I heard buttons are form elements, but I’m not in a form so I’ll use a link. I won’t be needing that href. Should I check what effect removing the href has? Nah, it’s probably fine. All my users will see it’s a button so I’ll call it good.”
You start your article / reply by saying “naming things is hard”. It’s my opinion that most of the important naming (the names of elements like
This is a pretty neat discovery. I would love to see this approach adopted into popular front end frameworks.
Combining the owl selector with a build process like UnCSS would make for a pretty lean stylesheet.
Great thread and comment dialog. Thanks for the post.
Is this equivalent to *:not(:first-child)?
nice!
GREAT article. I’d find it a better read though if you avoided the thesaurus words and just used words that are in our every day vocabulary though. Like “unaxiomatically” or “interoperability”. I think it’s a much better read when you use the same words you’d use when speaking. I had a writing teacher who said something that I’ll never forget, “read above your level and write below it.” That’s my 2 cents anyway.
a very thoughtful piece, thanks for this.
as CSS developers & designers, we need to understand specificity and strive to wield it masterfully, and you have provided the community with a great example of doing so with your lobotomized owl selector.
to paraphrase from above, we must keep the ‘C’ in CSS.
So refreshing to see people point out that different things about CSS can actually be used. It’s very disappointing to see so many people parrot mantras like, “Don’t ever use the universal selector,” or, “Just put classes all over your HTML and then use those as your styling hooks.” I have used the universal selector before in cases like this where I wanted/needed everything within a certain element to adopt a particular style rule.
@Devin McGregor
> Is this equivalent to *:not(:first-child)?
Almost, because that would style `root` too. To get the same selection without relying on the universal selector, I think we could simply use:
:not(:first-child):not(:root)
But in “real life”, I’d recommend sandboxing this *where needed* rather than blindly styling every_single_element on a page. May be doing something like this:
.in-between-margin-trick :not(:first-child) {
margin-top: 1.5em;
}
or (for IE8 support)
.in-between-margin-trick * + * {
margin-top: 1.5em;
}
In my opinion, we should strive to style things **as little as possible**… Because the less things you style, the less styles you have to style against.
Great article, I totally agree with this way of writing CSS, avoiding presentation classes as much as possible.
Don’t give in to the madness of OOCSS-ish patterns, it’s just bloat!
@Thierry Hi! This wouldn’t be one of my CSS articles without us having a discussion. Welcome.
Today, you’re not making much sense to me, Thierry.
First, you construct an equivalent to * + * (:not(:first-child):not(:root) – which has less support and is harder to write) then seem to suggest using this with a * + * fallback for IE8, all in the context of suggesting we should be writing _less_ CSS!
> “In my opinion we should be striving to style things as little as possible.”
Unnecessary fallbacks aside, you are saying that * + * should be confined to specific contexts because “the less things you style, the less styles you have to style against”. You omit one important factor: If the * + * does not apply margin to objects outside of these contexts, something _else_ will have to. You seem to foresee a problem with overriding styles applied with * + *, but your solution is itself an override.
The point is, * + * styles more things _with_ less. That is what smart CSS selectors do because they increase the brevity and maintainability of the stylesheet and keep the appearance of the document uniform. The radical thing about * + * that you may be missing is that it works best not as something you introduce, but as a foundation.
@Pat Brady
I’m glad you enjoyed the article and I’m sorry to hear you struggled with some of the language. Believe it or not, this is how I talk and write, without referring to a Thesaurus.
I find your teacher’s mantra a little odd. If everyone is writing below their reading level, a scarcity is produced of writing that is above the level of the average reader (?)
Interesting article and interesting comments. I love the creativity of this CSS, something which is often missing when writing!
This article could have easily been from 2007. There is nothing new, and it has been known for a long time that the way you write selectors doesn’t really affect speed, browser vendors made sure of that, and it’s obvious that the more selectors you have the longer the browser needs to parse and apply them. So I don’t really understand why the author had spent hours of his time writing something that has been written already countless times…
@Yair Even Or
Sorry to disappoint, Broseph.
Perhaps you could point me to the countless expositions of lobotomized owl-based CSS techniques from 2007?
I enjoyed this article. You thoroughly explained your reasoning and justified why it can be useful, and provided work arounds. It’s not something you see a lot of anymore. I see a lot of articles that suggest something and barely explain why (A List Apart excluded).
As for the technique, I will certainly see how it performs for me, and it is a shame this article did not come about a couple weeks ago, as I would have had the chance to play with it on a new project.
I (as well as everyone I suppose) come across the whole ‘&:last-child { margin-bottom: 0; }’ fiasco regularly, and I have noticed recently that I am applying a lot more classes to my HTML to create more modularity, and ignoring the ‘C’ in CSS as you suggest. I think this is in part to the grid system way of thinking, that and I use them to describe an element.
Sometimes I do wonder whether my CSS is better than it was just a few years ago…
@Devin McGregor & Thierry:
*+* and :not(:first-child) select the same, but there’s a big difference: specificity.
The owl’s specificity is 000, whereas *:not(:first-child)’s specificity is 010. Because of this *:not(:first-child) cannot be overwritten by element type selectors.
Rules like *+* {margin-top: 1.5em} set a default and should be easy to overwrite, i.e. must have low specificity. That’s why owl, not *:not(:first-child).
These types of techniques remind me of when I first read bullet proof web design back in 2005. Thanks for the article!
This makes my life so much easier! Vertical rhythm is one of the most annoying parts of web design to consistently get right, and this solves the issue of compounding margins really elegantly. Love it!
@Gunnar & Heydon:
Heydon, you’re putting my “suggestion” out of context. I was answering Devin question, which was:
> Is this equivalent to *:not(:first-child)?
You also say:
> Unnecessary fallbacks aside
What fallback are you talking about? These are not 2 rules to use together. The “or” between the rules means one would pick the rule depending on the browsers she supports.
Gunnar, I don’t think specificity plays much of a role here (unless you sandbox the rule as I suggested). If the styling needs to be overwritten, I’d expect people to use a class for that (0,0,1,0), and that would be enough to do the job. If overriding this style via a type selector is a possibility, then we may wonder why we are aiming at almost *all elements* on the page in the first place.
Also, I won’t discuss performance because I know I cannot win that war here, but I’d like to mention that this is not just the universal selector. It is the universal selector, a combinator, and the universal selector again. Paul Irish said this:
> [*] can be slow when you specifically use it like .foo > *, so don’t do that.
Think about it…
Now let’s try to remember the discussions we had when we were talking about resets, base style sheets, normalize, etc. We were trying to make sense of what to style and what not. The infamous * {margin:0;padding:0;} rule didn’t come back to life after people started saying there was no performance hit using such rule. And I think there is a reason for that.
Heydon says:
> The radical thing about * + * that you may be missing is that it works best not as something you introduce, but as a foundation.
If we kept the reset I just suggested, that foundation would become:
* {
margin: 0;
padding: 0;
}
* + * {
margin-top: 1.5em;
}
And that’s called overwriting too. CSS is about overwriting stuff. You say applying a specific margin to almost all elements leads to less overwrites, I say it’ll lead to the opposite.
Let’s give this some time. After all, we have seen people complaining that the “universal” reset was creating issues with some form controls, then we’ve seen people complaining about the too broad styling of box-sizing (Jonathan Neal then introduced “inherit”)…
@Thierry
Hello again.
> “What fallback are you talking about? These are not 2 rules to use together. The “or” between the rules means one would pick the rule depending on the browsers she supports. ”
There is no “or”. Why would you _ever_ choose a longer selector with demonstrably lower browser support when the two in contention do precisely the same thing? Madness.
> “If the styling needs to be overwritten, I’d expect people to use a class for that (0,0,1,0), and that would be enough to do the job.”
By people you mean developers. I’m talking about creating style schemae that accomodate content contributors. The low specificity _is_ important because it makes writing element-based (WYSIWYG / markdown produced) selectors as overrides easier.
> “Paul Irish said this: > [*] can be slow when you specifically use it like .foo > *, so don’t do that.”
Much as I respect his work, I don’t care what Paul Irish said. Show me bench tests. Show me evidence that the purported difference has any impact on users. I just siege tested a site which uses the lobotomized owl selector. Guess what? A big ASCII skull and crossbones did not appear in the command line with the rubric “selector performance death” 😛
@Heydon,
In this article, you use Steve Souders and Ben Frain names as a mean to brush away the performance issue but then you dismiss Paul Irish’s finding – even though what he reports is closer to the selector you’re using than what Steve and Ben discuss.
And asking for *bench tests* confirms that you have no data to backup your claim. It’s unfortunate that the reviewer(s) of this article didn’t suggest you to provide some data. I think that would not be necessary if there was some sort of consensus but as I pointed out, this is not the case here.
> I’m talking about creating style schemae that accomodate content contributors.
Then you should be *clear* about that so devs don’t think this is some kind of magic rule they should plug in every project.
Anyway, I won’t debate further here. I’d be better writing an article about this as at least I’d be able to **format** things the way I want 😉
@Thierry
It is not my or anyone else’s job to prove the nonexistance of something. That is a logical impossibility. I only point to Souders’ and Frain’s studies to underline the _lack_ of evidence for the stated issue – that the difference between selectors’ performance ACTUALLY MATTERS. It is one thing to say the difference can be measured and quite another to prove a detrimental effect caused by that difference.
> “And asking for *bench tests* confirms that you have no data to backup your claim.”
I am not making a claim, I am pointing to the lack of evidence for a claim. It is the job of the person that _claims_ something exists (in this case a significant performance issue with certain selector types) to prove it. That is how the “burden of proof” works: “the necessity of proof always lies with the person who lays charges.”
It is your claim; prove it is worth considering.
+1 on the formatting.
Talk is cheap. Show me the code.
You, sir, just blew my mind.
* + *
is indeed the ultimate selector for vertical rhythm – and, most importantly, it is beautiful to see on the screen.Ever since your talk at CSS Day, I read your posts in your accent…
Nice work!
I too think your language is to complicated. Considering the type of article, I believe that you should avoid using unnecessary words to not distract the readers and focus mostly on getting the message out.
@Ваня Яни
The less lazy among us have tested it out themselves. Here are a few examples:
http://codepen.io/jreece/pen/fapDE
http://codepen.io/bradwestfall/pen/yGJCK
http://codepen.io/laviperchik/pen/lCrnt
http://codepen.io/ajfarkas/pen/cafsv
http://codepen.io/lenngren/pen/GucBr
http://codepen.io/amandadorrell/pen/wClAn
First: ‘I love the idea!’. But to place this in context, I never use margin-top. Simply because the whole idea is that an element is positioned in a flexible way on the page, in most cases by the elements above. The same idea goes for p-tags or header elements.
So why not place margin-bottom on every * and reset the margin on last elements?
* {
margin-bottom: 10px;
}
*:last-child{
margin-bottom: 0;
}
So this is not by a level of depth and it is more clear to understand, no illustrations needed?
That being said, my use cases for the ‘+’ selector are very limited, and if you can prove me wrong, please do!
@Spillebeen Mathieu
> First: ‘I love the idea!’
Who said that? Was it someone famous?
> So why not place margin-bottom on every * and reset the margin on last elements
Because then you’d be doing two things instead of just one.
> That being said, my use cases for the ‘+’ selector are very limited, and if you can prove me wrong, please do!
Please enumerate your use cases. Without this information it would be difficult to prove anything.
@Spillebeen Mathieu
Readability, maintainability: http://codepen.io/anon/pen/gboyJ
Why reset if you do not need to?
For content-specific elements (such as p+p), ems would be preferable since you are dealing with font-size changes.
For structure level elements however, I would suggest using either a rem unit or multiplier of that so that space between containers will be uniform.
Therefore, it would be preferable to first define *+* in rems then cascading typographic content such as p+p as ems. This guarantees that spacing between elements will be uniform and that content will not appear crowded.
@Thierry
> If the styling needs to be overwritten, I’d expect people to use a class for that (0,0,1,0)
Just no. I don’t. I concider styling solely on classes (propagated by approaches like OOCSS) as the most erroneous trend in frontend development in the last decade.
Sticking to the marging-top example, one might reduce margin between adjacent headings:
h1+h2, h2+h3, h3+h4, h4+h5, h5+h6 { margin-top: 0.5em }
No need for polluting the markup with classes.
Above rule would not overwrite :not(:first-child), but it overwrites *+*, as desired. Specificity is an issue here.
been using the direct-neighbor selector for some case, but so far, i’ve been holding myself from using it as a global selector because:
– form controls (
label + input
,label + label
,button + button
, …)– (inline)grids (
.column + .column
)– inline-block elements that happen to be neighbors in text (for example some “tags”)
but as a general rule, i’m using
li + li
,p + p
,.row + .row
, … quite oftenPS
nice article 🙂
I recently ran a test using something like this `.parent > * + *` I thought that the performance seemed expensive compared to `.parent > .item` Since CSS selectors are evaluated from right to left using * + * at the end would require everything on the page to be considered twice?
I would suggest measuring the performance of a selector like `* + *` to see if you are happy with the speed of the selector.
So here is an example test Testing a CSS selector: lobotomized owl selector
You can compare using this lobotomized owl selector (Universal adjacent sibling combinator selector) vs. a descendant class selector test-lobotomized-owl-selector-speed.html and test-descendant-class-selector.html
There isn’t much if any of a performance difference. At least its in the tens of milliseconds range.
Brilliant. Love the illustration, the wise words, and the wonderfully named lobotomized owl selector.
Thoughtful article. A nitpick about the axiom definition. Wouldn’t it actually be defined as “All elements in the flow of the document that succeed other elements must receive a top margin of one line.” This might just be a disconnect in British and American English.
This is awesome. With working to change my CSS style from form-centric to function-centric, this will be a great addition! Great article and some really good comments. Thanks for sharing this bold idea.
DONT. LOBOTOMIZE. OWLS.
Nice approach, I’ll try this on my next project, instead of the good ol’ :last-child technique.
My main experience and concern about OOCSS practices is that it can be easily misused. If the CSS is not carefully planned and your team doesn’t follow specifications strictly, it can become a bad substitute for inline styles. And although we can give this practices sweet names like micro-styling, it could be called style-as-you-go.
In one of my last projects I delivered a stylesheet with something like:
One of the worst mistakes I’ve ever done in my life. It was immediately adapted as some kind of inline styling technique.
I was there during CSS Day and it was because of: “the thinking behind the invention”.
Just saying.
hi
This blew my mind! Goes to show that less is always more.
found myself writing this today (in SCSS, obviously):
> * + * {
voilà – the Niki Lauda owl, with two different ears
What the heck am I misunderstanding? I tried a fiddle (http://jsfiddle.net/skube/ddzsp9ax/) and expected the `two` block to have the top margin, but it doesn’t.
Edit: n/m I think it’s a specificity issue but then I would argue your figure (http://alistapart.com/article/axiomatic-css-and-lobotomized-owls#figure5 ) is slightly inaccurate and should show `.row * + *` instead of simply `* + *`
nice post on Axiomatic CSS. thanks
This article was, as always, a wonderfully-refreshing journey and ‘eye-opener’ for me.
I wonder about 1 thing though: What happens when we introduce HTML5’s document outlining algorithm using sections, such as:
After trying it out with the lobotomised owl (poor thing) with
margin-top
as you’ve described, it seems that theh1
loses its needed larger spacing between it and the paragraph, and instead the second section now has a smaller margin-top of it’s own.I do wonder why I’d put the sectioning elements there in the first place if I’m not going to style them (and thus give them visible boundries), but that’s motivated for in the HTML5 Sectioning spec.
Thank you for the article, It was a real eye opener as to the stupid simple things that you can do with css. I have actually implemented this on a site that I’m currently working on and for the most part it has worked out pretty well.
I did run into a big issue with the
* + *
selector and all its glory. Some unwanted spacing happens when you use<style></code>,
<link></code>,
[removed]
,<meta></code>. These selectors are very common when working on a large site in a framework and when adding micro data to your code. To see the issue you can see them in this pen
I have solved this unwanted issue by making an addendum to the
* + *
selector. The following works for every browser that supports the:not()
selector, which is every browser except IE8 and below. Check out the updated lobotomized owl selectorIf you have to support IE8 and below, I feel really really sorry for you. Fortunatlly for you the code below will work correctly 95% of the time.
The only case where it adds unwanted space is when you have something like below.
However this will work just fine.
After using this, it seems a few “reset” selectors are necessary.
CSS is things which offer world class web page designing according to your choice. if you use CSS is prefer Div base design. Thank you, great information.
Semantic UI is a library based around bringing useful linguistic concepts (plurality, different between modifiers and types, tense etc) to web development. Semantics does not refer to the misappropriation of the word to mean “Adherence to W3C web specification” but instead to its linguistic origins in creating systems of meaning, like Montague grammar. This argument about prescriptivist / descriptivist dilemma is well traveled territory in the field of linguistics, but still novel for the field of contrived languages, like programming languages. Generally anyone who create a formal system of language is bound to some level of prescription, but can avoid the overwhelming negative aspects of that ‘original sin’ by creating standards by consensus and convention. This is the same issue that Merriam Webster once struggled with or the Académie française.
With regards to the owl selector, Semantic uses it adjacent sibling selectors (owl) quite frequently for spacing within components.
They are generally very useful, but its worth a word of caution that they will not always apply correctly to arbitrary content. Any component that leads with an element that is not
display: block
orposition: static
will disrupt the vertical spacing of the component.With regards to CSS specificity: I don’t believe the idea of inheritance is broken, but the means of calculating specificity certainly is. Until there is a way to manually specify a ‘specificity index’ (like a z-index), we will be bound by the arbitrary tedium of automatic specificity calculations which don’t always do what we want (or expect) it to do.
@Semantic UI: Yeah, I think you failed basic semantics by doing this:
Love this technique.
Be aware that there is a small issue in Firefox (35) with
<br>
elements. Even though they’re flow elements Firefox will put margin between them when repeated, ie.<br><br>
. Easily fixed by addingbr { margin-top: 0; }
.Pretty sure this is a bug as I wouldn’t expect
<br>
elements to have margins, and other browsers do not have this behaviour.Do we clear out other margins before the lobotomized owl?
* { margin: 0; }
* + * { margin-top: 1.5em; }
Other than the fact that anything laid out horizontally gets murdered by this technique, it’s pretty sweet. Seems to be a good foundation for anything that’ll go into an article body:
article * + * { … }
Wow man. Wow.
Hey,
Interesting article. Just trying this out in a project which has Eric Meyer’s reset styles at the top. It seems, that due to the owls low selector specificity that the reset’s styles are being applied rather than the owl. Is there a way to keep using the reset and then the owl?
Thanks.
good article for learning web design , by chance I was looking for knowledge on this , so this really helped me ,, thank you. Harga Sepeda Pacifik
That’s so awesome! How is it possible that I didn’t come across this technique before!
It’s a long time ago that I’ve been this excited about a piece of CSS.