Hover 21, The Big Stonking Post™
Hover was the first Web Directions event devoted entirely to CSS. Along with the familiar faces of John and Rosemary, Hover was emceed by Hui Jin Chen. Hover was run online over two days, in three timezones.
Disclaimer & Credits
- These notes were hammered out very quickly and paraphrase what speakers were saying. If you need an exact quote, use a definitive source such as a recording or slide deck.
- Photo and other content credits as per the social media embeds.
- Slide credits obviously to the speaker.
The talks
- What’s New In CSS 2021 – Adam Argyle
- Container Queries & The Future of CSS – Miriam Suzanne
- The State of CSS-in-JS – Mark Dalgleish
- CSS Aspect Ratio – Anton Ball
- CSS Variables for Real Life – Matt Colman
- Typography superpower with variable fonts and CSS – Ananya Neogi
- Understanding display – Rachel Andrew
- Neurodiversity (and why you hate CSS) – Facundo Corradini
- The New CSS Logical Properties – Elad Shechter
- Beyond responsive design: new and future media queries – Kilian Valkhof
- CSS Comparison Functions – Ahmad Shadeed
- Move over TypeScript, here comes TypedCSS! – Rhiana Heath
- How To Draw, With CSS – Michal Porag
- A special Webbed Briefs – Heydon Pickering
Day One (April 23)
What’s New In CSS 2021 – Adam Argyle
Adam is taking us through 31 features, rapid fire… from high risk, never-in-any-browser; to stable and available. A high-energy braindump to kick off the conference; full of callouts to the people who propsed these ideas, and to other speakers who will dive in deeper later. A great way to get Hover started!
Very Risky
- Conditional Values – an unofficial draft by Lea Verou, adding inline if statements. unofficial draft - Lea Verou
- Switch – proposal from Brian Kardell, adding switch statements to CSS along with
available-inline-size
which is a read-only value that works much like container queries proposal – Brian Kardell - Relative units – (spec) adding units for line height, cap height, viewport width and height, rlh spec | demo
- Houdini layout – one thing Houdini aims to do is replace heavy use of JavaScript for layout, moving the processing into the layout engine instead of blocking the main app thread. Examples of
layout(masonry)
andlayout(packery)
draft | browser support - Scope – a proposal by Miriam Suzanne to create non-global scope for CSS proposal – Miriam Suzanne
Moderately risky

