I found the linked article "Axiomatic CSS and Lobotomized Owls" to be a decent read. I'm surprised that it hasn't been highly upvoted in the past despite having many submissions to HN.
While "Axiomatic CSS" per se has (unfortunately) not quite (yet?) gone mainstream, its origins -- see https://every-layout.dev -- are a profoundly excellent resource, and have been highly influential.
I was trying to figure out what font they are using and when I was inspecting the page I found the comment below. I have nothing in particular to say about it. I just thought it was interesting.
<!--
...
s, . .s
ss, . .. .ss
'SsSs, .. . .sSsS'
sSs'sSs, . . .sSs'sSs
sSs 'sSs, ... .sSs' sSs
sS, 'sSs, .sSs' .Ss
'Ss 'sSs, .sSs' sS'
... sSs ' .sSs' sSs ...
. sSs .sSs' .., sSs .
. .. sS, .sSs' . 'sSs, .Ss . ..
.. . 'Ss .Ss' . 'sSs. '' .. .
. . sSs ' . 'sSs, . .
... .sS.'sSs . .. 'sSs, ...
.sSs' sS, ..... .Ss 'sSs,
.sSs' 'Ss . sS' 'sSs,
.sSs' sSs . sSs 'sSs,
.sSs'____________________________ sSs ______________'sSs,
.sSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS'.Ss SSSSSSSSSSSSSSSSSSSSSs,
... sS'
sSs sSs
sSs sSs
sS, .Ss
'Ss sS'
sSs sSs
sSsSs
sSs
s
YOU ARE YOUR OWN GOD.
YOU HAVE THE POWER TO CHANGE THE WORLD.
MAKE THE MOST OF IT.
-->
Pretty sure that is from the church of satan. Which is not about worshiping satan but more humanist / atheist / there is no god but you should still be a force for good.
It's just that their imagery is intentionally quite jarring to christians.
To quote the satanists. It is not them who believe in Satan, its the christians who believe in Satan.
As a European, I find it quite amusing that religion is so central to american culture, that they even figured out a way to make a christian version of atheism.
As a fellow European, I feel we have nothing to be amused about. What the church thinks still has excessive weight in lawmaking and people's opinions. Publicly funded schools have "religion" classes where the local mainstream christianity variant is the main content. And the tax authority is still tasked with collecting the "church tax".
As former resident of several European countries, I find your statement, while not entirely incorrect, a bit too "blanketing".
All this may be quite dependent on where you live (the mention of the "church tax" makes me suppose Germany, as they have a Kirchensteuer, but I'm sure other countries must have a similar tax). In any case, there are European countries without church tax, beyond normal taxes that could be used for preservation of historical sites, religious or otherwise (which I agree may be somewhat biased in what religious sites can pretend to be considered historical).
Similarly, many countries do not have "religion" classes in "publicly funded schools", especially in countries that are (supposedly or admittedly) laic. That being said, there's also often a bias there as a lot of holidays are tied to religion and Christianity in particular, and it'd be quite common to explain in class the origin and nature of these holidays. I'd hardly think it counts as "religion" class, though, but that'd depend on what the teachers do.
In Germany, I was pleasantly surprised that some parties up for election have (regionally) expressed the will to abolish relgion-based studies in public schools. It makes me a bit hopeful, especially since I recently got the impression that young people are skewing more religious again. I have also seen some proposals to abolish the laws currently prohibiting singing and dancing during certain religious holidays.
I think in Germany this is really crying out of boredom. If you want to, you don't have to come in contact with any of it. It was still relevant 30-40 years ago, but not today. Not in any relevant capacity.
Other european countries are more laical or secular, but that is pretty much just flavor today.
Some eastern countries are more involved, but if you propose the church having relevant influence in central or western Europe, you really slept the last two decades.
How so? Religion is still central in many countries in Europe, eg Croatia, Poland, etc. It's even getting stronger as the populace is leaning more to the right every day. Plenty of religious people in the media here raving against covid vaccines etc.
The problem is that Europe is split up into dozens of countries with very somewhat different values and cultures, so whenever you say "In Europe X happens", then you can always invoke some version of your argument.
Europe is France, Netherlands, Albania, Moldova. All of these are very different in various statistics.
To some degree yes, but mainstream US is still far more culturally uniform from state to state than Europe's countries are. In Europe most of countries are nation-based and as such encapsulate also all the possible differences in ethnicities, languages, culture, religion and history to a much higher degree. Imagine each race/denomination/ethical group in US having their own independent state with their own laws and ways of life, and you get something like Europe.
But there is still a common language in the us.
And national TV-networks with lots of viewers in both those states.
Neither of those are true for Europe.
I would argue that it is fair to say that the US is more homogeneous than Europe, especially if you are talking about the entire Europe, and not just the EU.
I have never been to Croatia or Poland, but of course you are right in that there are European countries where religion has a more central role than in other European countries.
But, how common is it really in Croatia or Poland to use christian terms such as "satanist" when you want to say that you are an atheist?
There was an important piece left out of the description of the Church of Satan: it is typically used as a device to test civil liberties and separation of church and state.
If, say, a courthouse has a statue of a religious theme, then by the law of the land, the courthouse must be willing to erect a statue for any religion. Like, say, a statue of Baphomet. Or they can remove _all_ of the religious iconography. That demographics are mostly Christian and so such things are overtly offensive makes it more effective.
So, atheists or agnostics or even people of more orthodox religious persuasion are using the Church of Satan as a vehicle of representation for a strong stance on the separation of church and state.
>It's just that their imagery is intentionally quite jarring to christians. To quote the satanists. It is not them who believe in Satan, its the christians who believe in Satan.
Seems anti-social, especially when injected into a non-religious context like a site about web design.
That site is black on white¹, and has no other colors, images, fancy borders, nor any other obvious “design”—and yet it is remarkably pleasant to look at, even beautiful. The site sells the authors’ ideas; they obviously know something. (Plus no doorslams, cookie warnings, or other annoyances. And an RSS feed.)
† The only problem is that the atrocious #fafafa on #050505 is made a whole lot worse because there aren't a bunch of even worse things distracting you from it.
Okay, I'll bite. Why is #050505 on #FAFAFA (not the reverse, as you stated) "atrocious"? Are we playing the "anything less than #000000 on #FFFFFF is grey text on a grey background and entirely unreadable" card?
I don't understand their complaint either. Some people have a hard time with absolute black on absolute white (and/or vice versa) so easing up a little can be helpful. It's a small difference, 19:52:1 vs. 21:1 contrast ratio. I've seen advice to avoid exceeding 18:1 in large areas, maybe #111 on #f9f9f9.
We tend to focus only on the accessibility issues caused by low contrast, but very high contrast also makes reading more difficult, especially for people with dyslexia -- and it's also more likely to cause eye strain if it's a full-length article.
At any rate, "it's okay for text not to be pure black and backgrounds not to be pure white" has become my tiny hill to die on.
It's basically a measure of perceived brightness. The actual formula involves calculating the relative luminance of the background and foreground colors, where luminance is a value from 0 (darkest) to 1 (lightest), and using the formula
The WebAIM contrast checker web page is one of many. It's nice because the colors have lightness sliders so one can quickly try alternatives then copy the hex values into your CSS.
I like checking with Lea Verou's https://contrast-ratio.com because it can check colors written in many different formats, not just hex. Also, it can do +/- contrast ranges when colors include the alpha channel.
In the Chrome and Firefox DevTools, you often can simply click the color swatch for the `color` property. The pop-up includes the contrast number vs. the background-color for that text and whether or not it meets a Web Content Accessibility Guidelines (WCAG) contrast criteria (Level AA if it's 4.5 or above for regular-sized text, Level AAA if its 7 or above for regular-sized text).
I didn’t really understand why the sibling selector was introduced as a scoped version of the lobotomised owl, as if that was the canonical implementation. The sibling selector has always been underrated.
Just add the class to a parent and all the children will have spaced between, but no spacing around the edges. It’s then easy to add padding to the parent:
This is a bit easier these days with Grid. You can set grid-template-columns: 1fr; and use gap: 20px; to control the spacing which feels much more natural. You can then pad as you like.
edit: realise this is at the end of the article so you probably already know this
This means that it won't work in a builtin browser of a smartphone made 5 years ago.
I think that average quality websites made for public Internet should use only features that have been supported at least for 5 years in major browsers including mobile. And a high quality site must be usable in 10-years old browser.
Yeah I have a variation of this too. stack-y-<size> and stack-h-<size> for horizontal spacing. This combined with Flex makes a lot of layout implementations easy.
And then you can’t nest one container into another, because there is only one “margin” rule and they don’t add up. You start to wrap children into separate containers only to find out that it breaks more and more “nice and simple css tricks” you used before. Eventually you end up with half-broken bootstrap/etc clone that even supports component design if looked at from afar. After few weeks it starts to feel like not using components at all would be much less of a maintenance. Css “tricks” are full of these situational traps.
If you want to keep doing this, it’ll save you a whole lot of heartache if you also wholesale prevent margin collapsing. In fact, some people recommended that as a baseline default (I personally find it great for layout but surprisingly mixed for typography).
If only we had <sizer> (or display:sizer) element that could expand, disappear on wrap and not count as a regular child (sort of like a space in a text node)… But that would be so '90s.
decorative nodes to the DOM doesn’t seem like a good solution
Why? You could add the same constraints to the sizer: min, max, flex shrink/grow, put a line or any other shape in it. It wouldn’t even take a separate “display” mode, just make :row-start, :row-end and :row-wrap pseudoclasses to control collapsibility of regular divs at the sides of a container (or whatever styling you need, anything). Instead they feed us yet another crippled special case with these gaps.
Imagine you charge $69 an hour as a developer. Learning the proper way to think about building resilient CSS layout will save you tens of hours throughout your career by building things the right way from the beginning.
May I know what are the other two? I read Every Layout for the past hour and it's good so I'd like to read something else of similar quality in the future.
Also, how did you come across those books? I just found out about Every Layout in this thread. I'm not a web developer so I don't know if it was advertised in a web dev forum or what.
I think rule-followed-by-exception is clearly superior because it's more flexible and generalizes better to future additions.
Except when it isn't superior. Like when the exception is pages of code below the rule.
Which means that precise (enabling) selectors are more robust since you don't have to worry about future CSS additions (or even whether to look for exceptions).
Which means that in general, general rules don't work very well.
This stems from the incorrect (but popular) idiom of doing a container’s job by invading child properties. One can’t make it non-leaky neither to layout around, nor to a developer. These gaps are ones of the parent, not of a child, and anything else will leak.
> I think gap is where this is all headed in the long term.
gap? Is this new? I've been waiting for years for CSS to finally support something like that. Always thought it was weird that I had to mess with margins (and last-child hacks) to get a proper gap between items in a container.
It's been made more general than just grid (it used to be called grid-gap) and works with flexbox too. I don't know if Safari supports it in flexbox yet and it's a pain to detect with @supports because Safari _does_ support gap but in a different context, but it works fine in Chrome and Firefox.
Edit: just checked, Safari 14.1 added support for using gap with Flexbox.
This reminds of an idea in math that proofs by construction are better than proofs by contradiction. Or making artificial grammars (e.g. PLs) with recursive descent parsers instead of context-sensitive grammars with Turing-complete parsers.
If you can build something step-by-step with a clear hierarchy and easy to trace causes and effects, the result seems to be more convincing/reliable than a process involving a bunch of logical roundabouts. Of course, if that's at all possible for a problem at hand.
Is there a language that compiles to CSS but excludes the decades of cruft that have accumulated in CSS? Something that just exposes a few key primitives and jettisons the rest even if that means it doesn't handle some extreme edge cases?
I assume there's some CSS that doesn't have a use anymore but thinking about layout, we don't need floats for page layout but that was basically a hack, float is still useful for its original purpose.
Basically, the CSS spec isn't full of cruft but there are a lot of CSS practices that are no longer needed.
Was just thinking about this the other day. Once aspect-ratio gets Safari support, that will take away the need for the height:0/padding-bottom: 66% thing, which is one of the last hacky bits of CSS that I use regularly. Container queries will fill another huge hole, but I don't polyfill/do hacky things for that in the meantime.
CSS really does do pretty much everything you need these days.
I think the hard part with this is that because CSS properties are so context-dependent, the compiler would have to somehow figure out a way to translate your simple property into the correct one, without knowing how your HTML is structured.
For example:
.thing { topgap: 10 }
.other { topgap: 10 }
Would have to compile to different things if .thing was in a flexbox and .other was in a grid or a box. Since a lot of HTML is dynamically generated, we don't actually "know" this, and specifying which to use yourself ahead of time defeats the purpose, since you may as well just use the normal CSS properties. This could however work with completely static HTML. Maybe some JavaScript solution could hack on dynamic CSS but I would be sceptical of accessibility and performance in that case.
In the precompiled case, unless all the CSS was outputted using a very limited subset of CSS along with a large "base" CSS file, I don't quite know how it would work.
This is a case where build tools surprisingly shine. Example: if you use Fela (CSS-in-JS atomic style library), but build statically, it has all the context it needs to determine optimal order of rules and which rules are actually in use… but you can pipe the styles wherever you want at build time and eliminate the runtime for anything static.
(I use this on my site. It’s suboptimal for build and could use a mountain of refactor. But the source is up on my GH if anyone’s curious)
What in particular do you consider cruft? The original "standard flow" layout model is still very relevant for document-like pages like Wikipedia even if more advanced layout models have become available. In theory you can do everything with absolute positioning (the only primitive you really need) but it would be completely impractical.
I wonder if people would have the same sentiment if it had been a newly introduced language that the major browsers overnight agreed to all include as alternative to CSS. Now I feel like CSS keeps getting more complicated, but if there was a shiny new thing supported by all browsers, I would probably feel different.
I've been in the process of designing exactly such a language. It's nowhere near ready, but my goal is to create a design tool that can edit this language either using a figma/sketch like GUI or by editing the code directly.
Hmm, I visited the site on my phone and it seemed to be glitching out. A red background with white outlined large lettering blinking on and off so quickly I couldn't decipher the text. Looked like maybe a GA and some xxxxx after it. Viewing from an iPhone X using the iOS 14.7.1 on Firefox.
Anyone else seeing this? Or am I 1) crazy and/or 2) admitting to having some crazy virus on my phone?
Interesting way to think – we use additive color (RGB) on web so why not additive styling?
But in practice while creating interfaces, we're making broad brush strokes, then accommodating exceptions, like :last-child.
Also curious about how browsers prioritize the render stages – does every style get applied sequentially (hence cascading), or do pseudo selectors get applied later during the paint?
> Interesting way to think – we use additive color (RGB) on web so why not additive styling?
Sounds confused. I'm not sure what "additive styling" means, but I'm sure it doesn't mean the same thing as "additive color". "Kids like jelly beans, so why not lima beans?"
The reason we use additive color on the web is that it reflects the display technology, which is a bunch of independent light emitters. The web has nothing to do with it, except that the web is viewed on computers.
Style calculations are typically done before rendering, but as far as I know, there's nothing in the spec that dictates you needing to do anything specific other than comply with the output outlined.
I believe that's exactly the point. You don't set all to 5px and then override using a special rule that says 0px for the last. You exclude the last element from the 5px rule.
There might be other rules, browser, user that should not over the 5px rule
I disagree. If a 5px margin is the general rule, then I would argue it's cleaner to apply it generally, and then apply the 10px margin exceptions in separate rules.
- When special cases are added or removed, the general rule won't have to be adjusted, just code that handles the special cases.
- On the other hand, a single general rule that specifically avoids application to multiple exceptional cases will be pretty long and have multiple :not()s, thus reducing readability and maintainability.
Why burden the general rule with knowledge of its exceptions? To me, doing so is a (small) violation of the principle of separation of concerns.
plus it's called "cascading style sheets". you're going against the current if everything wants to be so specific. This is one of my gripes with styled components.. it makes it easy to forget the power of cascading rules!
For me, forgetting the cascade has nothing to do with it; in my use cases, styled-components is all about:
- eliminating the chance of colliding CSS class names when composing multiple micro-clients together
- simplifying builds, especially cascading builds (library + client). It's nice when styles are covered entirely by the JS build (no separate CSS/SCSS input or output files or separate build pipelines).
Yes, there are other complexities/problems that styled-components adds (including the likelihood that devs will forget about the cascade)... so I wouldn't recommend it for every case. But it does have its place.
As I understand it it's not about the value but that first a rule is applied to all elements and then a new rule overwrites the previous rule for some element, the last one in that example.
To quote the article referenced in the article: "I call this technique disabling selector since the li:last-child selector disables the previous selector's rule."
So the 10px margin for the last element is a disabling selector.
Another bad thing (in my opinion) is "useless" rules. There are at least two kinds of useless rules:
1) rule that does not apply to any element on the page. Such rules only inflate CSS file and waste traffic and CPU cycles to process them
2) rule that is overriden by another rule. Again, it doesn't have any effect on the page and only wastes CPU cycles.
The case 1 happens when styles for all pages are merged into a single file instead of making different bundles for different pages. Both cases happen when using bloated CSS frameworks.
Also, note to BSD: you want enabling feature selection macros on the compiler command line, not your stupid disabling ones. -D_BSD_SOURCE does not mean hide all non-BSD stuff, including POSIX. -ansi means I want a certain language dialect, not that non-ANSI declarations are to disappear from headers.
It might be subjective, but I disagree, for me it would be easier to reason, read and maintain the first way, preferably with scss, so you nest the last child. Maybe it is because that's the pattern I have most faced, though.
And I think definitely avoid li + li. It wouldn't be immediately obvious at all for me if I saw that, what the intention is.
> I think definitely avoid li + li. It wouldn't be immediately obvious at all for me if I saw that, what the intention is.
Nothing unfamiliar is obvious. As with any language, get to know the capabilities of CSS better and it will feel familiar. The article is right that for spacing, the `gap` property on the parent makes more sense but hasn't been around long enough, we need some more older browsers to age out (especially when used with Flexbox).
Yeah, but it wouldn't be just me, point of writing readable code is so that as many developers as fast as possible would understand what is going on. So in this case I think using the pattern that is most commonly used is the best thing to do.
I've done web for more than 7 years and I still immediately wouldn't recognize why someone has used selectors in such manner (li + li). Just obfuscates things IME.
I think CSS is approaching the point where it's equivalent to assembly because it's impossible to keep up and write good CSS. It's no longer easy to do it by hand which is why there is a whole ecosystem of tooling that handles CSS.
Not to mention that CSS is essentially platform-specific due to differences between chrome, safari and firefox.
Some tooling is for managing the complexity caused by complexity of the site/app.
Some tooling is managing the complexity of managing component-centered design (particularly scoping); it's a very positive approach to design but it's not without its problems.
Some tooling is to help developers avoid having to actually learn the CSS language well and/or to force it into JavaScript.
> CSS is essentially platform-specific due to differences between chrome, safari and firefox.
That's an exaggeration. Consistency of implementations between browsers is better than its every been. There are still some vendor-prefixed properties to care about, especially if one is generous in one's support for older browsers, but that's another reason CSS tooling exists, to write only standard CSS and let the tool fill in the older variants.
What this article describes is no different than programming patterns in more traditional languages.
I legitimately can't think of anything that has made it more difficult to write by hand in the last 15 or so years; if anything it's never been easier! Building complex software is...complex, and frameworks and tools in the CSS world are no different than reaching for an MVC framework or ORM.
There's minor quirks between browsers, but it's a far cry from being platform-specific, and a huge improvement on the incompatibilities of yore.
Mirroring this sentiment. CSS is fantastic now and they've put a lot of careful attention into the new specifications. I haven't run into a situation in years where I was unable to lay something out the way I pictured it in my mock ups. We used to have to do a lot of hacking just to get simple things into layout in the mid to late 2000's.
That's true for every language/format used on the front end.
I do a lot of visual work as a designer/developer. If it weren't for the obvious accessibility caveats such as basic page structure, I'd be making at least 20% of the pages I code in straight SVG.
Edit: Maybe not HTML5 I guess... you can make anything inscrutable if you try.
If you're using react or another frontend framework then you really don't need css selectors. Just make plain css classes and dynamically append them to your components. So much simpler.
We do this at my current job and it's honestly the easiest time I've ever had with CSS.
How do you solve the kind of problem the article is describing? How do you have a margin on the bottom of every <Card> except the last one? Is there a loop for cards with a conditional that doesn't add the margin? I think the declarative language solution they offer is better.
The nice thing about this is you have a full programming language at your fingertips. You could do something with every even card, ever prime number card, etc.
The performance difference is negligible. If you add a new card to the list then react is going to add/remove a couple CSS classes. Completely negligible.
Plus you're going to need this approach anyway if you want to do any more advanced logic like maybe you have a list of users and you want to color them based on some status.
With this method you have the above logic all in one place and in one language. After having used traditional CSS with selectors vs this method I really can't go back.
Seems funny to argue for JavaScript's simplicity while using .map() and an anonymous callback function; a good ol' for loop would make it more clear what's happening.
> all in one place and in one language
That seems like the real reason, keeping to one language.
I think following the rule of least power [0], having HTML semantics do what it's good at, CSS what its good at, and JavaScript for the rest is best for robust and performant outcomes.
<Card className={className} />
I only have a little experience with React and that was a while ago, can you not have the Card typed as an Element to use `Card.classList.add(className)`?
> Seems funny to argue for JavaScript's simplicity while using .map() and an anonymous callback function; a good ol' for loop would make it more clear what's happening.
When you're doing a side effect free transform of some data, I find .map far clearer.
A for loop would require .push type noise for that case and so personally I'd find that noisier and harder to skim read.
Tastes vary, of course, but certainly it doesn't seem funny to me at all.
The downside of the enabling rule is that it has high specificity. I often have that issue with links. But if you are really strict about this and never overwrite styles anyway you do not even need to think about specificity.
yes but no .. seems like a weird rule that makes it harder to understand and read. A flow of default, exception, exception is easier to follow. And What if you have odd even, every third etc etc ..
The solution is the same. `:nth-child(3n)` selects every third so you add the :not(:last-of-child) to the end to prevent it from being matched by the rule.
.card:nth-child(3n):not(:last-of-child) {
/* styles for every third card, not the last card */
}
What's less clear to me is why `.card + .card` would be better for applying a style to all but the first card than `.card:not(:first-child)`. I think there are reasons for not using `*:not(:first-child)` and preferring the "lobotomized owl" `* + *` but my hunch is they don't apply when styling classes.
Article: https://alistapart.com/article/axiomatic-css-and-lobotomized...
Prev. submissions: https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...