global
In general it's best to build up complex layouts with small components (rather than using inheritance), but not all styles should be strictly component based.
:root {
/* Now almost all elements display a sans-serif font */
font-family: sans-serif;
}
* {
/* Now literally all elements display a sans-serif font */
font-family: sans-serif;
}
Element selectors are more specific, as they only target the elements they name, but they are still "global" because they can reach those elements wherever they are situated.
p {
/* Wherever you put a paragraph it'll be sans-serif */
font-family: sans-serif;
}
These element selectors help build up a comprehensive design system which could be produced by static site generators or WYSIWYG editors.
utility classes
While not needed for simpler sites these can be useful at times. Take for example a site like this:
h2 {
font-size: 2.25rem;
}
h3 {
font-size: 1.75rem;
}
.sidebar h2 {
font-size: 1.75rem;
}
We don't want to make nonsense of the document structure by switching the
sidebar <h2>
to an <h3>
, so we instead add a more specific selector. We've
solved the problem for this specific element, in a specific context, but we may
in the future prefer to be able locally decrease the font-size on other
elements:
/* Backslash to escape the colon */
.font-size:\biggish {
font-size: 1.75rem;
}
Use these with moderation however as it's easy to add too many and bloat the page size (with unused rules) and make the html complex and ugly with loads of classes (such as you see with utility class libraries like tailwind). You don't really want to be simply writing your styles into the html directly.
We can make our new custom properties globally available by attaching them to the root element as variables instead:
:root {
--font-size-base: 1rem;
--font-size-biggish: 1.75rem;
--font-size-big: 2.25rem;
}
/* elements */
h3 {
font-size: var(--font-size-biggish);
}
h2 {
font-size: var(--font-size-big);
}
/* utilities */
.font-size\:base {
font-size: var(--font-size-base) !important;
}
.font-size\:biggish {
font-size: var(--font-size-biggish) !important;
}
.font-size\:big {
font-size: var(--font-size-big) !important;
}
Each class has !important
to max out it's specificity. Utility classes are
only for final adjustments and should not be able to be overridden.
One approach to avoiding utility class bloat is keeping a helpers.css
file in
your repo, but not ever sending it to the client. You can store all your
favorite utility classes inside it and if you find yourself trying to use one
and it not working simply copy it from helpers.css
to your live css file for
usage!