#254: Back to Basics, Focus Styles, Morphing Text, and Build vs Buy

For some reason this week I’ve been returning to the very basics of HTML and CSS, going over a lot of blog posts that remind me that there’s still some gaps I have in my knowledge when it comes to the foundations of web design. For example, back in May, Florens Verschelde wrote this great piece about styling buttons the right way and how to avoid all the common mistakes. Resetting the styles to make buttons look like links, and then adding hover, focus, and active states to make things look a bit snazzier.

On that note, Chris wrote a while back about the importance of :focus states:

Always worth repeating: all interactive elements should have a focus style. That way, a keyboard user can tell when they have moved focus to that element.

I feel like a lot of designers and developers hate :focus states. I’ve worked with folks who hate them and then whenever I need to use a keyboard to tab through an interface on the web I find it difficult to see the highlight. But :focus states should be gigantic and eye-catching, that’s really what’s best for usability.

The problem with CSS was that whenever you used :focus like this:

a:focus {
  background-color: blue;

…it meant that when you clicked that link with a mouse or with your finger on a touch screen you’d see the focus state. And a lot of folks hated that. But now it’s possible to only make these styles apply to keyboard-focused elements with the :focus-visible pseudo. So you can write something like this:

/* Focusing the button with a keyboard will show a dashed black line. */
button:focus {
  outline: 4px dashed black;
/* Focusing the button with a mouse, touch, or stylus will show a subtle drop shadow. */
button:focus:not(:focus-visible) {
  outline: none;
  box-shadow: 1px 1px 5px rgba(1, 1, 0, .7);

That :focus:not(:focus-visible) bit is a really smart hack for only applying these styles to mouse or touch clicks. And it’s a hack that has pretty okay-ish browser support, too.

[Chris]: All this focus stuff is a mind trip for me. I had to create a test page to wrap my mind around it all. It really is a clever trick to combine :focus and :focus:not(:focus-visible)so you can style keyboard focus and mouse focus differently, while not losing those keyboard focus styles in non-supporting browsers. In the future, if :focus-visible becomes perfectly supported and you’re in a position where you want keyboard-focus-only styles, you could only use :focus-visible, but that’s a lot of maybes.

[Chris]: Another thing worth mentioning. If you’re on a Mac and you are testing keyboard focus stuff, but aren’t a huge keyboard focus use yourself, you might have an OS setting you need to change. Go to System Preferences > Keyboard > Shortcuts and at the bottom there is a checkbox for “Use keyboard navigation to move focus between controls”. Browsers are starting to honor that, meaning keyboard tabbing might not work how you think it should if this setting isn’t on.

Another post that caught my eye this weekend was from Danny Guo where he wrote about relearning HTML from scratch and what he discovered along the way:

I wondered what I was missing by never learning HTML in a comprehensive way. Forget CSS and JavaScript. I’m just talking about raw HTML. It might seem silly to go back to such a basic aspect of web development after a decent amount of experience, but it’s easy to become overconfident with a skill just because you know enough to do a few useful things.

Dang, I love this so very much. I feel like I need to do this too since there’s a few ARIA-specific situations and edge cases where I often get stumped by. I know that ARIA should be used as a last resort, but still. There’s gaps there for sure.

Here’s another gap I discovered this week: I didn’t know that there was a hack to change the spacing between elements that are inline-block. I discovered this through Temani Afif’s blog post on how to create hexagonal grids with CSS grid. And the example he shows is this:

As I discovered in this blog post Chris wrote from way back in 2012, the trick is to set the font-size of the spaces between elements to 0 like this:

nav {
  font-size: 0;
nav a {
  font-size: 16px;

That’s… extremely weird!

This feeling of filling in the gaps is why I love Ana Tudor’s work so very much. She constantly shows me where the gaps are in my knowledge when it comes to CSS. And whenever I think: ah! I really do understand what the current limitations of CSS are, Ana bursts through the door and does something neat like this:

All this reminds me of Eric Meyer’s post this week called Ancestors and Descendants where he makes a list of weirdo browser bugs that plagued developers back in the day:

I know it’s still fashionable to complain about how CSS is all janky and weird and unapproachable, but child, the wrinkles of today are a sunny park stroll compared to the jagged icebound cliff we faced at the dawn of CSS.

Reading this post makes me feel so extremely thankful for all the hard work of those standards groups and advocates who pushed for a single web platform instead of the fractured nightmare it once was. But it also reminds me that sometimes we need to go back to the very beginning to understand why things work the way that we do.

And by returning to the basics we can make even better websites.

Trigonometry in CSS and JavaScript

I enjoyed this post from Michelle Barker all about trigonometry in CSS. And the way that Michelle uses custom properties to communicate between CSS and JavaScript is nifty as all heck.

CSS Morphing

Amit Sheen made this rather fabulous thing in CSS where he animates from one word to the next with morphing the shapes. Looks like Amit is using a CSS filter to blur the letters to make them look as if they’re morphing with some sort of SVG mask or something. Pretty impressive stuff.

What else are filters capable of? Well, we have a whole almanac entry on that if you want to do a deep dive as to what else is possible with CSS here. But I’d also highly recommend checking out this Pen from Mads Stoumann where he lists out each filter so you can see directly how to manipulate an image with CSS:

Debugging in iOS Safari

Here’s a list of tips for debugging iOS Safari issues from Chris:

I happen to have a Mac, so I can have XCode installed and thus have an iOS simulator that is pretty easy to pop open. And if you can run the iOS simulator, that means you can run desktop Safari as well, and thus even have access to DevTools that can reach into the simulator.

The layout selectors in Chrome and Safari are great if you want to fix small screen bugs but if you think there’s a bigger problem then emulating iOS Safari on the desktop is definitely the way to go.

Spoiler alert: you can use Inspect to use Chrome DevTools to debug iOS native devices, even on Windows.

Front-end testing is for everyone

Tests have saved my bacon more than once but I’ve always relied upon the testing setup of the engineering team at whatever organization I’m at. So it’s nice to read this in-depth piece from Evgeny Klimenchenko about why testing is worth the hassle:

Testing is one of those things that you either get super excited about or kinda close your eyes and walk away. Whichever camp you fall into, I’m here to tell you that front-end testing is for everyone. In fact, there are many types of tests and perhaps that is where some of the initial fear or confusion comes from.

If you’re unfamiliar with testing then I think this blog post is for you, or if you have someone on your team who isn’t an engineer that’s interested in why writing tests are important, then this is the post you need to send them.

Take control of your Core Web Vitals [Free webinar]

It’s game time. Core Web Vitals (CWV) are here, and the vast majority of businesses are completely underprepared. Fortunately, this provides an opportunity to get a competitive edge for you and your business, and Raygun is here to help.

Instant Deposits with WooCommerce Payments

Narrow the amount of time it takes between to collect earnings from your online store sales. With the new (and free!) Instant Deposits feature in WooCommerce Payments, your sales earnings are transferred to a debit card within minutes — including nights, weekends, and holidays.

That’s just one of the many benefits of using WooCommerce Payments with your WordPress store. Securely accept payments, track cash flow, and manage recurring revenue from your dashboard — all without setup costs or monthly fees.

Psst! Automattic is looking for a Happiness Engineer to join a global team that provides support for WordPress.com, WooCommerce, and other Automattic products. Use your passion for problem solving to help customers, like business owners and creative artists, succeed online. Apply now!

[Chris]: There is a classic “build vs buy” discussion that happens when building software? Do we build our own error tracking system or do we buy software that does error tracking? Do we build our own customer feedback forms, or do we buy software that helps with customer feedback? Do we spin up our own servers for our search databases, or do we buy dedicated managed hosting?

Early in the life of a startup, the decision to build might happen a lot. Because, well, you don’t have any money to buy with anyway. Or we’re developers, this is what we do feels right. Later, you might buy a lot more. Buying means you are outsourcing things that aren’t your specialty anyway to services that spend all day thinking about those problems. You get to take advantage of best-in-industry tools. It may turn out that buying actually meaning saving a lot of money, since you’re avoiding technical debt and focusing on your core product, not the periphery.

And then it can swing back again. At a certain gigantic scale, bringing things back in-house that you were buying can mean saving money and having fine-grained control and expertise.

That’s why it’s such a fun conversation. The math is different for everyone.

I really liked Simon Willison’s addition to that conversation. It’s not just about money and focus, it’s about culture as well.

Take logging for example. If you buy a log aggregation platform like Splunk Cloud or Loggly the pricing is likely based on the quantity of data you ingest per day.

This can set up a weird incentive. If you are already close to the limit of your plan, you’ll find that engineers are discouraged from logging new things.

This can have a subtle effect on your culture. Engineers who don’t want to get into a budgeting conversation will end up avoiding using key tools, and this can cost you a lot of money in terms of invisible lost productivity.

Tools that charge per-head have a similar problem: if your analytics tool charges per head, your junior engineers won’t have access to it. This means you won’t build a culture where engineers use analytics to help make decisions.

This is a very tricky dynamic. On the one hand it’s clearly completely crazy to invest in building your own logging or analytics solutions—you should be spending engineering effort solving the problems that are unique to your company!

But on the other hand, there are significant, hard-to-measure hidden costs of vendors with billing mechanisms that affect your culture in negative ways.

It’s not just an accounting problem. It’s not just a technology problem. It’s a people problem.