Journal
Using CSS display: contents to snap grandchild elements to a grid
I realised last night while watching a presentation by Lea Verou that I could streamline my CSS Grid layouts.
I’d been creating an overall page grid by setting body { display: grid; } then some grid areas but realised that this only worked for direct children and didn’t help with aligning more deeply nested elements to that outer grid.
For example in the case of the main header if I wanted its child logo, nav and search elements to snap to the body grid then I found myself having to duplicate the display: grid and grid-template-areas again on the header.
It didn’t feel very DRY but my understanding was that while we await subgrid, it was a necessary evil.
What I should have been using is display: contents.
If you set your header to display: contents then the parent (body) grid layout will apply to the header’s contents (logo, nav, etc) as if the header element (the “real” direct child of the grid) wasn’t there. This gives us good semantics without the need to redefine the grid on the header.
Here’s a codepen to illustrate.
I was aware of the existence of display: contents but somehow it hadn’t sunk in because I’d only read about it in the abstract. Lea Verou’s explanation made all the difference. Cheers, Lea!
Update 4/5/2019
Frustratingly, I’ve learned that although we can apply this technique, we shouldn’t… or at least not for a while.
Due to a bug in all supporting browsers the property will currently also remove the element (header in our case) from the accessibility tree meaning that its semantics will be lost.
For reference, see:
Update 11/4/2021
Thanks to Rachel Andrew for the heads-up that this issue is now fixed in both Firefox and Chrome.
We’re now just waiting for Edge and Safari to roll out fixes before we can regard this as a safe option.
The Art of DJing: Jeff Mills (on Resident Advisor)
Fair play, Jeff – once this interview gets going it’s pretty damn good.
Amongst other ground, it covers:
- The technique of “Subtraction”;
- the last quarter of records being the best;
- the bar for electronic music being set too low;
- the complexity of the art form of DJing; and
- thinking about other things while DJing in front of 2000 people…
Plenty of good bits to chew over!
How to control SVG icon size and colour in context
A while back I read a great SVG icon tip from Andy Bell which I’d been meaning to try and finally did so today. Andy recommended that for icons with text labels we set the width and height of the icons to 1em since that will size them proportionately to the adjacent text and additionally lets us use font-size to make any further sizing tweaks.
As previously mentioned, I’ve recently been working on my SVG skills.
Andy Bell’s SVG icon-sizing technique is really clever and feels like it adds lots of flexibility and future-friendliness so I was keen to try it out.
Here’s how it works.
The HTML:
<a class="call-to-action" href="/">
<span>I’m a link</span>
<svg
class="cta-icon"
aria-hidden="true"
width="1em"
height="1em"
viewBox="0 0 14 13"
xmlns="http://www.w3.org/2000/svg">
<path
fill="currentColor"
fill-rule="evenodd"
d="M3.49.868l7.683 3.634a2 2 0 0 1 .052 3.59l-7.682 3.913a2 2 0 0 1-2.908-1.782V2.676A2 2 0 0 1 3.49.868z">
</path>
</svg>
</a>
<a class="call-to-action call-to-action-alt" href="/">
<span>I’m a large link</span>
<svg
class="cta-icon" aria-hidden="true"
width="1em" height="1em"
viewBox="0 0 14 13"
xmlns="http://www.w3.org/2000/svg">
<path
fill="currentColor"
fill-rule="evenodd"
d="M3.49.868l7.683 3.634a2 2 0 0 1 .052 3.59l-7.682 3.913a2 2 0 0 1-2.908-1.782V2.676A2 2 0 0 1 3.49.868z">
</path>
</svg>
</a>
The CSS:
a { color: rgb(183, 65, 14); }
a:hover { color: #6A2000; }
.call-to-action {
display: inline-flex;
align-items: center;
font-weight: bold;
}
.call-to-action-alt {
font-size: 2rem;
}
.cta-icon {
margin-left: .5em;
font-size: .8em;
}
Here are my key takeaways:
- By applying
widthandheightof1emto our icon it is predictably sized by default. - It can now have its size further tweaked in CSS using
font-size, for example with ems (where1em= the font-size of the parent anchor element). - This technique requires the
viewboxattribute being present on the svg. - Apply the width and height =1em as inline attributes on the svg. We could apply them using CSS, however the inline approach avoids potentially massive icons showing in cases where CSS doesn’t load.
- To get the colour matching, apply
fill="currentColor"as an inline attribute on the svg’s path. - Now, when you apply a hover colour to the anchor in CSS, the icon will just pick that up. Nice!
- Applying
inline-flexto the anchor makes the vertical-alignment of text and icon easier. - Apply
aria-hiddento the icon because it’s mainly decorative so we don’t want it read out by screen readers.
$$ in the DevTools Console
I learned something new today when developing in the Firefox Dev Tools console (although this applies to Chrome too)—something which was really useful and which I thought I’d share.
Basically, type $$('selector') into the console (replacing selector as desired) and it’ll give you back all matching elements on the page.
So for example, $$('script') or $$('li').
Similarly you can select a single element by instead using one dollar sign ($).
These seem to be console shortcuts for document.querySelector() (in the case of $) and document.querySelectorAll() (in the case of $$).
The other really cool thing is that the resultant nodeList is returned as an array, so you could do e.g. $$('li').forEach(…) or similar.
via @rem (Remy Sharp)
Check localhost development on your iPhone
Here’s how to check the application you’re running locally on your MacBook on your iPhone.
It’s pretty much a case of connecting your iPhone to your MacBook by USB, tweaking some settings, then browsing to the application via a given IP in iOS Safari.
Stuffing the front end
Here’s Bridget Stewart, a developer from Ohio, with some thoroughly enjoyable “curmudgeonly” thoughts on why your website doesn’t necessarily need a Javascript framework.
With websites taking a median time of 5.8 seconds to show primary content (source: HTTPArchive) and Google warning us that 53% of mobile visits leave pages that take longer than three seconds to load, it’s hard to justify stuffing the front-end unnecessarily.
Bridget’s article also contains this quote which I love:
First, solve the problem. Then, write the code.
Essentially, don’t select the tooling first—a principle I fully endorse.
Accessible modal dialogues in 2019
I previously noted Keith J Grant’s article on the HTML dialog element which promised a native means of handling popups and modal dialogues. I’ve not yet used dialog in production, partly because of spotty browser support (although there is a polyfill) but also partly because—for reasons I couldn’t quite put my finger on after reading the spec—it just didn’t feel like the finished article.
Fast forward to March 2019 and Scott O’Hara has written an excellent piece describing why it’s still not ready. There are a combination of factors: lack of browser support, reliance on JavaScript; and multiple accessibility issues.
The good news is: having dug deeper into Scott’s work I see that among the many accessible components he has shared with the world is a custom, accessible modal dialogue. So next time the need arises, I think I’ll start there.
Thanks, Scott!
Box Shadow around the full box
Sometimes when coding a UI element you want a shadow around the whole box. However, most CSS box-shadow examples/tutorials tend to show inset box-shadows or ones that otherwise sit off to the side.
Here’s how to apply box-shadow to the whole box for a simple but nice effect.
.box-with-shadow {
box-shadow: 0 0 4px #ccc;
}
And here’s how it looks:
Details and summary for no-JavaScript disclosure widgets
The fairly-recently added <details> element is a great, native HTML way to toggle content visibility.
Certbot Troubleshooting
When taking the DIY approach to building a new server, Certbot is a great option for installing secure certificates. However, sometimes you can run into problems. Here, I review the main recurring issues I’ve encountered and how I fixed them.
When creating new servers for my projects I use Certbot as a means of installing free Let’s Encrypt secure certificates.
It’s great to be able to get these certificates for free and the whole process is generally very straightforward. However, since working with Let’s Encrypt certificates over the last few years I’ve found that the same recurring questions tend to plague me.
This is a note to “future me” (and anyone else it might help) with answers to the questions I’ve pondered in the past.
How do I safely upgrade from the old LE system to Certbot?
For servers where you previously used the 2015/2016, pre-Certbot Let’s Encrypt system for installing SSL certs, you can just install Certbot on top and it will just work. It will supersede the old certificates without conflict.
How do I upgrade Certbot now that Let’s Encrypt have removed support for domain validation with TLS-SNI-01?
Essentially the server needs Certbot v0.28 or above. See Let’s Encrypt’s post on how to check your Certbot version and steps to take after upgrading to check everything is OK. To apply the upgrade I performed apt-get update && apt-get upgrade -y as root although depending on when you last did it this might be a bit risky as it could update a lot of packages rather than just the Certbot ones. It might be better to just try sudo apt-get install certbot python-certbot-apache.
To what extent should I configure my 443 VirtualHost block myself or is it done for me?
When creating a new vhost on your Linode, DigitalOcean (or other cloud hosting platform) server, you need only add the <VirtualHost *:80> directive. No need to add a <VirtualHost *:443> section, nor worry about pointing to LE certificate files, nor bother writing rules to redirect http to https like I used to. When you install your secure certificate, certbot will automatically add the redirect into your original file and create an additional vhost file (with extension -le.ssl.conf) based on the contents of your existing file but handling <VirtualHost *:443> and referencing all the LE SSL certificate files it installed elsewhere on the system.
How should I manage automated renewals?
There’s no longer any need to manually add a cron job for certiticate renewal. Auto-renewal of certificates is now handled by a cron job which comes bundled with the certbot package you initially install – in my case usually a certbot ppa package for Ubuntu 16.04 or 18.04. However you won’t find that cron job in the crontab for either your limited user, nor the root user. Instead, it is installed at a lower level (/etc/cron.d) and should just work unless you’ve done something fancy with systemd in your system which in my case is unlikely.
How can I tell if renewals are working and what should I do if they’re not?
If you notice that the SSL certificate for your domain is within 30 days of expiry and hasn’t yet auto-renewed, then you know that something has gone wrong with the auto-renewal process. You can test for problems by running sudo certbot renew --dry-run. You may find that there is, for example, a syntax error in your apache2.conf or nginx config file which needs corrected – not that I’ve ever been guilty of this, you understand…