RSSAmplifier

Blog

Manuel Matuzović - Blog

My Blog about accessibility, performance, and CSS architecture and layout.

matuzo.atRSS feed ↗243 posts

Latest posts

Progressively enhancing Grid Lanes

This post is a follow-up on my previous post. I was wondering whether it s safe to use Grid Lanes today. I came up with a solution I find okay, but there is a caveat. Note: This post contains interactive demos. If you want to see them instead of screenshots, enable the CSS Grid Lanes Layout flag in Edge or Chrome or use Safari 26.4+ or Polypane 29+. In my last blog post, Your Grid Lanes will…

Your Grid Lanes will likely fail WCAG 2.4.3

I saw a great introduction to CSS Grid Lanes , aka Masonry Layouts, by Patrick Brosset at CSS Day 2026. I liked the versatility of its use cases, but I was also concerned that it s inaccessible by default. Note: This post contains interactive demos. If you want to see them instead of screenshots, enable the CSS Grid Lanes Layout flag in Edge or Chrome or use Safari 26.4+ or Polypane 29+. Intro to…

Setting the width of selects to the width of the selected option

The field-sizing property is coming to Firefox 152, making it available across all major engines. It allows you to control the sizing behavior of elements with a default preferred size, such as form elements. I ll take a closer look at the field-sizing property in another blog post, but I wanted to show you a cool feature first. By default, the width of a select element is determined by its…

Zen, Zed, and Zits

Don t worry, this post is not about zits, but something comparably annoying: Zen and Zed . One is a browser and the other an editor. Even writing this, I don t know which is which. Their names and icons are so similar that I keep getting them confused. I couldn t take it anymore; I had to take drastic measures. That s why I replaced the icon of the Zen browser application with a nice-looking e…

Context-aware headings in HTML

A common issue that we ve probably all faced at some point is having a component that includes a heading, which sometimes should be an H2 and sometimes maybe an H3, depending on where it s used. We solved this by giving editors an option to pick the appropriate heading level in the CMS. That works, but it means more work for them, because they need to keep track of the document outline, and it s…

Don't put aria-label on generic elements like divs

The title already tells most of the story, but here s why you must avoid labeling generic elements like divs or spans using aria-label or aria-labelledby . Looking at the ARIA spec, you ll find section "5.2.8.6 Roles which cannot be named (Name prohibited)" . It lists all roles that cannot be named. It includes “generic”, which is the default role of divs and spans. caption code deletion emphasis…

box-shadow is no alternative to outline

People like to use the box-shadow property for styling focus outlines because it gives them more flexibility. A focused button That s okay in browsers default color mode, but in forced colors mode , it s problematic because the box-shadow property computes to none , which means that there are no shadows and consequently no focus styles in this mode. You can confirm that by opening this page in a…

The geolocation element is odd

Imagine the following scene: you re on a website, and there s a button. When you click the button, it shows some text, but the website s font size is really small. So, you change the default font size in your browser from 16 to 24 pixels. You go back to the website and click the button again, but it doesn t work now. That s not just very unfortunate, but it s also absolutely unexpected, confusing,…

Your skip link targets may not need tabindex=-1 to work properly

Recently, someone posted on LinkedIn that skip links are often broken because their target elements are missing a tabindex attribute. I was really surprised to see that because I thought that was an issue of the past. That s why I decided to test it. The original problem The author explained in their post that when you use a keyboard and press Enter on a skip link, the page scrolls down to the…

role=presentation is no alternative for aria-hidden=true

In the previous post , I explained how to hide presentational SVGs using aria-hidden="true" . That s a reliable technique, but sometimes I see developers use role="presentation" instead, which may or may not work as expected. Before I show you where it fails, let s first try to understand the difference between role="presentation" and aria-hidden="true" . aria-hidden="true" According to the spec ,…

Put aria-hidden=true on decorative SVGs

The title says it all: put aria-hidden="true" on decorative SVGs, or they ll be announced by some screen readers. <svg viewBox="0 0 39 44" aria-hidden="true"> <path d="M19.5 36.5 1.6 26.1v-3.6l16.3 9.4V1.5h3.2v30.4l16.3-9.4v3.6z"/> </svg> Similar to when you set alt="" on an img element, screen readers will ignore this SVG Without aria-hidden="true" , you get the following results: <svg viewBox="0…

aria-haspopup might not do what you think it does

To kick off my new article series, #WebAccessibilityFails, I decided to focus on a bad practice I often see in main navigations during accessibility audits. Developers like to put aria-haspopup on buttons inside main navigations to indicate that the buttons control subnavigations. <nav> <ul> <li> <button aria-haspopup="menu">Products</button> <ul> <li><a href="#">Wood</a></li> <li><a…

