From my perspective that is not so much a reset/normalize.css but more something like a base.css.
A reset.css is supposed to create a common truth across different browsers. However, this doesn't concern so much with different browser default settings but more with developer preference for specific behaviors, like e.g. the boxing model (which is the often being done in a base.css/scss in addition to a reset.css).
That is not bad, just the wrong term being used. That being said, I like those settings :-)
> Historically, the main goal of a CSS reset has been to ensure consistency between browsers, and to undo all default styles, creating a blank slate. My CSS reset doesn't really do either of these things.
> These days, browsers don't have massive discrepancies when it comes to layout or spacing. By and large, browsers implement the CSS specification faithfully, and things behave as you'd expect. So it isn't as necessary anymore.
> I also don't believe it's necessary to strip away all of the browser defaults. I probably do want <em> tags to set font-style: italic, for example! I can always make different design decisions in the individual project styles, but I see no point in stripping away common-sense defaults.
> My CSS reset may not fit the classical definition of a “CSS reset”, but I'm taking that creative liberty.
This is a pretty clean reset, and the explanations are really nice and thorough! But the person coming out from the left edge of the page scared the crap out of me
Yeah, I found it quite sweet. I usually hate Intercom-style 'conversational' popups, but props to the author - he's made it unique and endearing enough that I would definitely have signed up if I were a front-end dev.
TL;DR: This rule does most of the heavy lifting and is the most novel aspect of this approach:
/\* Remove all the styles of the "User-Agent-Stylesheet", except for the 'display' property */
*:where(:not(iframe, canvas, img, svg, video):not(svg \*)) {
all: unset;
display: revert;
}
It practically wipes out all styling from user agents across the board, so you will never again need to exhaustively override every undesirable user agent style to get an element to look exactly the way you want. The styles you've placed on an element explicitly become (for the most part) the only things that will contribute to its appearance.
I've been prototyping with it at https://app.reflame.dev/ and it honestly feels like a breath of fresh air in terms of productivity.
One thing I've learned to watch out for when using it, is that it also happens to wipe out the default focus state styles of interactive elements like button, anchor, etc (the blue outline in Chrome). This is the reset working as intended, but it's also a show-stopping accessibility issue if not properly addressed in userland by adding some form of visual focus indicator back in. I have a feeling we might discover more gotcha's like this as time goes on, but so far this is the only one I've noticed, and as a result I've been very happy with the tradeoff.
Looks _horrible_ on non-retina (read: most external) monitors with macOS.
Browsers have sane defaults for every OS! Please retain them rather than making me install TamperMonkey just to read your blog.
Things maybe be "addressed," but that doesn't make them right.
> Apple disabled subpixel antialiasing across the operating system
Right, so what is he disabling exactly?
> Chrome and Safari still use subpixel antialiasing by default
Wrong. They do not. Zoom in yourself. There are no colored pixels.
That CSS line basically acts as a `font-weight: -=100` across the document. That's all it does, and that does not belong to a CSS reset. You might as well set the rest of the `font` properties and call it a regular stylesheet.
A friend recently started practicing front-end development and showed me something they put together. Included was a 200+ line CSS 'reset' file. It made up most of their CSS but they weren't able to explain what the different parts of it did or why they were needed. In fact, most of it wasn't applicable (it styled elements that didn't exist) or needed (it defined styles that were always overridden later on). I suggested they remove the file piece by piece to gain a better understanding of CSS.
I don’t think this is good advice. The point of a reset file is to reset everything. You don’t want to add an element later and have that element contain random default styles. Is understand how each line of a dependency works really important?
CSS resets have been contentious as long as they’ve existed, but they’re especially contentious now because they’re mostly superfluous (see the article) and tend to override things in ways that harm usability and accessibility.
If you’re using one now, yeah it’s probably a good idea to understand what it’s actually doing, rule by rule.
Yes, understanding each line is critical. I run a CMS that houses millions legal documents for thousands of organizations. A prior dev put in a reset that took away padding from P tags, so we have all these documents that have been built of the years with no layout difference between a soft return and a hard return. Which means they all have extra P tags between each actual paragraph, and at this point we can't even change our CSS without instigating reformatting of millions of documents. And legal authors do not like that one bit. So it stays because our data is more important than our CSS. But it also annoys.
I pointed this out to them all when I first joined, and they said, "But CSS resets are good ideas."
So yes - please take the time to understand what your CSS does, especially when working with tags that format text, as it can have subtle (and not so subtle) impacts on data created in a UI with unwise CSS reset choices.
I never quite get the reasoning behind changing box-sizing. My gut feeling is that most places that benefit from switching it to border-box were doing the wrong thing anyway, and that content-box really is the way you should be thinking—design the layout in terms of the content where possible, rather than other parts of the layout. To use his own example: `width: 100%`, that specific value is completely superfluous, just remove the line; and if you were talking about stacking things side-by-side, where historically you would have done things like `width: 50%` or `width: 33.3%` and hope the pixels line up well enough and it doesn’t wrap, then you should use flexbox instead.
Certainly there used to be a couple of major exceptions to my feeling that content-box is a better way of thinking, but this is the main one. Now I can only think of one significant exception: that `html, body { height: 100% }` needs border-box on body if you introduce padding or don’t zero margin, and that if you have an element inside the body that constrains the whole page’s width with max-width and also has margin or padding, same situation.
—⁂—
> The WCAG criteria states that line-height should be at least 1.5.
This is being completely misread. The criterion says that no loss of content or functionality must occur if the user overrides line-height and sets it to at least 1.5. It doesn’t say you should be setting it to at least 1.5—or else it would also say you should be setting letter-spacing to at least 0.12em, which would be awful.
—⁂—
On `-webkit-font-smoothing: antialiased`:
Neither screenshot exhibits subpixel antialiasing. I’m guessing (as a non-user of macOS) based on the appearance that `-webkit-font-smoothing: antialiased` might actually be disabling that thing that macOS misnames “font smoothing” which is actually glyph dilation (about which I have written here on HN before). If it’s doing that, then hey, that could actually be useful for adjusting font grades.
> MacOS is the only operating system to use subpixel-antialiasing, and so this rule has no effect on Windows, Linux, or mobile devices.
This is not true: on Windows, ClearType (enabled by default, I think? but certainly not always) does subpixel antialiasing, and you can definitely choose to go with subpixel antialiasing under Linux. It’s just that those platforms don’t provide a CSS knob to twiddle, perhaps because they saw how much it was abused on macOS.
Why apply it to paragraphs and headings alone? Would it not be better to just apply it to the root element? Let it cascade, it’s an inherited property. That way also you don’t get anomalous behaviour when you write lists without wrapping each item’s contents in <p>.
I ran into so many issues with content-box a decade back I never thought about it again and always defaulted to border-box.
I think it's absurd that I can set a div to a specific width (100px, 200px, whatever) and the padding or border will make the div larger than that width.
It makes it so hard to think about designing a page when you have to continuously add together padding, margin, and border with the width to get the actual width.
You're right about flexbox and grid solving most of these issues -- and responsive design has pretty much done away with using exact pixel widths for anything, but I still run into some cases (especially around creating grid layouts that automatically reflow) where CSS columns and floats are the best approach (not often, but it still happens...) and then you need to rely on the width being the actual width, you know?
I’ll try framing and explaining it a slightly different way:
It’s about the difference between layout and content concerns.
Margin and padding should generally be layout concerns.
Explicitly-set width and height should generally be content concerns. This means it should exclude margin and padding, so content-box is the most appropriate model.
Before flexbox came along, it was necessary to use width and height for layout concerns quite extensively, which is why people started recommending border-box. But now, the root elements are pretty much the only places that may (or should) use width and height for layout concerns. So I say specify border-box for them if you need, but leave it at content-box everywhere else.
Just like gap (flex/grid/column) isn’t part of width or height—it’s a layout rather than content concern.
I’m saying that you’re thinking the wrong way: don’t try to squeeze your content into the layout, but define your content first of all and let the layout exist around it.
Why should width and height be content concerns? Typically the measured width and height are the most important pieces of information needed by a layout engine.
Actually I’d say that height is seldom a content concern in horizontal writing modes; it’s width that’s the important one for content: think the width of a table column, you will choose the width based on the content (and not padding or gap between columns, which is a layout concern).
> I think it's absurd that I can set a div to a specific width (100px, 200px, whatever) and the padding or border will make the div larger than that width.
That’s not what’s happening.
Imagine you have a physical box. The contents are 10cm wide. There is padding of 2cm on each side. And the space around the box is 3cm. How wide is the box? It’s not 10cm; it’s 14cm.
When you say:
> I can set a div to a specific width
…you aren’t setting the width of the div, you are setting the width of its contents. That’s why the property value is box-sizing: content-box – because you are setting the width of the content.
If you’re setting the width of the content when you mean to set the width of the box, then no wonder it’s not doing what you want.
I don’t think this is a great analogy. Margin is the space around a physical box. The border is the edge of the box, like a piece of wood. The padding is the space inside the box separating the content from the box itself. And then the content is its own thing.
How big is the box? I think most would measure from border to border. I think it’s easier to think of CSS in that way.
> How big is the box? I think most would measure from border to border.
Again, you’re not understanding what’s happening here. You’re right – the measurement of the box is from border to border. That’s completely correct! But the width you are setting is the width of the content, not the width of the box. Pointing at the width of the box and saying that it’s not the width you set is looking at it completely wrong. You didn’t set the width of the box. You set the width of the content.
… and there are plenty of types of real-world containers that are defined by what they can contain, by their internal rather than external dimensions. Especially capacity in litres.
Take bicycle tyres. The most popular naming scheme in Australia approximates the external diameter in inches, which is objectively problematic. The technically vastly superior naming scheme endorsed by ISO measures the rim diameter, which is the far more important measurement for determining compatibility, in millimetres. As it stands, each inch measurement corresponds to at least two incompatible sizes, depending on the tyre’s width: for example, 16″ tyres are normally 305mm (e.g. 16×2¼″), but there’s also the rarer 349mm (e.g. 16×1⅜″) commonly used in recumbents.
As much as it has any explanation (“Generally, it is considered preferable to use the border-box model for all boxes. It makes calculating/anticipating box dimensions easier.” is about all it has, really), that’s the same old explanation that I have already offered a rebuttal to. I hold that border-box encourages layout thinking rather than content thinking, and that that’s normally a bad thing. Most of the time, border-box is making doing the wrong thing easier.
This reset does too much IMHO, the rest of the CSS will become dependent on these styles. That said, I'm guilty of this myself. Here's mine: http://0x0.st/-7gE.css
To me, having reset styles feels like using unwanted globals in a programming language. Styles on html and body are ok though, as there's only 1 of them on a page.
> The main element has height: 100%, but the element doesn't grow at all!
> This doesn't work because in Flow layout... the width of an element is calculated based on its parent, but the height of an element is calculated based on its children.
Well, more specifically, `height: 100%` isn't expanding as it's already the maximum height of its parent, right? All he's done is increase the parent height.
Nice to know the history of css resets and that you don’t need them anymore for their original purpose but this is a nice short starting point. Not to blindly copy in but gives some options to consider.
A reset.css is supposed to create a common truth across different browsers. However, this doesn't concern so much with different browser default settings but more with developer preference for specific behaviors, like e.g. the boxing model (which is the often being done in a base.css/scss in addition to a reset.css).
That is not bad, just the wrong term being used. That being said, I like those settings :-)