Some Additional, Advanced CSS
Our HTML/CSS focus up to this point has been relatively broad, to start with the basics. Here we want to sand down some of the rough edges, and introduce you to some specific, advanced techniques you can use to refine and enliven your work—still with just CSS, no JavaScript (yet)!
It is vain to do with more what can be done with less.
A good pattern to follow in web (and all) development is to use each technology
Let’s look at some examples.
Overflows and Scrolling
An overflow in CSS happens when there is too much content to fit in a container—usually because you have manually constrained its block-size or inline-size. (By default, the browser will try to show you everything!)
overflow– MDN- Overflowing Content – MDN
There are going to be a lot of MDNs, here.
But we can use this behavior
Importantly, this creates a new position (namely, position: sticky)—and some other properties—will now use the overflow container as their reference/origin:
- The stacking context – MDN
Always confusing; think of these asframes orgroups in Figma.
text-overflow / -webkit-line-clamp
You can also text-overflow (for a single line) or -webkit-line-clamp (for multiple lines) properties—which will add an ellipsis … where the text overflows. Only do this when the full text is available on a subsequent page:
text-overflow– MDN
For single lines…-webkit-line-clamp– MDN
And multiple lines!
-webkit stuff is hokey, but still how it is done! Browsers are weird.
Precise Text Positioning
You have probably noticed that HTML renders a lot of extra space around text elements, called the
- Font Metrics, Line-Height and Vertical-Align
A deep-dive on type positioning. - Vertical Spacing and Line-Height in Design Systems – Google Fonts
It’s all very complicated.
It is based on the font-family, the font-size, and the line-height, which basically means it is different all the time—and crucially, often different from Adobe/Figma to HTML. This makes it difficult to position type precisely—especially at large, expressive sizes like your headings! It’s always annoying, and you’ll often be adding/subtracting your spacing (margin or padding) to account for it, if you want to line everything up
Let’s avoid it. We can use pseudo-elements, ::after / ::before—which you may remember are entirely created by CSS, not in your HTML—to negate this vertical space with a negative margin. By doing this on the pseudo-elements, we can still position the parent element normally, otherwise:
margin-inline-start and margin-inline-end, though usually this adjustment is much more minor (to the point of ignoring).
text-box is coming
Figma was actually text-box-trim and text-box-edge properties! These will negate all this pseudo-element, negative-margin dance with one line of code.
text-box- MDNtext-box-trim- web.dev
So… much… easier!
Text Ragging (Kinda)
We’ve gone on-and-on about how you can’t treat the web like print—always perfectly ragging your text for nice, smooth blocks. In modern (responsive) web design we don’t always know what our text will be, nor where it will wrap!
But we can do a handful of things to make for hyphens / ­, <wbr>, white-space, <nobr> and , and text-wrap to
hyphens / ­
The hyphens property allows long, multi-syllable words to be hyphenated when they wrap across multiple lines. This can be done automatically by the browser, or by manually inserting ­ (for
hyphens- MDN
This depends on the browser andlang, unless you manually add­.
<html lang="en"> is needed—as the auto property works from each browser’s different, internal (and usually, only English) dictionary—so this all has somewhat limited utility/reliability/consistency.
<wbr>
Somewhat related/similar to ­, the <wbr> is a <br> ! You can use these to manually control where single long word will wrap,
wbr – MDN
These are often needed with slashes/URLs.
white-space: nowrap; / <nobr> /
But much more often, you’ll want to keep certain words
white-space– MDN
Prevents text from wrapping.nobr– MDN
This istechnically deprecated. But one of your instructors is a “stan.”
You can keep multiple words (or whole phrases) together with white-space: nowrap;. Historically, the <nobr> tag applied this—keeping in mind that like <em> or <strong>the default behavior is cleared by most resets (ours included)—so likewise you have to restore the property in your own CSS.
You can also use a manual entity between words:
  with text-wrap: balance;
After many, many years of patient, typographic waiting (and some JS shenanigans) we now have widespread (and mostly even) browser support for “balancing” uneven line lengths with text-wrap: balance; :
text-wrap – MDN
Don’t overuse/abuse this in running text, though!
pretty, but Safari Hanging Punctuation (Sorta)
Ideally we could set punctuation
::beforeand::after– CSS Tricks
Another greatCSS Tricks article.
::before and ::after.
When in doubt,
But also, as Bringhurst says, “read the text before designing it.” Always put yourself in the mind of your reader!
Filters!
CSS can apply visual effects on elements—adjusting their graphical display filter property:
filter– MDN
Back to MDN.
These have corresponding backdrop-filter values—which apply the effect to the page opacity (or semi-transparent color) or a mix-blend-mode for interesting Photoshop/Figma-like layer-blending effects:
backdrop-filter– MDNmix-blend-mode– MDN
Often used together.
Transforms!
Beyond our standard sizing and layout afforded by CSS, you can also
scale()/scaleX()/scaleY()/scaleZ()/scale3d()- Change the displayed size of the element—as if it is an image.
skew()/skewX()/skewY()- Tilt an element to the left or right, like turning a rectangle into a parallelogram.
translate()/translateX()/translateY()/translate3d()- Move an element left/right and up/down, and also in three-dimensional space.
rotate()/rotate3d()- Rotate the element.
perspective()- Doesn’t affect the element itself, but sets the distance between the user and the
three-dimensional plane.
transform – MDN
These are fun—but should
The units for these are all a bit different; MDN is your friend here, as usual. You can apply single or multiple transforms, which are written
.rotated {
transform: rotate(-5deg);
}
.rotated-and-scaled {
transform: rotate(-5deg) scale(120%);
}
Keep in mind that these transformations are applied overflow above, transform also creates a new
You shouldn’t use transform for layout—as in, don’t use translate when margin, padding, flex, or grid can achieve your layout. This is
Use transform only for what other properties can’t accomplish!
Transitions!
CSS transitions allow us to move nicely between CSS property values.
- Using CSS Transitions – MDN
Every state change is better with some easing.
Instead of having a property take effect duration), and with a specific acceleration (timing-function), or a delay. Motion can quickly get very complex!
You’ll often see a transition in shorthand:
.some-cool-transition {
transition: all 2s 1s linear;
}
.some-cool-transition {
transition-delay: 1s;
transition-duration: 2s;
transition-property: all;
transition-timing-function: linear;
}
You can also control how different properties of an element transition independently, with a
.some-cool-transition {
transition: background-color 2s linear, transform 1s ease-in-out;
}
.some-cool-transition {
transition-duration: 2s, 1s;
transition-property: background-color, transform;
transition-timing-function: linear, ease-in-out;
}
Sometimes the shorthand here is easier than discrete properties, where you have to maintain the same order across all of them. It’s all the same to the computer!
Often, CSS transitions will be used
Nearly all CSS properties can be transitioned—but keep in mind that changes that cause a color, opacity, and transform for the smoothest performance.
And Animations!
Sometimes, transitioning a property from one value to another isn’t enough—you may need more complicated (or repeating) motion behavior. CSS animation allows precise state sequencing with @keyframes (akin to…
- Using CSS Animations – MDN
Some of you already got into these!
To create a keyframe animation, we define an element’s initial state in CSS—then an animation property, which includes timing and behavior, as well as an animation name (something that you make up). Again, you’ll often see these in shorthand:
section {
animation: blinking 3s infinite ease-in-out;
}
section {
animation-duration: 3s;
animation-iteration-count: infinite;
animation-name: blinking;
animation-timing-function: ease-in-out;
}
Importantly, we then define the actual keyframes of an animation in a separate
For accessibility, it is best-practice to
With great power there must also come great responsibility.