A new meta tag for respecting text scaling on mobile

When you open the accessibility settings on your smartphone and increase the font size, you will immediately notice that the system font size increases. On Android, as a Firefox user, you will also notice that websites scale. As a Chrome user, you won t see any difference because Chrome doesn t respect the font size settings for web content. As an iOS user, it s the same. Comparison of Firefox,…

Introduction to the new HTML element <geolocation>

There is a new HTML element called geolocation . I checked it out and here s what I learned. The <geolocation> element The <geolocation> element provides a button that, when activated, prompts the user for permission to access their location. Originally, it was designed as a general <permission> element, but browser vendors indicated that implementing a “one-size-fits-all” element would be too…

Lowering the specificity of multiple rules at once

You probably already knew that you can use :where() to lower the specificity of a single selector, but did you know that you can achieve a similar effect on multiple rules at once? The other day, I had an Aha! moment when someone suggested something I knew existed but hadn t considered using. In my reset style sheet UA+ , I used :where() for combined selectors to keep specificity low. Here s an…

My favourite front-end and web development conferences

As someone who enjoys attending conferences, I thought it might be helpful to share a list of my favourite front-end and web development conferences. Smashing Conf 🇩🇪🇳🇱🇧🇪 I ve been attending Smashing Conf for more than 10 years now. It s obviously one of my favourite events. It s a relatively small conference, the topics focus on web development and design, the atmosphere is fantastic, and…

Better defaults for popovers

I recently added a rule to my reset style sheet UA+ that I wanted to share with you. When you add a popover to a page and open it, it looks similar to a dialog in terms of its styling. It s positioned at the center of the viewport. HTML Hypertext Markup Language (HTML) is the standard markup language for documents designed to be displayed in a web browser. That s okay, but I would argue that in…

Workshop: Deep Dive on Accessibility Testing

Once again, I’ve teamed up with my friends at Smashing Magazine 😻 to share with you everything I know about web accessibility testing! In this smashing workshop we’ll talk about automatic and manual testing, screen reader basics, Single Page Applications, Dev Tools, and more. What you will learn in this workshop Which testing tools are available and most commonly used. How to assess the…

I’m speaking at Web Day Out 2026

The first Web Day Out conference is taking place next year on March 12, my birthday, in Brighton, and I m one of eight speakers. The core idea of the event is to get you up to speed on the most powerful web platform features that you can use right now. I love that because it aligns perfectly with what I ve been working on over the last couple of years: finding ways to break old habits to get the…

Dealbreaker bugs in native popovers

One of my clients decided to write a custom popover component that uses native popovers under the hood. We built the component and were happy with it. They were about to ship it until we realised there was an accessibility bug so severe that it was a dealbreaker for us. Popovers are floating UI elements you can show or hide by pressing a button. They come with many accessibility features built in,…

What's an interactive element?

Two years ago, I wrote an article about the dialog element . I tested where focus goes when you open a modal dialog via the showModal() method. I tried different combinations of elements and attributes to see what happens because back in 2023, the behaviour was very inconsistent. In one of my tests, I put the tabindex attribute on the dialog element. That s why Joy contacted me earlier this week,…

A workaround for using custom properties in media queries

