I think it’s great that the CSS Working Group does these. It’s like planting a flag in the ground saying this is what CSS looks like at this specific point in time. They do specifically say it’s not for us CSS authors though…
This document collects together into one definition all the specs that together form the current state of Cascading Style Sheets (CSS) as of 2020. The primary audience is CSS implementers, not CSS authors, as this definition includes modules by specification stability, not Web browser adoption rate.
Remember “CSS3”? That was the closest thing we had to a “snapshot” that was designed for CSS authors (and learners). Because CSS3 was so wildly successful, we saw a short round of enthusiasm for CSS4, me included. There is zero marketing panache on that snapshot page, which is exactly what CSS4 would need to succeed. Remember, HTML5 and friends (including CSS3) even had fancy logos!
If someone were to say to me “Chris, when CSS3 came around, I boned up on all that, but I haven’t kept up with CSS since, what should I learn?” I’d say “That’s a damn fine question, developer that has a normal healthy relationship with technology.” But honestly, I might struggle to answer cohesively.
I’d say: Uhm, CSS grid for sure. Custom properties. Clipping and Offset paths I suppose. prefers-reduced-motion. I dunno. There are probably like 100 things, but there is no great single reference point to see them all together.
I’ll work on putting a list together. I don’t think I’ll have the gumption to call it CSS4, but at least I’ll be able to answer that question. Feel free to suggest ideas in the comments.
Are you seeing the 'Error establishing a database connection' notice on your WordPress website? It is a fatal error that makes your WordPress website inaccessible to the users.
This error occurs when WordPress is unable to connect to the database. A number of things can affect your WordPress database connection which makes it a bit difficult for beginners to troubleshoot.
Me, I really dislike FOUT. I like that it’s an option, because not displaying text quickly on the web is no good. I know font-display: swap; is popular because it’s good for performance, but that FOUT stuff pains me. Matt Hobbs:
If there’s one thing I’d like readers to take away from this post it’s that font-display: swap is a very good option for users with a fast internet connection. But its infinite swap period could be frustrating for users on very slow and unstable connections. If you have users viewing your site under these conditions (I’m pretty certain you will at some point in time), then it may be worth considering font-display: fallback or even font-display: optional.
Seeeee, I told ya. I like how font-display: optional; totally stops FOUT. The font is either applied super fast, or isn’t used at all (but still downloaded async). Chances are, on the next page load, the font is loaded and cached and will be used.
Note this is about slow connections, not necessarily connections where the user would prefer as little data usage as possible. If that’s the case, check out some of the recent posts we linked up in Responsible, Conditional Loading.
Something I learned (or, I guess, re-learned) this year is how important it is to pay close attention to the bit depth of images. Way back in the day, we used to obsessively choose between 2-, 4-, or 8-bit color depth on our GIFs, because when lots of users were using dialup modems to surf the web, every kilobyte counted.
Now that a huge number of us access the web via broadband, guess what? Every kilobyte still counts. Because not everyone has access to broadband, particularly in the mobile space; and also, any time we can shave off page rendering is worth pursuing. I’d assumed that optimization tools handled things as trivial as color depth optimization that for us, but discovered I was wrong there.
This is particularly true for PNGs. By default, lots of image editing tools save PNGs with 2^24 color depth, just in case.
For a photograph, that makes some sense (though if it’s a photograph, you should probably save it as JPG or WebP) but for things like logos and icons, that’s approximately 2^24 more colors than you’re going to be using.
So in Acorn, my image editor of choice, I’ve been taking special care to crank down the bit depth on PNGs in the export dialog. In many cases, I’ve cut image weight 80% or more by indexing colors to a palette of 256 or fewer values, with no loss of visual fidelity. (Again, these aren’t photographs I’m talking about.)
Here’s an example:
That PNG at full-color depth is about 379KB. Restricted to a palette of 32 colors, it’s 61KB. And that’s just at the export time: once I run them through ImageOptim, the optimized sizes are 359KB and 48KB. That’s a weight savings of about 85%, just by lowering the color depth. And if I deployed the image and discovered it needs a few more colors, I could re-run the process to use 64 colors: the final size, in that case, is 73KB, still enormous savings.
Reducing color depth by eye is clearly more onerous than throwing an optimization script at a directory of images, but in my experience, the results are much more efficient in terms of image weight and therefore user experience. And that’s really what all this is about, isn’t it?
In an age where so much web design is already neat, clean, and simple, I can think of three ways to distinguish your site from the norm:
Stunning visuals that cannot be created in UI vector editors, like Figma and Sketch
Beautifully-animated interactions that cannot be dreamt in the language of Stacks of Rectangles
Typography
The third is the most accessible, and an awesome place to differentiate your brand. Accordingly, look for a renaissance of type — a flourishing of serifs, throwbacks, quirky fonts, and genre-bending typefaces. Expect that font pairing will become an even more important skill, and picking great fonts for your brand will carry even more weight in the near future.
After all, it’s basically a design cheat code.
🔥 There are only two “cheatcodes” in UI design. The first is: USE GOOD FONTS. Here, the popular but slightly too goofy Abril Fatface pales in comparison to stately Freight. (10/50)
Looks like all the content of MDN is on GitHub now. That’s pretty rad. That’s been the public plan for a while. Chris Mills:
We will be using GitHub’s contribution tools and features, essentially moving MDN from a Wiki model to a pull request (PR) model. This is so much better for contribution, allowing for intelligent linting, mass edits, and inclusion of MDN docs in whatever workflows you want to add it to (you can edit MDN source files directly in your favorite code editor).
Looks like that transition is happening basically today, and it’s a whole new back-end and front-end architecture.
Say you wanted to update the article for :focus-within. There will be a button on that page that takes you to the file in the repo (rather than the wiki editing page), and you can edit it from the GitHub UI (or however you like to do Git, but that seems like right-on-GitHub will be where the bulk of editing happens). Saving the changed document will automatically become a Pull Request, and presumably, there is a team in place to approve those.
We think that your changes should be live on the site in 48 hours as a worst case scenario.
Big claps from me here, I think this is a smart move. I can’t speak to the tech, but the content model is smart. I’d maybe like to see the content in Markdown with less specialized classes and such, but I suspect that kind of thing can evolve over time and this is already a behemoth of an update to ship all at once.
In August 2020, the entire MDN (writers) team was laid off, so it looks like the play here is to open up the creation and editing of these technical docs to the world of developers. Will it work? It super didn’t work for the “Web Platform Docs” (remember those?). But MDN has way more existing content, mindshare, and momentum. I suspect it will work great for the maintenance of existing docs, decently for new docs on whatever is hot ‘n’ fresh, but less so for anything old and “boring”.
Seems a little risky to fire all the writers before you find out if it works, so that speaks to the product direction. Things are changing and paying a content creation team directly just ain’t a part of whatever the new direction is.
This year, I learned that there is a wide world of free stock imagery available beyond Unsplash and Pexels. You see, I’ve been working on designing WordPress themes this year, and all images need to be compatible with the GPL. Unsplash and Pexels both have free and open licenses, but unfortunately, aren’t compatible. Many other free stock photos sites don’t have the highest quality photos, so I’ve had to get creative about where I get the imagery I use in my mockups.
I discovered the solution to my stock imagery problem, ironically, on Unsplash. I started noticing photos from sources like the British Library, Birmingham Museums Trust, and Library of Congress. Who often has archives of public domain imagery? Libraries, museums, and governments. The sites are never a site like Unsplash, but they work well if you have the time and patience to dive through their archives. Plus? You can find some pretty cool photography, art, and illustrations that have a very different vibe than most stock photo resources.
Many museums have started digitizing their collections in the past few years, such as the Smithsonian’s National Museum of Asian Art, the Met, and the Art Institute of Chicago. As the museums are often digitizing the work themselves, they have the luxury of releasing the images into the public domain. Museums are a fantastic resource for art, and for photos of objects like ceramics and jewelry that work well in e-commerce mockups.
Governments
US Government agencies like NASA tend to release a ton of their own media for public use, and I’ve discovered that space images look great in blog post mockups. Need some COVID photos? The CDC’s got you covered. Need some black & white nature photos? Check out the National Park Service’s “Open Parks Network.”
Finding high-quality, totally free stock imagery can be a huge hassle. But I’ve found, with some creativity and some patience, there are far more options than I knew!
Tracking changes is a quintessential copyediting feature for comparing versions of content. While we’re used to tracking changes in a word processing document, we actually have HTML elements capable of that. There are a lot of elements that we can use for this process. The main ones we’ll look at are <del>, <ins> and <mark>. But, as we’ll see, pairing them with other elements — including <u>, <aside> and custom markup — we can get the same sort of visual tracking changes features as something like Word, Google Docs, or even WordPress.
Let’s start with the <ins> element.
The <ins> designates text that should be or has been inserted. The verb tense gets a little wonky here because while the <ins> tag is suggesting an edit, it has to have, by virtue of being in the <ins> tag, already been inserted. It’s sorta like saying, “Hey, insert this things that’s technically already there.”
Notice how the browser underlines the inserted text for us. It’s nice to have that sort of visual indication, even if it could be mistaken as an underline using the <u> element, a link, or the CSS text-decoration property.
Let’s pair the insertion with the <del> element, which suggests text that should be or has been deleted.
The browser styles <del> like a strikethrough (<s>) element, but they mean different things. <del> is for content that should be removed/edited out (like that creepy seeming section above) while <s> is for content that’s no longer true or inaccurate (like the letter writer’s belief that that section would be endearing).
OK, great, so we have these semantic HTML elements and they produce some light visual indicators for content that is either inserted or deleted. But there’s something you might not know about these elements: they accept a cite attribute that can be used to annotate the change.
cite takes a properly formatted URL that provides points somewhere to find the reasons why the change was made. That somewhere could even be an anchor on the existing page.
That’s cool, but one issue is that the citation URL isn’t actually visible or clickable. We could use some CSS magic to display it. But even then, it still won’t take you to the citation when clicked… nor can it be copied.
That said, it does make semantically clear what’s part of the edit and what is not. If we wrap <ins> and <del> in a link (or even the other way around) it still is not clear whether the link is supposed to be part of the edited content or not.
But! There’s a second attribute that <ins> and <del> both share: datetime. And this is how we can indicate when an edit was made. Again, this is not immediately available to a user, but it keeps semantically clear what is part of the edit and what isn’t.
HTML’s datetime format, as a machine readable date and time, requires precision and can thus be a bit, well, cranky, But it’s general tenants aren’t too hard. It’s worth noting though that, while datetime is used on other elements, such as <time>, formatting the value in a way that doesn’t include at least a specific day, month, and year on <ins> and <del> would be problematic, obscuring the date and time of an edit rather than provide clarity.
We can make things clearer with a little more CSS magic. For example, we can reveal the datetime value on hover:
Checkboxes work too:
But good editing is far more than simply adding and deleting content. It’s asking questions and figuring out what the heck the author intended. (For me personally, it’s also about saving me from embarrassing spellling and grammar mistooks).
So, meet the <mark> element.
<mark> points out text of special interest to the reader. It usually renders as a yellow background behind the content.
If you’re the editor and want to write a note to the writer (let’s name that person Stanley Meagher) with suggestions to make Stanly’s letter more awesome (or less creepy, at the very least) and that note is large enough to warrant flow content (i.e. block level elements), then the note can be an <aside> element.
<aside class="note">Mr. Meagher, I highly recommend you remove this list of preferred cheeses and replace it with things you love about the woman you are writing to. While I'm sure there are many people for whom your list would be interesting if not welcome, that list rarely includes a romantic interest in the midst of your profession of love. Though, honestly, if she is as perfect for you as you believe, it may be the exact thing you need to test that theory.</aside>
But often you’ll want to do something inline in order to point something out or make a comment about sentence structure or word choice. Unfortunately there’s no baked in way to do that in HTML, but with a little ingenuity and some CSS you can add a note.
<span class="note">Cheesecake isn't really a "cheese"</span>
The <u> element — long an anathema to web developers for fear of confusion with a link — does actually have a use (I know, I was surprised too). It can be used to point out a misspelling (apparently squiggly and red underlines aren’t a standard browser rendering feature). It should still not be used anywhere it might be confused with an actual link and, when used, it definitely should use a color that distinguishes it from links. Red color may be appropriate to indicate an error.
<p>Please, <u>Lura</u> tell me your answer. Will you wear my mathlete letter jacket?</p>
As we’ve seen throughout this article, the browser’s default styles for the elements we’ve covered so far are certainly helpful but can also be confusing since they are barely distinguishable from other types of content. If a user does not know that the document is showing edits, then the styling may be misconstrued or misunderstood by the user. I’d therefore suggest some additional or alternate styles to help make it clear what’s going on.
ins {
padding: 0 0.125em;
text-decoration: none;
background-color: lightgreen
}
del {
padding: 0 0.125em;
text-decoration: none;
background-color: pink;
}
mark {
padding: 0 0.125em;
}
.note {
padding: 0 0.125em;
background-color: lightblue;
}
aside.note {
padding: 0.5em 1em;
}
u {
text-decoration: none;
border-bottom: 3px red dashed;
}
I ask myself the same question every time I learn something new in HTML: How can I needlessly animate this?
It would be great if we could fade up the changes so that when you clicked a checkbox the edits would fade in as well.
The notes and text in <del> tags can’t be faded in with CSS the same way that background colors and paddings can. Also, display: none results in no fading at all. Everything pops back in place, including the backgrounds. But using a combining the CSS visibility property with a set height and width value of 0 allows the backgrounds to smoothly fade in.
And there you have it: specifications and a few strategies for keeping track of edits on the web (plus an excellent example of how not to write a love letter (or, perhaps, how to write one so perfect that responding positively to it is a sign you’re soulmates).
Edit: Adrian Roselli adds some excellent accessibility information in the comments. Before you implement these ideas in production, be sure to consider those suggestions.
Back in August 2020, when the content-visiblity property in CSS trickled its way into Chrome browsers, Una Kravets and Vladimir Levin wrote about it and we covered it. The weirdest part is that to get the performance value out of it, you pair it with contain-intrinsic-size on these big chunks of the page where you insert some arbitrary guess at a height. I wrote:
That part seems super weird to me. Just guess at a height? What if I’m wrong? Can I hurt performance? Can (or should) I change that value at different viewports if the height difference between small and large screens is drastic?
Jake Archibald and Das Surma just did a video on all this and it helped clarify that a bit. You can see at about 7:30 in just how confusing it is. Jake used this massive HTML spec page as a demo, and made <section> wrappers around big chunks of HTML, and applied:
section {
content-visibility: auto; /* this is the thing that delays painting */
contain-intrinsic-size: 1px 5000px; /* this is the guess at the height of the content, and also saying width doesn't matter */
}
Apparently that 5000px isn’t the height of the element, it’s the size of the content of that element. I guess that matters because it will push that parent element taller by that number, unless the parent element overrides that with a height of its own. The magic comes from the fact that the browser will only paint¹ the first section (where it’s very likely the viewport isn’t over 5000px tall) and defer the painting on the rest. Sorta like lazy loading, but everything rather than media alone. It assumes the next section is 5000px tall, but once the top of it becomes visible, it will actually get painted and the correct height will be known. So assuming your page is just big ass blocks on top of each other, using an extremely large number should work fine there. Godspeed if your site is more complicated than that, I guess.
It’s a good video and you should watch it:
This is yet another thing where you have to inform the browser about your site so that it can Do Performance Good™. It is information that it can figure out by itself, but not until it has done things that have a performance cost. So you have to tell it up front, allowing it to avoid doing certain types of work. With responsive images, if we give images a srcset attribute with images and tell the browser in advance how big they are, including a sizes attribute with information about how our CSS behaves, it can do calculations ahead of time that only download the best possible image. Likewise, with the will-change property in CSS, we can tell the browser when we’re going to be doing movement ahead of time so it can pre-optimize for that in a way it couldn’t otherwise. It’s understandable, but a little tiresome. It’s like we need a stuff-you-need-to-know.manifest file to give browsers before it does anything else — only that would be an additional request!
The accessibility implications are important too. Steve Faulkner did a test applying content-visibility: auto to images and paragraphs:
The content is visually hidden, but in both JAWS and NVDA the hidden<img> is announced but the content of the <p> element is not. This has to do with how the img and the p element content are represented in the browser accessibility tree: The img is exposed in the accessibility tree with the alt text as the accessible name. The content of the p element is not present in the accessibility tree.
He notes that content hidden this way should not be available to screen readers, per the spec. I could see it going either way, like hide it all as if it was display: none, meaning none of it is in the accessibility tree. Or, leave it all in the accessibility tree. Right now it’s a tweener where you might see a bunch of stray images in the accessibility tree without any other context than their alt text. This is an interesting example of new tech going out with more rough edges than you might like to see.
Speaking of alt text, we all know those shouldn’t be empty when they represent important content that needs to be described to someone who can’t see them. They should be like paragraphs, says Dave:
I finally made the simplest of all connections: alt text is like a paragraph. Word pictures. Basic I know, but it helps me contextualize how to write goodalt text as well as source order of my code.
I don’t want to be overly negative here! The performance gains for setting up a long-scrolling page with content-visibility is huge and that’s awesome. Being able to inform the browser about what is OK not to paint in two lines of code is pretty nice.
I keep saying “paint” but I’m not sure if that’s really the right term or if it means something more specific. The spec says stuff like “allowing user agents to potentially omit large swathes of layout and rendering work until it becomes needed” (emphasis mine).
We’ve covered techniques before for when you want a full-width element within a constrained-width column, like an edge-to-edge image within a narrower column of text. There are loads of techniques.
That works as long as the column is centered and you don’t mind having to hide overflow-x on the column (or the body) as this can trigger horizontal overflow otherwise.
There was a little back and forth on some other ideas lately…
Josh Comeau blogged that you could set up a three-column grid, and mostly place content in the middle column, but then have the opportunity to bust out of it:
I think this is clever. I’d probably use it. But I admit there are bits that feel weird to me. For instance…
Now everything within the container is a grid element. Not a huge deal, but the elements will behave slightly differently. No margin collapsing, for one.
You have to apply the default behavior you want to every single element. Rather than elements naturally stacking on top of each other, you have to select them and tell them where to go and let them stack themselves. Feels a little less like just going with the web’s grain. Then you still need a utility class to do the full bleed behavior.
What I really like about the idea is that it gives you this literal grid to work with. For example, your left spacer could be half the width of the right and that’s totally fine. It’s setting up that space to be potentially used, like Ethan talked about in his article on constrained grids.
Kilian Valkhof responded to the article with this idea:
Also very clever. This constrains the width of everything (in whatever container, and it wouldn’t have to be the body) except the elements you want to bust out (which could be a utility class there too, and not necessarily images and videos).
Again, to me, this feeling that I have to select every single element and provide it this fundamental information about layout feels slightly weird. Not like “don’t use it” weird, just not something I’m used to doing. Historically, I’m more comfortable sizing and positioning a container and letting the content in that container lay itself out without much further instruction.
You know what I like the most? That we have so many powerful layout tools in CSS and we have conversations about the pros and cons of pulling off exactly what we’re going for.
CSS Grid is a collection of properties designed to make layout easier than it’s ever been. Like anything, there’s a bit of a learning curve, but Grid is honestly fun to work with once you get the hang of it. One area where it shines is dealing with headers and footers. With a little adjustment in our thinking, we can pull off headers and footers that behave like they are fixed, or have that “sticky” treatment (not position: sticky, but the kind of footer that hugs the bottom of the screen even if there isn’t enough content to push it there, and is pushed away with more content).
Hopefully this sparks further interest in modern layouts, and if it does, I can’t recommend Rachel Andrew’s book The New CSS Layout strongly enough: it covers both of the major modern layout techniques, grid and flexbox.
What we’re making
Let’s implement a fairly classic HTML layout that consist of a header, main content and footer.
We’ll make a truly fixed footer, one that stays at the bottom of the viewport where the main content scrolls within itself, as needed, then later update the footer to be a more traditional sticky footer that starts at the bottom of the viewport, even if the main content is small, but gets pushed down as needed. Further, to broaden our exposure to grid, let’s design our main content holder so that it can either span the whole width of the viewport, or take up a nicely centered strip down the middle.
A fixed footer is slightly unusual. Footers are commonly designed to start at the bottom of the viewport, and get pushed down by main content as needed. But a persistent footer isn’t unheard of. Charles Schwab does it on their homepage. Either way, it’ll be fun to implement!
But before we move on, feel free to actually peek at the fixed footer implemented on the Charles Schwab site. Unsurprisingly, it uses fixed positioning, which means it has a hard-coded size. In fact, if we crack open DevTools, we see that right off the bat:
Not only that, but there’s the balance of making sure the main content doesn’t get hidden behind that fixed footer, which it does by setting hard-coded paddings (including 15px on the bottom of the <footer> element), margins (including 20px on <ul> in the footer), and even line breaks.
Let’s try to pull this off without any of these restrictions.
Our baseline styles
Let’s sketch out a bare minimum UI to get us started, then enhance our grid to match our goals. There’s a CodeSandbox below, plus additional ones for the subsequent steps that get us to the end result.
First, let’s do some prep work. We’ll make sure we’re using the whole height of the viewport, so when we add our grid, it’ll be easy to put the footer at the bottom (and keep it there). There’s only going to be one element inside the document’s <body> with an ID of #app, which will hold the <header, <main> and <footer> elements.
Next, let’s set up our header, main, and footer sections, as well as the grid they’ll all sit in. To be clear, this will not work the way we want right out of the gate. It’s just to get us started, with a base to build from.
We’ve created a simple one-column layout, with a width of 1fr. If that 1fr is new to you, it essentially means “take the remaining space” which, in this case, is the entire width of the grid container, #app.
We’ve also defined three rows:
#app {
/* etc. */
grid-template-rows: auto 1fr auto;
/* etc. */
}
The first and third rows, which will be our header and footer, respectively, are sized with auto, which means they’ll take up as much space as needed. In other words: no need for hard-coded sizes! This is a super important detail and a perfect example of how we benefit from using CSS Grid.
The middle row is where we’ll put our content. We’ve assigned it a size of 1fr which, again, just means it takes up all of the remaining space that’s left over from the other two rows. If you’re wondering why we aren’t making it auto as well, it’s because the entire grid spans the viewport’s whole height, so we need one section to grow and fill up any unused space. Note that we do not have, nor will we ever need at any point, any fixed heights, margins, paddings — or even line breaks! — to push things into place. Such is the good life when working with grid!
Shall we try some content?
You’ll notice in the Sandbox that I used React to build this demo, but since this isn’t a post about React, I won’t belabor those details; React has absolutely nothing to do with any of the CSS Grid work in this post. I’m only using it as an easy way to navigate between different chunks of markup. If you hate React, that’s fine: hopefully you can ignore it in this post.
We have Header, Main and Footer components that render the expected <header> , <main> and <footer> elements, respectively. And, of course, this all sits inside our #app container. Yes, in theory, #app should be an <article> element, semantically speaking, but that’s always looked weird to me. I just wanted to covey these details so we’re all one the same page as we plow ahead.
For the actual content, I have Billing and Settings sections that you can navigate between in the header. They both render fake, static content, and are only meant to show our layout in action. The Settings section will be the content that we put in a centered strip on our page, Billing will be the one that spans our whole page.
The Billing section looks good, but the Settings section pushes our footer off screen. Not only that, but if we scroll, the entire page scrolls, causing us to lose our header. That may be desirable in some cases, but we want both the header and footer to stay in view, so let’s fix that.
Fixed header, fixed footer
When we initially set up our grid, we gave it a height of 100vh, which is the entire height of the viewport. We then assigned the rows for the header and footer an auto height, and the main a height of 1fr to take up the remaining space. Unfortunately, when content exceeds the space available, it expanded beyond the viewport bounds, pushing our footer down and out of view.
The fix here is trivial: adding overflow: auto will cause our <main> element to scroll, while keeping our <header> and <footer> elements in place.
We want our <main> element to either span the whole width of the viewport, or be centered in a 600px space. You might think we could simply make <main> a 600px fixed width, with an auto margins on either side. But since this is a post about grid, let’s use moar grid. (Plus, as we’ll see later, a fixed width won’t work anyway).
To achieve our centered 600px element, we’ll actually make the <main> element a grid container. That’s right, a grid within a grid! Nesting grids is a totally legit approach, and will even get easier in the future when subgrid is officially supported across browsers. In this scenario, we’ll make <main> a grid with three column tracks of 1fr 600px 1fr or, stated simply, 600px in the middle, with the remaining space equally divided on the sides.
Now let’s position our the content in the grid. Our different modules all render in a <section> child. Let’s say that by default, content will occupy the middle section, unless it has a .full class, in which case it will span the entire grid width. We won’t use named areas here, and instead specify precise grid coordinates of the form [row-start] / [col-start] / [row-end] / [col-end]:
You might be surprised to see a col-end value of 4, given that there’s only three columns. This is because the column and row values are column and row grid lines. It takes four grid lines to draw three grid columns.
Our <section> will always be in the first row, which is the only row. By default it’ll span column lines 2 through 3, which is the middle column, unless the section has a full class on it, in which case it’ll span column lines 1 through 4, which is all three columns.
Here’s an updated demo with this code. It’ll probably look good, depending on your CodeSandbox layout, but there’s still a problem. If you shrink the display to smaller than 600px, the content is abruptly truncated. We don’t really want a fixed 600px width in the middle. We want a width of up to 600px. It turns out grid has just the tool for us: the minmax() function. We specify a minimum width and a maximum width, and the grid will compute a value that falls in that range. That’s how we prevent the content from blowing out of the grid.
All we need to do is swap out that 600px value with minmax(0, 600px):
Earlier, we decided to prevent the footer from being pushed off the screen and did that by setting the <main> element’s overflow property to auto.
But, as we briefly called out, that might be a desirable effect. In fact, it’s more of a classic “sticky” footer that solves that annoying issue, and places the footer on the bottom edge of the viewport when the content is super short.
How could we keep all of our existing work, but allow the footer to get pushed down, instead of fixing itself to the bottom in persistent view?
Right now our content is in a grid with this HTML structure:
…where <main> is a grid container nested within the #app grid container, that contains one row and three columns that we use to position our module’s contents, which go in the <section> tag.
…and incorporate <footer> into the <main> element’s grid. We’ll start by updating our parent #app grid so that it now consists of two rows instead of three:
#app {
/* same as before */
grid-template-columns: 1fr;
grid-template-rows: auto 1fr;
grid-template-areas:
'header'
'main';
}
Just two rows, one for the header, and the other for everything else. Now let’s update the grid inside our <main> element:
We’ve introduced a new auto-sized row. That means we now have a 1fr row for our content, that holds our <section>, and an auto row for the footer.
Now we position our <footer> inside this grid, instead of directly in #app:
#app > footer {
grid-area: 2 / 1 / 2 / 4;
}
Since <main> is the element that has scrolling, and since this element now has our footer, we’ve achieved the sticky footer we want! This way, if <main> has content that exceeds the viewport, the whole thing will scroll, and that scrolling content will now include our footer, which sits at the very bottom of the screen as we’d expect.
Here’s an updated demo. Note that the footer will be at the bottom of the screen if possible; otherwise it’ll scroll as needed.
I made a few other small changes, like minor adjustments to paddings here and there; we can’t have any left or right paddings on <main>, because the <footer> would no longer go edge-to-edge.
I also made a last-minute adjustment during final edits to the <section> element—the one we enabled adjustable width content on. Specifically, I set its display to flex, its width to 100%, and its immediate descendant to overflow: auto. I did this so the <section> element’s content can scroll horizontally, within itself, if it exceeds our grid column boundary, but without allowing any vertical scrolling.
Without this change, the work we did would amount to the fixed footer approach we covered earlier. Making section> a flex container forces its immediate child — the <div> that contains the content — to take up all of the available vertical space. And, of course, setting that child div to overflow: auto enables scrolling. If you’re wondering why I didn’t just set the section’s overflow-x to auto, and overflow-y to visible, well, it turns out that’s not possible.
Parting thoughts
We haven’t done anything revolutionary in this post, and certainly nothing that couldn’t be accomplished before CSS Grid. Our fixed width <main> container could have been a block element with a max-width value of 600px, and auto margins on the left and right. Our fixed footer could have been made with position: fixed (just make sure the main content doesn’t overlap with it). And, of course, there are various ways to get a more traditional “sticky footer.”
But CSS Grid provides a single, uniform layout mechanism to accomplish all of this, and it’s fun to work with — honestly fun. In fact, the idea of moving the footer from fixed to sticky wasn’t even something I planned at first. I threw it in at the last minute because I thought the post was a bit too light without it. It was trivial to accomplish, basically moving grid rows around, not unlike putting lego blocks together. And again, these UIs were trivial. Imagine how brightly grid will shine with more ambitious designs!
Remy documented this the other day. Firefox supports a Highlight keyword and both Chrome and Safari support a -webkit-focus-ring-color keyword. So if you, for example, have removed focus from something and want to put it back in the same style as the browser default, or want to apply a focus style to an element when it isn’t directly in focus itself, this can be useful.
For example:
button:focus + span {
outline: 5px auto Highlight;
outline: 5px auto -webkit-focus-ring-color;
}
Looks good to me. It’s especially helpful with the sorta weird new Chrome double-outline style that would be slightly tricky to replicate otherwise.
Una doing an amazing job of showing just how (dare I say it?) easy CSS layout has gotten. There is plenty to learn, but what you learn makes sense, and once you have, it’s quite empowering.
This is a neat interactive page by Ville V. Vanninen to reference the names of things in the CSS syntax. I feel like the easy ones to remember are “selector,” “property,” and “value,” but even as a person who writes about CSS a lot, I forget some of the others. Like the property and value together (with the colon) is called a declaration. And all the declarations together, including the curly brackets (but not the selector)? That’s a declaration block, which is slightly more specific than a block, because a block might be inside an at-rule and thus contain other complete rule-sets.
Any time I chat with a fellow web person and CSS-Tricks comes up in conversation, there is a good chance they’ll say: oh yeah, that guide on CSS flexbox, I use that all the time!
Indeed that page, and it’s cousin the CSS grid guide, are among our top trafficked pages. I try to take extra care with them making sure the information on them is current, useful, and the page loads speedily and properly. A while back, in a round of updates I was doing on the guides, I reached out to Lynn Fisher, who always does incredible work on everything, to see if she’d be up for re-doing the illustrations on the guides. Miraculously, she agreed, and we have the much more charismatic illustrations that live on the guides today.
In a second miracle, I asked Lynn again if she’d be up for making physical paper poster designs of the guides, and see agreed again! And so they live!
Here they are:
You better believe I have it right next to me in my office:
They are $25 each which includes shipping anywhere in the world.
Here’s a fancy new experimental feature in Chrome! Now, we can get an overview of the CSS used on a site, from how many colors there are to the number of unused declarations… even down to the total number of defined media queries.
Again, this is an experimental feature. Not only does that mean it’s still in progress, but it means you’ll have to enable it to start using it in DevTools.
Open up DevTools (Command+Option+I on Mac; Control+Shift+I on Windows)
Head over to DevTool Settings (? or Function+F1 on Mac; ? or F1 on Windows)
Click open the Experiments section
Enable the CSS Overview option
And, oh hey, look at that! We get a new “CSS Overview” tab in the DevTools menu tray when the settings are closed. Make sure it’s not hidden in the overflow menu if you’re not seeing it.
Notice that the report is broken out into a number of sections, including Colors, Font info, Unused declarations and Media queries. That’s a lot of information available in a small amount of space right at our fingertips.
This is pretty nifty though, huh? I love that tools like this are starting to move into the browser. Think about how this can help us not only as front-enders but also how we collaborate with designers. Like, a designer can crack this open and start checking our work to make sure everything from the color palette to the font stack are all in tact.
The title of this Sara Soueidan article speaks to me. I’m a big fan of the idea that some CSS is best applied globally, and some CSS is best applied scoped to a component. I’m less interested in how that is done and more interested in just seeing that conceptual approach used in some fashion.
Sara details an approach where components don’t have too much styling by default, but have CSS custom properties applied to them that are ready to take values should you choose to set them.
For each pattern, I’ve found myself modifying the same properties whenever I needed to use it — like the font, colors (text, background, border), box shadow, spacing, etc. So I figured it would be useful and time-saving if I created variables for those properties, define those variables in the ‘root’ of the component, and ‘pass in’ the values for these variables when I use the pattern as I need. This way I can customize or theme the component by changing the property values in one rule set, instead of having to jump between multiple ones to do so.
I’d say 85% of my grid usage is in one of these two categories…
I just need some pretty basic (probably equal width) columns that ends up being something like like grid-template-columns: repeat(3, minmax(0, 1fr));to be safe.
Actually doing some real layout where five minutes in I realize I’d really like subgrid.
Subgrid? It’s a nice intuitive way to have a child element on the grid inherit relevant grid lines from the parent grid.
Here’s a great recent video from Rachel Andrew covering it. Last year, we linked up her talk on the same! It’s such a clutch feature and I wish we could rely on it cross-browser. Right now, Firefox is the only one that has it. (Chrome issue, Safari issue)
In my recent video, right about at 20 minutes, I realize subgrid would make even a fairly simple layout much nicer, like removing the need for variables or resorting to magic numbers.