CSS reset exploration #2333
zarahzachz
announced in
RFCs
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Adding a CSS reset
Created: January 12, 2023 1:50 PM
What’s a reset?
Each browser has what’s called user-agent styles that apply CSS to HTML used in a web application, and these user-agent styles can vary wildly from browser to browser. That’s why the concept of a CSS reset came about.
A CSS reset is a type of stylesheet that standardizes user-agent styles across all browsers. There are two types of resets:
body
)Full resets
Full resets are kind of a nuclear option; they strip away any user-agent styles, leaving you with what can best be described as a big ol’ blob of text. It’s kind of like applying primer to a wall before you paint. This can be a great approach, especially if you’re starting from scratch, as it’s the fastest way to guarantee user-agent styles don’t interfere with your work. However, it can also result in unnecessary code as many of the reset styles will ultimately need to be redefined later on.
To better illustrate the pros and cons of that last bit, visualize the full reset as a stylesheet that exists in its own file that’s stripped away all inherent styles from your markup. One of these rules removes margins from paragraph tags. To improve legibility of your paragraphs, you decide to add margin to the paragraph tags in another stylesheet. You now have two rules around paragraph margins - one overwriting the other, resulting in unnecessary code.
Normalizing
The normalize approach requires more knowledge and effort up front to be effective. You have to have knowledge of all browser user-agent styles, and you have to make decisions on how these elements are meant to be styled. As a result, it’s more time intensive but results in leaner code.
Because we work in a fairly mature design system, it makes the most sense to pursue the normalize approach. All we’d need to do is audit what styles we already use in our system on various HTML elements and move them into their own “reset stylesheet” to better work with the cascade (aka, they can more easily be overwritten later on, if need be).
Why does our design system need a reset?
As implied above, a reset standardizes how HTML tags appear across all supported browsers. This in itself makes it a lot easier to develop against as it reduces the need for excessive CSS to block certain user-agent styles and assists with QA as there’s no risk of user-agent styles interfering with the UI.
There are also slight accessibility considerations that can be made via a CSS reset in terms of limiting motion for those who’ve turned this preference off:
Currently, we have to redeclare set styles for each UI component we build. E.g.,
box-sizing: border-box
appears in 13 different components (in Core) and could easily have been written once as*, *::before, *::after { box-sizing: border-box; }
.It should also be noted that because the design system doesn’t offer a reset, the decisions around what needs reset and how is left to individual teams to figure out. There’s a risk that these reset decisions could be incompatible with each other as well as with the design system itself.
Consuming apps and their resets
Auditing what appear to be resets in apps we test releases against:
body
layoutp[role=”button”]
(wut???) andselect::-ms-expand
)body
box-sizing
resetsfigure
anda
*
- could be an issue?body
box-sizing
resetsbody
code
resetfont-family
body
box-sizing
stuffbody
Elements needed to be reset
Modern browsers have gotten better about their user-agent styles, but there are still issues. I've listed common problem child tags below, but we may discover additional elements during a design system audit.
html
body
ol
,ul
,menu
withrole="list"
img
,picture
,svg
)button
a
table
Implementing a reset
If the data gathered from consuming teams is accurate, implementing a CSS reset may take time to roll out in a way that’s not intrusive to our customers. However, there may be ways to mitigate any negative impacts.
Create a CSS reset and import it at the top of our SCSS manifest
This one’s pretty simple; we audit out design system styles, pull out any resetty stuff and chuck it into its own file for ease of maintenance. We then import this file at the top of our application or SCSS manifest so the cascade to do its job (overwrite what’s meant to be overwritten).
This stylesheet target HTML elements and include no custom classes. It’s just meant to obliterate user-agent styles.
Downsides of this approach is we may target an HTML element used by a consuming app in an unexpected way [sad trombone].
Apply reset styles within
.ds-base
Design system documentation advises teams to apply
.ds-base
to thebody
tag of their application to receive correct type treatments. We could nest the bulk of our resets within this class, scoping most changes to it. (The only styles not able to be scoped would be those applied to thehtml
tag itself.)The downside here is that I’m not entirely sure if all teams are using
.ds-base
in their projects. The language in our guidance makes its use seem optional. There’s also a question of whether these reset styles would also need to be included in the.ds-base--inverse
class, and if nesting resets within two different selectors could unnecessarily bloat the CSS of the design system or cause collisions for teams using both classes down the road.Create a separate reset stylesheet for teams to embed
I’m considering this the “opt-in” approach. Basically, we audit the resetty styles in our component library and create a separate stylesheet based on what we find and use that internally. We also allow teams to use this stylesheet in their build if they want. So instead of bundling all our CSS in one file, teams can import either/both the reset and design system styles.
The biggest downside for this option is that we’d be removing the resetty styles from our UI library, so teams would have to have some sort of reset solution to get the proper design system.
Use
:where()
selectorThe
:where()
selector (supported in all modern browsers) can be used to target HTML elements without increasing their specificity. This could be used in conjuncture with any of the solutions suggested and would allow teams to more easily overwrite what we’ve done if they prefer their reset solution instead.Other gotchas
font-size
was being set. Didn’t see anything being set on:root
(good thing as it would allow us to move forward with converting ourpx
torem
) but did find many teams were using their own custompx
font sizes (and onelarger
)My thoughts
I recommend we…
:where()
when possible. This ensures users get all the design system styles they need in one place and helps us keep our styles organized (placing them in their own file hopefully means there’s low risk of them being accidentally tampered with or deleted)Beta Was this translation helpful? Give feedback.
All reactions