Designing Beautiful Shadows in CSS
joshwcomeau.com
Josh Comeau:
In this tutorial, we’ll learn how to transform typical box-shadows into beautiful, life-like ones.
Josh Comeau:
In this tutorial, we’ll learn how to transform typical box-shadows into beautiful, life-like ones.
Terence Eden explains how different screen technologies, human biology, and fingerprint grease make “pixel perfection” a pointless goal:
There is no grid. There never has been. You can align to theoretical pixels - but as soon as the image hits a physical screen, it will be adjusted to best fit reality.
An obsession with pixel perfect rendering is futile.
Every Layout expands on this idea, specifically as it pertains to CSS:
Suffice it to say that, while screens are indeed made up of pixels, pixels are not regular, immutable, or constant. A
400px
box viewed by a user browsing zoomed in is simply not400px
in CSS pixels. It may not have been400px
in device pixels even before they activated zoom.
See also: Ian Mallett’s Subpixel Zoo: A Catalog of Subpixel Geometry.
Ollie Williams welcomes the new CSS properties for styling underlines:
Finally we can demarcate links without sacrificing style thanks to two new CSS properties.
text-underline-offset
controls the position of the underline.text-decoration-thickness
controls the thickness of underlines, as well as overlines, and line-throughs.
I’ve been working on a blog post about this topic, and Ollie does a good job of covering some of the points I want to make. But I want to go further and explore implementation quirks, the details where the new properties don’t quite go far enough, and make a case for why underlines shouldn’t be pixel-aligned.
Evan Minto:
min()
accepts one or more values and returns the smallest value. The magic of the function is that, just likecalc()
, the arguments can use different units, which allows us to return values that change dynamically based on context.
min()
is one of three new comparison functions introduced as part of the CSS Values and Units Module Level 4. There’s alsomax()
, which naturally does the inverse ofmin()
. Finallyclamp()
is a convenience function that applies both a minimum and a maximum to a single value.
This is brilliant and I can’t wait until I can change my @supports
queries from display: grid
to min()
.
A repository of styled and “styled” form control elements and markup patterns, and how they are announced by screen readers.
Heydon Pickering and Andy Bell have created a terrific resource for CSS layout patterns following algorithmic design principles.
We make many of our biggest mistakes as visual designers for the web by insisting on hard coding designs. We break browsers’ layout algorithms by applying fixed positions and dimensions to our content.
Instead, we should be deferential to the underlying algorithms that power CSS, and we should think in terms of algorithms as we extrapolate layouts based on these foundations. We need to be leveraging selector logic, harnessing flow and wrapping behavior, and using calculations to adapt layout to context.
This approach is precisely what I’ve been striving for ever since Jen Simmons’s Intrinsic Web Design talk from last year.
Ethan Marcotte:
When I’m asked to describe design systems work, I say the word that springs immediately to mind is mapmaking. As designers like Matthew Ström and Alla Kholmatova have argued, every website has a design system underneath it. Take yours, for example: your website’s interface is built from a library of components, each shaped by a series of design decisions and business needs. Your design system may not be explicit—maybe you don’t have a polished pattern library, or a set of well-defined design principles, or maybe your documentation’s not as robust as you’d like it to be—but it’s still a system. And in order to improve that system, you have to research it before you can begin to gradually, slowly improve it.
Brad Frost:
I was just talking with Dave about the accessibility of moving images on the web, and he said:
hm… I wonder if you could use
picture
+prefers-reduced-motion
?He then sends the following code:
<picture> <source srcset="no-motion.jpg" media="(prefers-reduced-motion: reduce)"></source> <img srcset="animated.gif alt="brick wall"/> </picture>
Whoa! This is a revelation.
There are a few CSS techniques for hiding content visually while keeping it accessible to screen readers, but none of them are perfect — and in some cases may even be harmful.
@zellwk has put together a great round-up of the issues.
UPDATE! This approach has bugs. Best solution so far is by @_josephwatkins.
— Zell Liew 🤗 (@zellwk) April 25, 2019
I updated my article with my latest findings: https://t.co/UosivA8R5h https://t.co/Qk2Hzqye67
Tobias Ahlin:
On the surface it seems fairly easy to create a masonry layout with flexbox; all you need to do is set
flex-flow
to column wrap` and voilà, you have a masonry layout. Sort of. The problem with this approach is that it produces a grid with a seemingly shuffled and obscure order. Items will be (unbeknownst to the user) rendered from top to bottom and someone parsing the grid from left to right will read the boxes in a somewhat arbitrary order, for example 1, 3, 6, 2, 4, 7, 8, 5, and so on so forth.Flexbox has no easy way of rendering items with a
column
layout while using arow
order, but we can build a masonry layout with CSS only—no JavaScript needed—by using:nth-child()
and theorder
property.
This is very clever — an actually helpful use of order
that helps visual order more accurately follow source order.
But there’s a catch: it requires a fixed height for the container — and it needs to be a magic number that’s taller than the tallest column. That unfortunately makes it not super resilient to content changes, limiting its usefulness.
Richard Rutter:
There is more to setting hyphenation than just turning on the hyphens. The CSS Text Module Level 4 has introduced the same kind of hyphenation controls provided in layout software (eg. InDesign) and some word processors (including Word). These controls provide different ways to define how much hyphenation occurs through your text.
This is great news. I’ve always avoided CSS hyphenation because of how aggressive the algorithms are. Using these new properties in concert with @supports
we can get well-controlled hyphenation as a progressive enhancement while avoiding the half-baked hyper-hyphenated middle ground we’ve had so far.
Dave Rupert thinks version number bumps would be a good move for HTML and CSS, marketing-wise. I agree!
A single number bump replaces a mountain of marketing. Every discerning technologist knows it only makes sense to invest in technologies that are moving forward. To invest in a stagnant technology would be a dereliction of duty.
I think this has effected web technologies deeply. HTML5 was released in 2008 and its handful of new elements and APIs was a boom for the language. Even Steve Jobs advocated for it over Flash. Web Standards had won, Firefox and Webkit were our champions. “We need to upgrade to HTML5” was a blanket excuse for auditing your website and cleaning up your codebase.
Andy Bell suggests using CSS Custom Properties together with Heydon Pickering’s lobotomized owl selector to manage vertical spacing. It’s an elegant solution that works well with the cascade:
.flow {
--flow-space: 1em;
}
.flow > * + * {
margin-top: var(--flow-space);
}
I’ve been experimenting with old-school margin collapsing for vertical rhythm this past year, in Cobalt. I’m a proponent of spacing being an inherent property that exists by default instead of something that has to be explicitly added. But margin collapsing doesn’t really play well with Grid layout (until we get something like margin-trim
), so I might give this method a try.
Vincent De Oliveira:
Line-height
andvertical-align
are simple CSS properties. So simple that most of us are convinced to fully understand how they work and how to use them. But it’s not. They really are complex, maybe the hardest ones, as they have a major role in the creation of one of the less-known feature of CSS: inline formatting context.
No kidding, this stuff is complex.
Florian goes over a set of confusingly named properties and values from the css-text-3 specification that control what happens to white spaces when laying out text, and how line breaking works. He explains the logic of the system, different ways the properties can be used to achieve various results, and looks into some of the complication caused by incomplete implementations.
I care about this topic a lot, but it really tests my patience. If only browser support for these properties were consistent, I could start to build a mental model that takes them all into consideration. As it stands, it’s such a mess that I routinely have to spend time reading about it, and still not be super confident with the results.
A really clever (if somewhat opaque) use of flexbox to achieve some semblance of container-based layout breakpoints. Intrinsic Web Design for the win!
Jonathan Snook tried to make it more understandable, and Heydon published a follow-up post with some optimizations.