If you know your basic CSS selectors `.stack > * + *` is very easy to understand. I didn't know `* - *` was sometimes referred to as "lobotomized owl selector" but it doesn't matter, `>`, `*` and `+` are all basic selectors that everyone working with CSS should know from the top of their head. None of these are "clever". If you can't read `.stack > * + *`, you don't know CSS selectors. I'd even argue if you don't use mostly `>` instead of ` ` (space selector) your stylesheets are probably unmaintainable.
CSS hacks were a shit show 10 years ago because of browser compatibility, but the thing presented here is not a hack, it's just a useful rule.
I'm not worried.
> The spec is already huge, the selectors are hard to read and google, the interplay between various features is devilishly complex.
Actually things are getting less complex due the fact we don't need to use all of the hacks, work-arounds and polyfills that were once just what pretty much every web developer did not that long ago. And of course, the original sin of the misuse of HTML tables for layout.
Sure, it wasn't fun to deal with new specs coming out while trying to maintain existing code and attempting to understand when (or if) we can use the new stuff. Sometimes is was like trying to fly a plane while the plane is being retrofitted with new features.
The irony: many of the techniques described in the article is how we should have been doing things for along time. Hayden's article [1], which is the basis for this, was published nearly 10 years ago—these concepts aren't new.
[1]: https://alistapart.com/article/axiomatic-css-and-lobotomized...
Hardly a sin - there were no alternatives at the time (1996 - 1998) if you wanted a tabular or grid layout.
This isn't to say those hacks were good, mind you - just that their existence was never really a problem insofar as ability to understand them if you dealt with it once.
Having said that, I also knew what it did immediately upon reading it, and I am not a CSS expert. One you know a little bit about selectors, then you should be able to decode this one rather easily.
I still can’t remember how to horizontally and vertically center an element but CGPT sure can.
Many of the newer CSS features prevent you using JavaScript to achieve the same thing, which is better as it results in better performance and easier to understand code.
I would rather have newer standardised selectors than see the same pattern re-implemented with JS differently in every codebase.
Because the syntax looks somewhat like the function notation in math, and a variation of it is also present in many programming languages, often functional, but also Java since version 8. It's quite widespread and not very bizarre / specific to JS.
You'd have mentioned tagged templates [1], I'd have to bow.
[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
And let's face it… to understand the example code you only need understand what > + * do in CSS
Using intrinsic sizing, and the sorts of approaches Andy Bell suggests reduces the volume of CSS enormously and can often get rid of media queries and huge numbers of selectors that get repeated across viewport sizes
I'd really encourage you to watch this talk by Andy https://www.youtube.com/watch?v=5uhIiI9Ld5M
I had the same thought with Regex before learning it. Now I can read it like css selectors, and you'll notice that the complex patterns are that way because they have to cover dynamic situations (using ranges, lookbehind/lookahead, etc).
/* lobotomized owl typography*/These various CSS states would be much better expressed as named properties of React components. That way there would be explicit branches instead of allowing the CSS selector engine to do some implicit insanity.
.stack > * + * {
margin-block-start: 1.5rem;
}
I got it immediately because I think I've been doing something similar for a while. I identified the problem it solves. I understand that if you haven't encountered the situation, it's probably hard to decipher.It reads like: apply a top margin to all direct children that are not the first one.
I write it like this:
.stack > :not(:first-child) {
margin-top: 1.5rem;
}
I probably should start using -block-start. I'll keep my selector though I think.I didn't know about the default value parameter of --var, I'll probably use it too.
So do I, I am somehow wired to think "* is going to be very bad for performance because now the rendering engine will need to apply this bunch of rules to any and every element on earth, which might not be only overkill, but which also might have undesirable side effect."
It might not really apply here but the feeling is present.
margin-block-* and margin-inline-* (versus margin-{top,right,bottom,left}) are more generic and take into account the writing-mode, direction, and text-orientation.
https://developer.mozilla.org/en-US/docs/Web/CSS/margin-inli...
Notably, for instance, if you want to support both rtl and ltr languages, margin-inline-start (instead of margin-left) will behave correctly and put the margin at the correct side.
If you ask me, it's a step towards specifying/conveying the intent and not hard-coding the look.
I think I'd probably opt to buy into flexbox/grids and gap for greenfields projects, but I do appreciate the notion of flow axioms and styling the space between adjacent items.
*, *::before, *::after{
box-sizing: border-box;
overflow-wrap: break-word;
}Firstly, it’s too general. Most boxes don’t care which sizing model is being applied. I have found that I want explicit control more often. To be fair, I learned web development when I had no choice but to work with both models so I don’t find the switching much of a burden.
Second, I’ve seen * { box-sizing: border-box; } cause whole areas of the screen to disappear due to a bug in Chrome. This was years ago, so those bugs have probably been fixed, but it was such a significant problem to the layout and caused by such a generally applied rule, that it’s put me off.
I learned CSS with the W3C / standard box model, in a time where we had to deal with the buggy IE behavior which was essentially box-sizing: border-box. Now, we have the choice of specifying which box model to use and is seems many people prefer box-sizing: border-box. I'm definitely used to the standard/default one more but odds are someone overridden this.
I don't know which one is better but now we have two existing box models, and depending on the project you work on, the default one depends on what was decided when starting it. It's weird, before it was depending on the browser in use, not the project :-)
I'm not sure how this interacts with libraries / components you import that might not expect such a global setting. I guess you have to be very defensive about this when writing a component. And it seems the expectation is that the component writer should be defensive rather than the website / app builder be careful not to break stuff with global rules. Which is also weird to me.
The spirit of the cascading styles was that you could style and customize everything and that stuff you import would adapt to your styling, but we are rejecting this idea by going out of our ways fool-proofing everything and making nothing customizable. I understand why (it's hard to support everything and ensure no breakage), but this still feels backwards to me.
With all the recent criticism of tailwind, css-in-js, and other bloated frameworks I truly feel like 90% of projects could get away with a handful of sensible global styles or "classless css" and then aggressive use of components with scoped styles. You hardly ever need anything else
[1]: https://alistapart.com/article/axiomatic-css-and-lobotomized...
...but that's exactly how a sound design system SHOULD work. Structural components (containers etc) SHOULD be in complete control of child distribution. I simply cannot imagine what a nightmare having to manage margin at an atomic component level for everything would be instead of just spelling out a few container components for them all to live in.
Furthermore the resistance to using the two display types that utilise the gap property (flex + grid) is absolutely bizarre. No sane person would avoid these tools as web dev without them is messy and utterly maddening, so this resistance makes no sense at all.
> The author's arguments against gap
I don't think it's a argument against gap. It's that this technique is advantageous in some situations. It is stated later on that grid is his choice for bespoke layouts.
> what a nightmare having to manage margin at an atomic component level for everything would be instead of just spelling out a few container components
This is the essence of the technique. Specifying `* + *` allows controlling the layout of adjacent elements, rather than an atomic element. I think this would all make more sense after reading some of the precedent material: https://alistapart.com/article/axiomatic-css-and-lobotomized.... (It's actually pretty succinct, so rehashing it here wouldn't add anything.)
border box, flex, the trick to make a square with ::before and content/padding 100%
By no means am I an expert, but I thoroughly enjoy writing CSS using techniques they teach in the book. Somehow, it helps me to think of CSS as a constraint programming system. Combinators are that --- layout constraint directives.
Architecturally, I really like the choice of pulling apart CSS in terms of structural definitions (Stack, Box, Switcher etc.), style definitions (applied to leaf nodes as far as possible), and global rules, ratios, and units (e.g. modular scale).
I think the system composes beautifully and lets me do a lot with a very small set of core definitions.
My personal site uses those techniques: https://www.evalapply.org/static/css/style.css
edit: formatting
We were begging for these features for years and it was a nightmare waiting for enough browser support.
It helps avoid bleeding issues of space which used to require :last-child / :first-child / :only-child overrides.
When I was younger I also had a phase where I liked to do things like these because I could. Nowadays I do things in a way that doesn't waste my own (or other people's) time by being too clever
A person which values their sanity would not write this in CSS.
@tailwind base;
@tailwind components;
@tailwind utilities; :)