- Container Queries – for real! You can try this now! You put a contain property on the outer element, then other rules can respond to dimensions of that nearest container instead of the whole viewport. unofficial draft – Miriam Suzanne
- Leading Trim – aims to solve the problem of element dimensions not matching typography dimensions. This effectively shrink wraps the element to the cap height, which is what people often really wanted. learn more | draft – Elika Etemad
- Houdini paint – this lets you extend the engine to paint new backgrounds, the creative options are truly endless draft | learn more | browser support
- Scroll timeline – aims to replace JS solutions for orchestrating relationships between elements based on scroll. Cool demo of a series of fractions, where the slash spins while scrolling between scroll snap points. There are polyfills if you can’t wait for this. draft | demo | browser support
- Spelling and grammar – while the spellcheck and contenteditable attributes aren’t new, what is new is pseudo selectors
::spelling-error
and::grammar-error
spec | browser support - :target-within spec
- Nesting – a draft written by Tab Atkins quite a while ago, to add natively-supported nesting syntax popularised by LESS and SCSS. It works in some subtly different ways, by accessing the parent context and not just the parent selector draft – Tab Atkins
- Cascade layers – allows multiple files/sources to build into a specific point in the cascade, even later in time. This is a huge change to the cascade 'rules’ but addresses a lot of concerns and criticisms spec – Miriam Suzanne
- Foldables – for literally foldable devices, which have different quadrants in their display Explainer | polyfill
- Color Level 5 – lets you work with colour in more advanced ways with color-mix (nifty threshold tricks),
color-contrast
(lets you specify a colour to contrast against – or provide some options for contrasting colours and CSS can 'pick’ one),color-adjust
allows brightness changes,lch
('destructuring for colours’) draft - Masonry – extending the Grid spec to enable masonry layouts draft
- Media Queries level 5 – some nice syntax updates like
<=
,@custom-media
lets you use media queries as variables/custom props Spec | browser support
Low risk
Some of these may require polyfills, many don’t work in IE11. But for many people that’s no longer a big risk factor.
(Example of the colour spaces now open to CSS – brighter colours! Bright as the display can manage, not bright as the language would let you specify…)
- Colour Level 4 – hex with alpha, functional notation (much cleaner syntax), ability to use relative colours via
lch
andlab
colours. This actually gives access to more-vibrant colours that screens can manage but hex didn’t give you access to use. spec | browser support - HD Color – high dynamic range colour comes to the web spec | Demo
- Typed Custom Properties – you can make custom properties but they take anything…
@property
lets you set a type for the property and whether it inherits. This is a huge boost for reliability and code quality! spec | browser support - Content Visibility – note this has some accessibility issues to work out – lets you 'hide’ off screen content with placeholder dimensions. Be really careful to test this if you do use it, but so long as you do there’s no reason not to use it!
- Aspect Ratio – define one width or height plus an
aspect-ratio
and the browser just works it out for you. spec | browser support ::marker
lets you tweak the design of list item markers. Nice, stable and often requested by designers. spec | browser support- Conic Gradients – allows for some really nice new design effects (https://www.conic.style/ for inspiration) spec | browser support | inspiration
- Containment – stops elements from creating cyclical errors that were blocking a lot of container query ideas. You can specify properties to 'contain’ to the element. spec | browser support
:focus-visible
– fixes the problem of getting keyboard-oriented focus styles while using the mouse. This is so widely desired that browsers are shipping it on by default. spec | browser support:focus-within
– style a parent element while a child element has user focus. This is very useful, very powerful!- Logical Properties – a way to move away from assumptions like “left” and “right”, or the position of an “underline” which isn’t always under the text. The logical properties move to contextual, relative values like
max-inline-size
instead ofmax-width
;padding-inline
instead ofpadding-left
andpadding-right
; and usingblock
as a keyword. This will seriously help or change how we think about internationalisation and layout. spec | browser support :is()
and:where()
– allows some neat syntax, although you have to get your head around the specificity differences, so you don’t add higher specificity just because you needed to target a lot of selectors. Very neat. spec | browser supportprefers-reduced-data
media query – lets you reduce heavy resources like fonts and images when the user needs to save data. This is a really big deal for vast numbers of people coming to the web on in countries where expensive mobile plans are still the norm. draft | browser support::cue()
draft | browser support
CSS is cruising!
Container Queries & The Future of CSS – Miriam Suzanne
(I had some connection issues so this is an incomplete writeup)
To understand where we’re going with CSS, we have to understand where it has come from. The web was always For Everyone, on any device.
Web for all. Web for everything. – W3C Mission
So we should send hints and boundaries to browsers and let them work it out. CSS is built to be tolerant to the many challenges users face; while giving authors some escape hatches to boost the importance of certain rules.
CSS also aims to make our styles re-usable; while still resolving conflicts when we send multiple instructions for a single element. So we can establish defaults, set the broad strokes, then adjust all the way down to styles for a single element for one element (with ID selectors).
But this gets complicated. There are a lot of situations where the most general rules, with the lightest selectors, are the most important to always 'win’. So we have a lot of complexity in the way we set our layers of intent… plus !important
grenades.
Cascade Layers are the first big feature in this space. It gives authors a way to define layers like resets, themes and components; and also define the relative importance of those layers (implicitly – the order follows the first definition of layers). It means far less need for hacks and selector warfare.
Scoped Styles – @scope
– gives a form of encapsulation to CSS. The spec is still being debated a lot so it’s a great time to be giving feedback.
So this brings us to the real reason we’re all here…
Container Queries! What devs have been asking for all these years, CQs allow you to style according to the dimensions of containing elements and not the entire viewport. The container element is set in CSS, then other rules can query that element.
/* Establish containers */
.container {
contain: size layout;
}
.sidebar, main, .grid-item {
/* contain: size layout; */
contain: inline-size layout;
}
/* Query containers */
@container (min-width: 40em) {
.card { /* ... */ }
h2 { /* ... */ }
}
You can preview the current state of CQs by enabling them in canary builds of Chrome.
As Jen Simmons put it we are moving to intrinsic web design. Our platform is growing and changing, it is still going through radical changes!
The State of CSS-in-JS – Mark Dalgleish
The TL:DR for CSS-in-JS is that it has heaps of options but is dominated by Styled Components and Emotion.
- A big callout for component developers is the ability for SC to set style according to the props being passed in.
- Emotion gives syntax much closer to what you’d write in CSS directly.
- Both of these libraries get millions of downloads every week so they are very popular.
So is CSS-in-JS a solved problem? Not really – there are a lot of tradeoffs to juggle…
- bundle size
- performance
- flexibility
- abstractions
- static extraction
There’s also a bit of “not invented here” factor where people don’t want to make big bets on an area that’s changing relatively rapidly.
So there are new projects appearing that have different takes on the various concerns.
- Goober – big focus on bundle size and perf
- Stitches – digging into higher level abstractions and ways to handle variants; and also to add better support for CSS variables. They have the foundations set to look for planned static extraction later.
Mark has been working on Vanilla Extract, to go all in on static extraction. The goal is zero-runtime CSS-in-Typescript. The idea is to write styles with the benefits of typescript, but extract vanilla CSS and ship that to users (SCSS-in-JS!).
Another project looking at static extraction is Compiled, by Atlassian. It takes more of an inline/in-JSX approach to writing styles. It uses a bable plugin so it does require the code to be statically analysable. They’re aiming for the holy grail of being as expressive as you want with JS, but enjoy the optimisation of CSS.
So what should you pick if you’re starting a project today? Styled Components and Emotion are stable options that are relatively 'safe’ in this space. But there are lots of new options appearing which are worth checking out.
CSS Aspect Ratio – Anton Ball
Why do we need CSS aspect ratio? The solutions we currently use aren’t so great and it’s a cleaner, better solution.
Quick recap of aspect ratios – they are a relative size ratio:
- 1:1 is a square
- 4:3 is a common monitor ratio
- 16:9 is a really common video ratio
We haven’t had a native solution for this in CSS. There are some hacks and some JS libraries that have papered over the gap. CSS has lots of good approaches to handling images, but they don’t work with video.
Users are often victims of cumulative layout shift – eg. when responsive images load, pushing content around. Ever clicked on the wrong thing because the page jumped? That’s CLS.
So what are the current solutions? The most common are probably the Padding Top Hack or libraries like fitvids.js.
But now we are getting a native CSS solution: aspect-ratio
(not to be confused with the aspect ratio media query).
aspect-ratio: auto|ratio
eg: width: 100%; aspect-ratio: 16/9;
The syntax echoes grid syntax, as consistency helps a lot.
Intrinsic Aspect Ratio (aka natural aspect ratio) is useful for elements that are replaced with other things (iframe, video, embed, img). This is where browsers take the width and height and calculate the ratio for you.
We need to understand that aspect ratio is not the only thing affecting width; and in the heirarchy of CSS it can be thought of as the 'weakest’. If both width and height are set, that combination will override the aspect-ratio
property.
Another gotcha is overflowing content – oversized content will extend the element, unless you specifically set the min-height to zero… at which point it will spill out. Whatever works best in your scenario.
Browser support is good although not universal yet – Safari is notably yet to ship support. It is however part of Web Compat 2021 as it’s such a common use case.
CSS Variables for Real Life – Matt Colman
Currently CSS variables aren’t used that much. They need to come down the CSS pyramid, from the tip to the base.
Matt’s process for new tech is to look into things when they pop up in a few different places; and a quick google showed “CSS vars in five quick examples”... which has the example of changing a background colour. Ok, cool, but we’ve always been able to do that… and basically none of the examples were compelling. Not even “css vars are awesome for dark mode”.
This trend ran through a lot of the top results on the topic. Cool example, but where can I really use it?
That’s the problem, Kent!
Matt finally found a great use case in the JIRA deployments view. They had a tricky rendering case where they needed a border to match a background… but the background varied a lot; and they had to sync hover state as well.
At first they tried to use currentColor
but it wasn’t the colour, it was the background. But it triggered the realisation that it was the first CSS variable.
So they…
- set the colour as a shared var between the container and the element, making it easy to synchronise the row background and the child element’s border
- set fallback variables to make it more reliable
- set different colours per row, because CSS variables are locally scoped
Another real-world example was a CSS var based font size system.
CSS variables also make it much easier to co-name design tokens and code, in a way that’s revealed in dev tools.
Typography superpower with variable fonts and CSS – Ananya Neogi
Currently static fonts dominate the web – for each font variation, we have to send a font file. So different weights and styles all add weight, meaning we have to restrict the type choices we make.
Variable fonts change this equation, by sending one file that supports multiple weights and styles. One file, multiple fonts. You can use CSS to access all the fonts in the file.
Variable fonts have the concept of 'axes’:
- Registered axes –
wdth
,wght
,ital
,slnt
,opsz
- Custom axes – allows extras from the font designer
We use font-variation-settings
in CSS to work with these axes.
h1 { font-variation-settings: "wght" var(--text-wght); }
- Weight controls how heavy the text looks (sort-of-but-not-exactly translates to how thick the stroke is)
- Width controls character width
- Italic is a boolean, the text is either italicised or not
- Slant is similar to italics, but offers more control over the degree of slant
- Optical Size changes the apparent size of the type different, so things remain legible at smaller sizes
So how do you know what your font can do?
- Drop it on WakamaiFondue.com
- Check in Firefox dev tools – there’s a 'font’ tab that gives you access to adjust the axes
Where do you find variable fonts?
- v-fonts.com
- Google fonts
- recursive.design
So what are the practical uses and benefits?
- There are big performance benefits
- The perf benefits in turn give much more freedom to designers, who have more options with typography
- Custom axes can effectively provide totally different typefaces out of one file (eg. the Movement font)
To really make use of all this, combine custom properties, calc()
, media queries… (code demo with quite a bit of maths going on)
Reference: https://blog.typekit.com/2016/08/17/flexible-typography-with-css-locks/
(Demo of the fundamental techniques)
The deeper customisation of variable fonts have accessibility potential, eg. to improve reading experience with optical sizing on small screens:
p {
--text-opsz: 20;
font-variation-settings: "opsz" var(--text-opsz);
@media screen and (min-width: 25em) {
--text-opsz: 16;
}
}
You can also use the GRAD
axis in some fonts, which is hard to see in a presentation but it makes text much clearer when adjusted for different colour combinations. This is a common issue with dark modes, where text becomes less legible.
The more control we have over the way we can design on the web, the better experience we can
Ananya’s slides and code samples
Understanding display – Rachel Andrew
(This is a good one to revise, there is a heck of a lot in this. One of those presentations that everyone from beginner to veteran will learn something.)
CSS1 became a recommendation in December 1996, and it’s a tiny document. But it contains the fundamentals of the language we still use today.
Rachel can’t count the number of times she’s drawn the box model while teaching people CSS... and similarly everyone encounters the concepts of inline and block elements.
Browsers have a user agent stylesheet that applies the very basics of formatting to HTML, even if you don’t. These elements have key intrinsic features; and this can be seen in the way that spacing on those elements is applied.
Block, inline and box model has been the foundation of understanding CSS layout for 20 years. But in recent times, Rachel has found it’s time we have to change that approach. It makes people think Flexbox and Grid are completely separate and not part of the general model of the web.
It all starts with display
. This is the key to understanding everything else. It’s a CSS3 specification, based on concepts in CSS2. These levels of CSS aren’t separate, they build on each other.
Going back to block and inline, what does that mean?
- Block expands to fill available space (which dimension depends on reading direction)
- Inline does not expand
This makes up the normal flow of the document. This is what your layout will always return to, so working with it is easier
Rachel jokes she travels the world talking about little boxes – and it’s easy to think of block and inline as boxes.
CSS specs have a lot of odd words, because of the demands of spec writing – if you don’t know what it means there should always be a link to be able to learn it.
Flexbox creates a new formatting context, in which normal flow does not apply. You now need to pay attention to the flexbox spec. Flex is block, inline-flex is inline. Same for Grid – it sets up a block that abides by the Grid spec.
So display now does a lot of things… and there is some refactoring happening. There is now display: block flex;
and display: block grid
etc. These mappings are only implemented in firefox at this point. But they are useful to understand:
Old Value | New Value(s) |
---|---|
block | block flow |
flow-root | block flow-root |
inline | inline flow |
inline-block | inline flow-root |
flex | block flex |
inline-flex | inline flex |
grid | block grid |
inline-grid | inline grid |
CSS has some new properties, including flow-root
which solves a classic overflow problem of content breaking out. The overflow:auto
hack worked because it created a new block formatting context… flow-root addresses this.
Creating a new context with flow-root will also solve problems with collapsing margins. Flexbox and Grid also retain margins.
...back to boxes…
Any element gets a box; and this creates a box tree as things are nested. But some things aren’t elements that get a box… anonymous boxes, like text nodes.
<p>Some <span>text</span> nodes.</p>
If you set that paragraph to display:flex
, spacing can collapse and you can’t target the anonymous nodes with CSS.
There’s also display:table-cell
… this has some interesting behaviours as it creates anonymous boxes to emulate the HTML structure of table
.
Then there’s float
and position
that take elements out of normal flow. This puts the onus on the author to manage most things that flow was handling for them. This is specified as “out of flow” and defines what should happen.
Out of flow elements can still be effected by changes to parent elements, which may create new contexts that take over. (demo of floated vs grid cards) In essence, floated items won’t be floating any more inside a grid. You can still absolutely-position elements inside a grid layout; but relative to its content area. Display table-cell won’t create anonymous boxes.
This is all defined in the spec, so browsers can handle it consistently.
There are two values of display that don’t generate boxes:
display:none
– box and children all removed, it’s like the box was never theredisplay:contents
– removes the box but not its children, they are promoted in the tree
There are some browser bugs to be resolved around this. Test thoroughly if you are using display:contents at the moment.
Some new terminology: priciple box and marker box. This is demonstrated with with lists – the marker goes around the bullet, the principle goes around the content. CSS lists spec is adding ::marker
so we can target these directly. This opens up some neat things like the ability to add generated content to markers.
All of this stuff is values of display
! Having separate specs for grid and flexbox is more about working group process than anything else.
Very important to understand – values of display do not inherit.
So what about subgrid
? Doesn’t that inherit? Sort of… it allows you to use the track definitions in the subgrid, but values of display are not inherited.
Understanding Display: slides, links/resources, code demos and examples
Day Two (April 30)
Neurodiversity (and why you hate CSS) – Facundo Corradini
The term “neurodiverse” was coined to refer to the unlimited variation of the human mind, without negative connotations of other terms.
(Participatory exercises in visualisation and internal monologue – some people can see pictures or hear their internal monologue, others can’t.)
We all have a primary way of thinking, but nobody’s experience of this is exactly the same. Does that mean some are smarter than others? Well, “intelligence” is traditionally defined as the ability to learn a new task very quickly. Which doesn’t seem to really fit here.
Howard Gardner – Multiple intelligences theory – proposed that there is a range of common styles of intelligence (or perhaps modes of learning). Mainstream psychology recognises the general idea but doesn’t like the terminology/definitions so much.
Designers are commongly Visual-Spatial; programmers are commonly Logical-Mathematical… but CSS sits between.
It is a design task? Is it a coding task? It’s both!
Is CSS a programming language? Yes – it’s a declarative, domain-specific programming language. But many people strongly reject the idea because they prefer a narrower definition of programming language.
CSS is highly contextual, which makes it a lot like most spoken languages. Take the example of the word “lead” in English… it has dozens of possible meanings. In CSS flex:1
can mean many different things depending on the other properties being applied.
CSS has a grammar and you have to follow it to understand what’s going on. Max Stoiber’s red/blue twitter poll shows many people still have trouble following the many contexts of CSS.
CSS is really contextual! Containing blocks, Formatting context, Stacking context, writing-mode, @rules, Inheritance Cascade, Specificity, Origin…
CSS has idioms. Clearfix CSS is a good example – you’re not trying to create a table or show content, those properties are being used to manipulate space.
CSS is a living language that continues to evolve as the need for new words arise.
So back to the question – is CSS design or programming? CSS relies heavily on Verbal-Linguistic intelligence… which is why both designers AND devs can struggle with it.
It can be good to think of CSS the way you’d think of learning a second language. So what approach do you take? How deeply do you need to learn it?
UI libraries are like taking a crash course in a language, just enough to get through a holiday. Most bootcamps are focused on JavaScript and use the crash course approach for CSS. But it means you would struggle to live there…
Some people try to learn CSS by learning lists of properties. But nobody really learns a new language by studying nothing but the dictionary…
For CSS, if you don’t learn more deeply you will always struggle. Instead of fighting margin collapses and float clearing, learn the deeper concept of formatting context… and understand the cascade!
Don’t just use tutorials and libraries, dive into the specs to understand what’s going on. You’ll learn more in an hour reading specs than a month of googling tutorials.
So there are lots of ways to handle the situation.
- Do a crash course
- Learn the language deeply
- Hire an interpreter – hire people who are experts
There’s no harm in allowing people to shine in their role. Include diverse people and play to their strengths.
Celebrate diversity!
The New CSS Logical Properties – Elad Shechter
The internet was not created for the types of websites you use today! Think of CSS flexbox… it only started being implemented in 2012!
If you have been shipping internationalised websites, you’ll have experienced problems in the past where it was easier to ship two different stylesheets than it was to create one that handled both RTL and LTR. Going from left-to-right languages to top-to-bottom is like rotating everything 90degrees… but the
Enter the new CSS Logical Properties… but first a quick refresher
Block Axis defines the overall flow of the page:
writing-mode: horizontal-tb
(horizontal top to bottom)vertical-rl
(vertical right-to-left)vertical-lr
(vertical left-to-right)
Inline Axis defines the text direction in the page
- direction property (LTR/RTL)
To get away from directional naming, flexbox uses names like block-start
and block-end
. So when the direction of the page changes, the naming doesn’t become weird.
CSS Logical Properties continue this important conceptual shift.
Top isn’t Top any more!
Top and bottom are the Block Axis
top
=block-start
bottom
=block-end
Left and right are the Inline Axis
left
=inline-start
right
=inline-end
Margins
margin-top
=margin-block-start
margin-bottom
=margin-block-end
margin-left
=margin-inline-start
margin-right
=margin-inline-end
Width and height turn into min and max inline and block sizes.
So the new CSS box model is renamed, and in the next few years we will stop talking about directions assuming LTR+TB.
But this means we have to relearn all the positional names as well
top
=inset-block-start
left
=inset-inline-start
bottom
=inset-block-end
right
=inset-inline-end
There are also new shorthands. There was no shorthand for top/bottom/left/right properties… but with logical props, we have prefixes that can be used as shorthands. Eg. for all the inset-
properties:
inset: 0 0 0 0;
inset: 0 0;
inset: 0;
Text-align
text-align: left
=text-align: start
text-align: right
=text-align: end
(lots of code examples along these lines, view the slides if you want a full list – these just give the flavour)
Live example: https://codepen.io/elad2412/pen/oQJmYQ
So can you use it yet? If you don’t need to support IE11, yes https://caniuse.com/css-logical-props – most of the core values are supported, there are some exceptions.
...and there are still some problems such as having to write out all margin properties longhand; and media queries don’t support them yet; things like that.
They are considering a new keyword 'logical’ to convert things like margin into logical flow; there is also a suggestion to have a flow-mode property you can set on html {}
(you can upvote Elad’s suggestion at https://github.com/w3c/csswg-drafts/issues/1282#issuecomment-443253091)
More reading:
Beyond responsive design: new and future media queries – Kilian Valkhof
Responsive design is about websites adapting to things like the user’s device and surroundings. So the more we can do to understand what the user prefers, the better. There is a lot of new stuff coming, this talk will pick out some of the key things.
New media queries that are likely to be available soon:
contrast
reduced-data
custom-media
reduced-transparency
light-level
dynamic-range
Starting with everyone’s favourite… dark mode! prefers-color-scheme
currently has just two values, light and dark; but the format keeps it open for future options.
prefers-reduced-motion
– reduce the amount of swooshing going on. You should put your animations behind this check, so users who don’t want them don’t have to put up with them. There is also a hack where you can remove animations via a *
selectors in CSS.
(Aside: see the linked guide for more examples than the few I’ve cherry picked here)
reduced-data
is something you can add in today, serving lighter resources to browsers that do support it.
prefers-contrast: more|less|no-preference
– there are lots of reasons to need different levels of contrast, many devices now include night modes that people are using to remove blue light. So there is a lot of interest in this space.
forced-colours: none|active
– hard override of your colours, gives users a high level of control. Not a lot of adjustment required; and there are some ways to force your own colours, eg. if you have a colour picker.
prefers-reduced-transparency
– helps reduce problems like layering images and text.
light-level: dim|normal|washed
– this handles the issues caused by ambient lighting varying from very-bright to very-dark.
@custom-media
is a big deal for all this as it enables variables in media queries, which helps manage these things in a rational way.
More:
CSS Comparison Functions – Ahmad Shadeed
An example to illustrate what CSS Comparison Functions are…
To change the text size at different sizes we’d usually reach for a media query:
.title {
font-size: 1rem;
}
@media (min-width: 600px) {
.title {
font-size: 2rem;
}
}
But you can do it this way instead with clamp:
.title {
font-size: clamp(1rem, (2vw + 1rem), 2rem)
};
So CSS Comparison Functions give us much shorter, neater syntax.
min()
– you set a range of values and it will display the smallestmax()
– you set a range of values and it will display the largest- eg.
min(50%, 500px)
andmax(50%, 500px)
Clamp allows a preferred value as well as min/max:
.element {
width: clamp(200px, 50%, 1000px);
}
- The width will never go below 200px
- The preferred value is 50% and will only work if the viewport width is greater than 200px and less than 1000px.
- The width won’t go above 1000px
Things get even more powerful as clamp supports Math Expressions – you don’t even need to use calc()
.
Currently we design specifically for a set of different sizes; in the future we will set min/max/preferred and let the browser rendering inside those limits.
Accessibility note: avoid using min() for font-size, it’s very risky… easy to accidentally set microtext on portrait-mode mobile screens.
Example use cases for CSSCFs:
- adding max() into linear-gradient(), so effects cna be adjusted at different screen sizes
- using clamp() to adjust the padding above and below page sections; or the margins around headings
To support IE11 you can set a fallback property first, then add the CSSCF property; or use at-supports.
More:
Move over TypeScript, here comes TypedCSS! – Rhiana Heath
Typed CSS really just means adding some type safety to CSS.
Why even have types?
- better errors
- code the documents itself
- faster performance
So what types does CSS have now? While we see things in terms of properties, values, unitless values, etc… in terms of readable types they’re all just strings.
If you’ve worked with CSS values in JS you’ll have hit the issue – eg. where 500px is a string, which you need to split into the value and the unit to work on it.
If you typo a value like 500pxs you get a generic Invalid property value
error. It’s technically accurate but it’s not helpful – it can be caused by such a broad range of problems.
So what is Typed CSS?
It’s an API under the CSS Houdini umbrella – Typed Object Model (OM) sits alongside the more-discussed APIs like Layout.
What types are we looking at in the CSS Typed OM? CSS-specific things like…
- keyword
- position
- unit – a good example: in “500px”, “px” is the unit and 500 is the value
- image
A couple of disclaimers:
- Houdini is still fairly experimental and doesn’t have production-ready support yet… ishoudinireadyyet.com
- Houdini is JS+CSS, not pure CSS
Example:
foo.css('width')
current state – returns value as a string500px
foo.attributeStyleMap('width')
typed css – returns unit and value in a CSSUnitValue object{ value: 500, unit: 'px' }
You can also set attributes this way. foo.attributeStyleMap.set('width', CSS.percent(50))
Once you can reliably get values and units separately, you can work with them much more easily; and it enables things like unit conversion. In a practical sense this means you can do calculations with mixed units, like a percentage added to a pixel value.
You can also add in error handling, eg. try/catch using CSSStyleValue.parse()
to check if you have a valid value.
More:
- Rhianna’s Slides (includes resource/link list)
- Codepen with Typed OM demos
How To Draw, With CSS – Michal Porag
Have you ever wondered how people create incredible art with CSS?
Dribbble is a great place to find inspiration for this. Of course if you copy anything, ask the artist for permission first. Or make something that is clearly a copy of a famous work, with no deception.
Great example of randomly generated Mondrian squares – this is actually easier in code than it is in paint! We can also improve artwork with CSS thanks to animation.
But how do you start? Start simple – play with border-radius
on all corners of an element. You can make a range of curved shapes.
Example with Pikachu – draw two lines across the face and you can see how the curves add up to make the shape, just by adjusting the border radius. Remember that when the corners don’t meet or add up, you can get straight lines as well.
Use relative units for this, to open up more opportunities and work on more devices.
Once you master tricks of creating basic shapes, use z-index to layer them.
The next trick is to bend gradients. Remember there are linear, radial and conic gradients in CSS and they will all give you different creative options. Conic gradients can make sharp cornered shapes too.
The next trick – box-shadow doesn’t just add shadows, you can create more shapes by adding more shadows.
Walkthrough of drawing a single-div kite
- Conic gradients with solid colours create triangles; these are combined to make the kite body
- Elongate the shape with transform (scaleY) to make it look like kite sails
- The tail is created on a pseudo element with a black border
- Border radius curves the tail
- Then crazy box-shadow tricks to create the kite tail bows
- Then animate rotation to give it movement
A special Webbed Briefs – Heydon Pickering
(This writeup does not in any way approach the experience of watching this, you should just watch it. I have created a writeup mostly for my own amusement.)
There are lots of ways to draw a line onto a computer screen with CSS...
#1 The Horizontal Rule
<hr />
is a semantic element indicating a break in the content. It renders with a “shadow” set with an inset border. To remove that you can add a noshade
attribute will draw a line without a shadow… although it is deprecated, so you should really just do it with a CSS border
. You could also style an empty <div>
but that has accessibility issues – it’s not a semantic element.
#2 Scalable Vector Graphics
SVG has a few ways to draw a line. You can use a no-height rect
or a line
or a polyline
… but the most versatile way to draw a line is path
. Combine curves with fills and you can you draw just about everything, like skulls, because your calendar’s memento mori stopped working.
#3 UTF-8 encoded SVG background images
You can send a 1×1 SVG as a data url; then use repeating backgrounds to draw lines. Or stripes. Or sweary monks. If you use this technique with enough complexity you might achieve the galaxy-brained heights of CSS-in-SVG-in-CSS-in-JS.
#4 Repeating linear-gradients
SVG backgrounds are neat but you can’t rotate them. Linear gradients can rotate things, so if you want diagonal things you could use them for that. Hashtag diagonal hashtag stripes hashtag hashtag hashtag number.
#5 Houdini paint worklets
Paint worklets let you draw a line by writing a bunch of JavaScript. It has access to JS Math so you can do nifty random things. It looks a lot like canvas and needs JS. But it’s totally CSS. You might be a parsnip if you do this.
#6 WebGL
Arguably the pinnacle of over engineering for drawing a line… in simulated 3D space. But you can’t tell because you’re looking at it side on.
In summary
You can make browsers draw lines lots of ways. You should choose the simplest and most efficient way for your specific use case.
Some lines are decorative, but some are meaningful and should be audible.
Finally, remember that the leading cause of death in the UK is choking on an unchewed melon. The second most common cause of death is spontaneous combustion triggered by telling someone CSS Is A Programming Language.