I’m a big fan of custom properties and I use them almost everywhere. One of the places where I’d love to use them, but can’t, is with media queries. I came up with a workaround and wrote about it on Piccalilli . Here s a sneak peek: @property --inline-size-s { syntax: "<length-percentage>"; inherits: true; initial-value: 100vi; } :root { --breakpoint-s: 48em; --inline-size-s:…

Never lose a z-index battle again

Recently, I learned about numeric keywords . Since I was terrible in school, I didn t know what to do with them, but when I saw infinity , I immediately thought of a great use case. According to the spec , the infinity keyword in the calc() function can be used to indicate the largest possible value of something since an infinite value gets clamped to the allowed range. For example, you can set an…

Breaking up with my X

About 2.5 years ago, I was banned from Twitter for no apparent reason. I wrote about it on this blog and described the events and personal consequences. I broke the rules. Your account is permanently suspended Restart When I was first shadow-banned and then permanently banned, I tried a couple of times to contact Twitter support and get my account back, but I wasn t successful. The problem was…

Close requests, close watchers, and the dialog element

The latest version of Chrome (134) comes with a new light-dismiss behavior for the dialog element, which enables a native click-outside feature. That s fantastic! Reading the announcement, I wondered how many ways there are to close a dialog element. The specification states that a user can send a close request to the user agent, indicating that the user wishes to close something currently being…

How to make LibreWolf your default browser on macOS

I recently switched to LibreWolf as my default browser, and I also wanted links to open by default inside it, but there isn t an option in LibreWolf like in other browsers. Luckily, there s another way. At least I found a solution for macOS: Click the Apple menu  in the corner of your screen. Select System settings . Select Desktop & Dock . Scroll down a bit. Under Widgets you can select your…

Maybe don't use custom properties in shorthand properties

I ve already written about how the fact that the initial value of a custom property is a guaranteed-invalid value can lead to unexpected results. Today, I realized how that can be problematic when you use custom properties in shorthand properties. A quick recap When you set a valid value for a property followed by another declaration with an invalid value, the second declaration will be ignored.…

#unplugtrump

Since Trump took office on Jan. 20 this year, he and his henchman have done many things that bewildered me. I assume that most of you are following the news, so you know what I’m talking about, but here are some things I found especially cruel and disgusting. Terminated diversity, equity, and inclusion programs across the federal government Granted clemency to everyone charged in connection with…

Is the button focusable?

Let’s play a game. I’ll hide a button using different techniques in HTML and CSS, and you have to guess whether it’s still focusable. That s our button. <div> <button> Catch me if you can </button> </div> Now, let s hide it. CSS First, we’ll use CSS to hide the button visually. We aim to ensure the button isn’t focusable when it’s not visible. So, if the answer to the question “Is the button…

NVDA bug: anchor links broken if they point to a parent element

In my last blog post , I explained how to create a back-to-top button that visually indicates the scroll position. I tested it in different browsers to see if the CSS works. I didn t test with screen readers because the HTML was basic and straightforward. There wasn t anything that could go wrong, or at least I thought so. <main id="content"> <p>…</p> <a href="#content" class="back-to-top"> Back…

Building a progress-indicating scroll-to-top button in HTML and CSS

I noticed a nice detail on theneedledrop.com . They have a square scroll-to-top button with an arrow pointing right. The button s border is black, and the background color is white. When you scroll, the arrow points up, and the background color turns gradually yellow as you scroll. That s nothing too special, but it caught my attention because it looks nice and I realized we can build this without…

Debugging a Craft CMS installation on macOS

The other day, I tried to install Craft CMS 5 on my Macbook, and I had some issues with my setup. I followed the first two steps in the installation guide , and everything worked fine. mkdir my-craft-project cd my-craft-project/ ddev config --project-type=craftcms --docroot=web After running the next command, I got an error that confused me because it seemed like nothing I could influence. ddev…

A year in review: 2024

2024 was our first year with three kids, and what a year that was. Personal Life with three kids is different in many ways, but most importantly, it s awesome. I love my little daughters so much, and I enjoy every day with my family. Okay, maybe not every day because when they re all sick at the same time, fuck me, that s exhausting. Generally, we don t get much sleep, but that extra load when…

A year in review: 2023

No, that s not a typo. I m writing my year-in-review post for 2023 in 2025. It s not like 2023 was terrible, but it was intense, and I needed some distance before I could write about it, and then I just forgot to do it. Before I can write about 2024, I have to do 2023 first. So, here we go: Personal We moved to Graz in late 2022, and after more than a year, we re still happy here. We love the flat…

Website accessibility reaction videos (in German)

Recently, I started a new project. I react to the accessibility of more or less randomly picked websites. Before you get too excited, It s in German. I feel more comfortable recording live reactions to websites I have never seen in my native language. However, I may try it in English if there s demand. So far, I ve recorded four videos: Wie barrierefrei ist gruene.at? Wie barrierefrei ist fpoe.at?…

TYPO3Camp Vienna: Talk and Workshop

Friends of mine organise the seventh international TYPO3Camp, which takes place in Vienna on October 11th - 13th, 2024. I m there to give a keynote talk and a workshop. Date October 11th - 13th, 2024 Website typo3camp.at Price for the event Starting at 94.87 Euro Price for the workshop 690.00 Euro As you ve probably already guessed, the talk and the workshop are about accessibility. Here are some…

Workshop: Deep Dive on Accessibility Testing

Once again, I’ve teamed up with my friends at Smashing Magazine 😻 to share with you everything I know about web accessibility testing! In this smashing workshop we’ll talk about automatic and manual testing, screen reader basics, Single Page Applications, Dev Tools, and more. Sounds interesting? Great! Here are some more details about the workshop: Sorry, your browser doesn t support embedded…

Day 109: the animation-composition property

CSS animations can be composited in three ways: replace , add , and accumulate . The animation-composition property allows you to switch between them. div { animation: changeColor 1s forwards; animation-composition: add; } Let s say you have two color HEX values, #112233 and #224466 . Here s what happens with each composition type when you animate the background color of an element from the first…

Day 110: animating properties

Several posts in the series are not about modern CSS but CSS basics. I had to write those to truly understand some fundamentals of the language before I could write about new properties. This post is one of them. I knew there are properties you can and cannot animate, but I didn t understand the nuances. So, here we go: Animation types Unless otherwise specified, all CSS properties are animatable.…

Day 108: the of S syntax in :nth-child()

You can use the of S syntax in the :nth-child() pseudo-class to filter elements before the arguments in :nth-child() apply. The S in of S stands for a forgiving selector list. /* :nth-child(An+B [of S]?) */ tr:nth-child(even of .visible, .active) { } Let s say you have six list items and want to highlight every second item, but two of them are hidden. HTML <ol> <li>Element 1</li> <li…

Day 107: the light-dark() color function

The light-dark() color function allows you to define two values for a color property. The property uses the first value when the color scheme is light or unknown and the second when it s dark. For the function to work, you must define the available color schemes for the element. Apply it to the html element if you want it to work on the entire page. html { --black: oklch(0% 0 0); --white:…

beyond tellerrand: One of my favourite web development and design conferences

People often ask me for recommendations for front-end development conferences. Picking my Top 3 would be challenging, but I know that beyond tellerrand in Germany is one of them. Location in Düsseldorf Web developers love the beyond tellerrand conference (BTConf) , although the event isn t a typical web dev conf. The organizer, Marc Thiele, a lovely and special person, has a strong web dev…

My CSS wish list 2024

Following last year , I created a CSS wishlist for 2024. Before I get into the details, I have to say that creating a wishlist almost feels wrong because there are more features in CSS today than I could have ever wished for. So, I d like to take this opportunity to thank everyone who contributed to CSS being where it is today: spec writers, invited experts, browser developers, everyone involved…

Workshop: Deep Dive on Accessibility Testing

Once again, I’ve teamed up with my friends at Smashing Magazine 😻 to share with you everything I know about web accessibility testing! In this smashing workshop we’ll talk about automatic and manual testing, screen reader basics, Single Page Applications, Dev Tools, and more. Sounds interesting? Great! Here are some more details about the workshop: Sorry, your browser doesn t support embedded…

Not all automated testing tools support Shadow DOM in web components

There isn t much more to say; it s all in the title. Many automated testing tools are a collection of JavaScript functions you run on a page. Most of those rely on querying the DOM. If a tool doesn t consider shadow trees, it only catches accessibility errors in the Light DOM, which may give you a wrong sense of safety and potentially affect your users. That s one more reason not to rely on…

Day 106: the scripting media feature

The scripting media feature is an excellent addition to CSS for those who believe in progressive enhancement: It enables you to detect whether scripting languages, such as JavaScript, are supported. If you disable Javascript in Firefox 117+, Chrome 120+, or Safari 17+ on this page, the disclosure widget below hides the button and displays the content instead. Show details Detailed content goes…

Day 105: defining multiple syntax components

As already explained on day 84 , using the syntax descriptor, you can define the type of a custom property in an @property at-rule. @property --lh { syntax: <number> ; inherits: false; initial-value: 1; } button { --lh: 1; line-height: var(--lh); transition: --lh 1s; width: min-content; } button:is(:focus-visible,:hover) { --lh: 2; } Hello World That works well, but some properties, like…

Removing list styles without affecting semantics.

Some people, I guess primarily developers and not actual users, don’t like the fact that Safari removes list semantics of lists that don’t look like lists ( list-style: none ). Scott O’Hara provided a fix in “Fixing” Lists , where he suggests setting role="list" explicitly on the list to re-add list semantics. <ul style="list-style: none" role="list"> <li>…</li> </ul> That works, but I found a way…

Totally remdom, or How browsers zoom text

Last week, I lied to my students. After I explained how the rem unit worked, I told them that they could compare px and rem by increasing the font size in their mobile browsers and see how it affects text zoom. Before I said that, we created a simple test page with two paragraphs and two rules. HTML <p class="px">Hello World!</p> <p class="rem">Hello World!</p> CSS .px { font-size: 16px; } .rem {…

Day 104: animation with registered custom properties

All major browsers except Firefox (coming soon!) support the @property at-rule . It enables you to do things you previously couldn t, like animating custom properties. Let s say you have two animations. One fades an element; the other moves it. Based on their motion preference, users see one or the other. .banner { --animation: fade; animation: var(--animation) 3s cubic-bezier(0.18, 0.89, 0.32,…