Manuel Matuzović - Blog

My Blog about accessibility, performance, and CSS architecture and layout.
https://www.matuzo.at/blog (RSS)
visit blog
Website accessibility reaction videos (in German)
19 Sept 2024 | original ↗

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...

TYPO3Camp Vienna: Talk and Workshop
19 Sept 2024 | original ↗

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...

Workshop: Deep Dive on Accessibility Testing
4 Sept 2024 | original ↗

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...

Day 109: the animation-composition property
21 Aug 2024 | original ↗

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...

Day 108: the of S syntax in :nth-child()
25 Jul 2024 | original ↗

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...

Day 107: the light-dark() color function
19 Jul 2024 | original ↗

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...

beyond tellerrand: One of my favourite web development and design conferences
18 Apr 2024 | original ↗

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...

My CSS wish list 2024
11 Jan 2024 | original ↗

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,...

Workshop: Deep Dive on Accessibility Testing
2 Jan 2024 | original ↗

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...

Not all automated testing tools support Shadow DOM in web components
2 Jan 2024 | original ↗

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...

Day 106: the scripting media feature
13 Nov 2023 | original ↗

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...

Day 105: defining multiple syntax components
10 Nov 2023 | original ↗

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: ''; 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; }...

Removing list styles without affecting semantics.
6 Nov 2023 | original ↗

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. … That works, but I found a way of...

Totally remdom, or How browsers zoom text
3 Nov 2023 | original ↗

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 Hello World! Hello World! CSS .px { ...

Day 104: animation with registered custom properties
2 Nov 2023 | original ↗

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 { background: #000; ...

Day 103: the prefers-reduced-transparency media feature
1 Nov 2023 | original ↗

Design trends like Glassmorphism use translucent backgrounds to create a specific visual effect, resulting in underlying background colors or elements shimmering through the background of the overlaying element. That may be visually appealing, but it can distract some people and impair legibility.Operating systems like macOS and Windows offer...

Skip links on ikea.com
11 Oct 2023 | original ↗

I am always pleasantly surprised when I find useful skip links. That's why I decided to collect examples here on my blog.I'll start with ikea.com. The first focusable element on every page is a skip link that allows you to skip the entire header, which makes sense because there are 15 interactive elements in it. Sidenote: I'm not sure why they...

Mark all as read
5 Oct 2023 | original ↗

I was on the train home from Hamburg when I decided to finally migrate my website from Netlify and 11ty to Kirby on my friend's server. I got most of the work done on the train and made some final changes on Monday.There's a lot you should consider when migrating from one tech stack to another. I didn't. I yoloed it, uploaded the site, and...

Web Components Accessibility FAQ
7 Sept 2023 | original ↗

I specialize in HTML and CSS, but I also write JS. Especially in the last year or so, I wrote quite a lot of JavaScript because we decided to port the front end of one of my clients to web components. When I first learned about web components, I had a lot of questions, especially regarding accessibility. While I found answers to many of them, I...

New workshop: Advanced Modern CSS Masterclass
5 Sept 2023 | original ↗

In my newest workshop I introduce you to the most useful modern features in CSS and show how you can implement them today in your code base to improve scalability, maintainability, and productivity.About the workshop clamp(), :is(), :where(), min(), max(), lab(), lch(), oklab(), oklch(), cascade layers, container queries, logical properties,...

Day 102: selecting the scoping root
1 Sept 2023 | original ↗

There are different ways of selecting the scoping root inside a @scope rule.When you use the :scope pseudo-class in a stylesheet, it matches the :root element. :root { border: 10px solid red; } :scope { border-color: blue; } /* -> 10px blue border on the element */ When you use it inside a scope rule, it matches the rule's scoping...

Pros and cons of using Shadow DOM and style encapsulation
23 Aug 2023 | original ↗

When I started to work with web components, I compared different options and decided to go with lit. I knew the extra performance cost would pay off quickly, and it fit into my performance budget. I’m still happy with my decision. .pro { color: green; } .con { color: red; } I was new to web components and lit, so I had to consult...

aria-haspopup and screen readers
17 Aug 2023 | original ↗

I read Steve Faulkners “hasPopup hasPoop” where he mentions differences in what screen readers announce when dealing with the aria-haspopup attribute. I wanted to know how that manifests used on a button. table { table-layout: fixed; white-space: nowrap; } tbody td { background: green; color: #fff; } tbody th { ...

Visually hidden links with 0 dimensions
19 Jul 2023 | original ↗

If you have used a visually-hidden class in the past, you might have noticed that the width and height is set to 1px and not 0. I’ve always wondered why. Even in James Edwards’ “The anatomy of visually-hidden” I didn’t find the answer because he wasn’t sure either. While testing a client’s site a few minutes ago, I found at least one good reason....

O dialog focus, where art thou?
17 Jul 2023 | original ↗

Here’s a job interview question for you: When you click a button and call the showModal() method to open a modal , where does the focus go by default, and how can you move it elsewhere?Don't know the answer? Neither did I, so I tested it. OS/Browsers macOs 13.4.1 Ventura Chrome 114 Firefox 115 Safari 16.5.1 Here’s a Codepen with all demos so you...

the article element and screen readers
4 Jul 2023 | original ↗

I wanted to know how and if common screen readers expose the element. Here are my results:Summary tl;dr: shit's complicated. Some screen readers don't announce articles and have no default quick nav shortcuts. Some don't announce them but treat them as landmarks. Others announce them as articles and treat them as landmarks. There's no difference...

the details element and in-page search
30 Jun 2023 | original ↗

An important factor in terms of UX and accessibility for deciding whether the element is the right solution for a problem is the find-in-page behaviour.In Chromium-based browsers, the details element automatically opens when it contains a string the user searches for. If Safari and Firefox, it has to be opened for the find-in-page feature to...

form and search landmarks
28 Jun 2023 | original ↗

I wanted to know how well common screen readers and browsers support search and form landmarks. Here are my results: table { table-layout: fixed; white-space: nowrap; } tbody td { background: green; color: #fff; } tbody th { font-weight: normal; /* position: sticky; left: 0;*/ } td.no { background:...

Cascade Layers are useless*
21 Jun 2023 | original ↗

*if you don‘t understand the problems they solve and use them in combination with other solutions that tackle the same challenges albeit less elegantly and with the downside of limiting you in taking full advantage of selectors, one of the coolest features in CSS, and if you ignore the fact that they can help you organise and manage your own and...

Day 101: scoping
16 Jun 2023 | original ↗

Similar to container queries or cascade layers, we have another new impactful feature in CSS: scoping.Let's start nice and easy by reading the spec. A scope is a subtree or fragment of a document, which can be used by selectors for more targeted matching. More targeted matching sounds great. We can use the @scope rule to scope styles of a child...

Syntax podcast episode 623: “Nothing in CSS” errata
12 Jun 2023 | original ↗

I just listened to the Syntax podcast for the first time because they were discussing topics near and dear to my heart, HTML and CSS. The episode is called “Nothing in CSS - 0 vs 0px, no, none, hidden, initial and unset”, and they’re talking about all the things that can be 0, none, or hidden in CSS and HTML. Super interesting stuff, but...

CSS! CSS! CSS!
11 Jun 2023 | original ↗

I just came home after three beautiful days in Amsterdam, where I gave a talk at the CSS Day conference. I’ve watched many inspirational and engaging presentations and had many interesting conversations. My biggest takeaway: The CSS community needs you!First things first: CSS Day is a wonderful event, and the community is lovely. If you can,...

Deleted files in a freshly cloned git repo
29 May 2023 | original ↗

The other day someone emailed me and told me that they tried to clone the HTMHell repo, but they only got an empty folder (except for the hidden .git folder), and all files were deleted as if they cloned the repo and immediately moved all files into the trash. li { margin: 0 !important; } I couldn't reproduce the issue on my Mac, but I...

Workshop: Deep Dive on Accessibility Testing
23 May 2023 | original ↗

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...

details/summary inconsistencies
21 Apr 2023 | original ↗

Scott O'Hara wrote a fantastic blog post about the details and summary elements last year. He explains that there are a lot of oddities and inconsistencies, and he backs his statements with detailed testing.To better understand the extent of these oddities and inconsistencies, I did my own testing (not as detailed as Scott's), and here's what I...

Invalid at computed-value time
18 Apr 2023 | original ↗

I rewatched Lea Verous’s talk about custom properties recently and learned something I missed the first time I watched it.A declaration of a custom property can be invalid at computed-value time, if its value is invalid. Depending on the property’s type, this results in the property being set to unset, so either the property’s inherited value or...

It's very likely that…
17 Apr 2023 | original ↗

I repeatedly see certain bad practices in HTML that ironically contain clues for implementing them properly in their class names or in the way they're built. In this evergreen post, I collect them.…if you're using javascript:void(0) as the value of the href attribute, the element you're actually looking for is . Open modal More accessible...

50.1% empty links
4 Mar 2023 | original ↗

The new WebAim 1 Million report was recently published, and the results are sobering. Compared to the previous year, 0.5% fewer websites contained automatically detectable accessibility issues, but the total number of erroneous websites is still 96.3%.The number of empty links increased by 0.4% from 49.7% to 50.1%. More than half of the websites...

My CSS wish list
14 Feb 2023 | original ↗

I know I’m late to the party, but there are a few things on my CSS wish list I haven’t seen on others, so I thought I’d share.Visually hidden content I'd love to see a native implementation of visually hidden text. I’m not the biggest fan of hiding stuff only for some, but it’s inevitable sometimes. Instead of this: .visually-hidden { ...

Day 100: it's over, or is it!?
10 Feb 2023 | original ↗

OMG, I did it, day 100! 4 months and 16 days ago I published the first post and then I wrote another post every workday for 138 days straight without missing a single day. In this final post, I want to do a quick recap and give an outlook for what's coming next.Recap Starting this project was one of the best and worst ideas I ever had. It was a...

Why I'm not the biggest fan of Single Page Applications
10 Feb 2023 | original ↗

Sometimes it seems like accessibility experts and other web professionals hate JavaScript. This might be true for some, but most understand that JavaScript can be useful for improving UX and even accessibility. JavaScript solutions are often more accessible than their pure HTML or CSS counterparts.We know JavaScript is not an enemy, but,...

Day 99: native nesting
9 Feb 2023 | original ↗

Nesting in CSS is coming soon! For me personally not the killer feature, at least compared to cascade layers or container queries, but still exciting. Let’s see how it works.The most important thing to know about native nesting in CSS is that the nested selector always must start with a symbol (. # : [ * + > ~) because of limitations in browser...

Day 98: oklab() and oklch()
8 Feb 2023 | original ↗

oklab() and oklch() are okay versions of lab() and lch() because lab() and lch() are not okay.I will not pretend that I really understand this whole color on the web thing, how it works or why one color function offers many more options to developers than the other, but I did learn several things during this experiment. I understand why a color...

Day 97: animating grids
7 Feb 2023 | original ↗

It’s possible to animate gap, grid-template-columns, and grid-template-rows.Almost 6 years ago I wrote a blog post on CodePen titled “Animating CSS Grid Layout properties”. A lot has changed since then, especially recently, and I wanted to update the post, but the blogging feature on CodePen has been sunset and I can’t edit the post anymore....

Day 96: the margin-trim property
6 Feb 2023 | original ↗

The margin-trim property allows a container element to trim the margins of its children where they adjoin the container’s edges.Let’s say we have a parent element and 4 children, and we use margin-block-end to add some spacing between these elements. A B C D li { margin-block-end: 1rem; } [data-sample] ul { list-style: none; ...

Day 95: the color-mix() function
3 Feb 2023 | original ↗

The color-mix() function takes two colors and returns the result of mixing them, in a given color space, by a specified amount.To mix colors, pass the in keyword, followed by the color space, and 2 colors. body { background-color: color-mix(in srgb, blue, white); } The syntax is pretty straightforward, but the result is not so much. At least...

Day 94: the accent-color property
2 Feb 2023 | original ↗

The accent-color CSS property allows us to specify the accent color for user-interface controls generated by an element.Yeah, I know, yet another property that isn’t new at all, but Safari added support only recently (in 15.4) and I’ve never used it. Reason enough for me to include it in the series. We can use the property to change the accent...

Day 93: the lch() color function
1 Feb 2023 | original ↗

The lch() color function allows you to pick colors from the CIELAB color space, which is device-independant and covers the entire gamut (range) of human color perception.Currently, the CSS colors we can define are in the sRGB color space. For the longest time, professional monitors weren’t able to display all possible colors in this range. So,...

Day 92: relative color syntax
31 Jan 2023 | original ↗

With the relative color syntax we can modify existing colors using color functions. If an origin color is specified, each color channel can either be directly specified, or taken from the origin color and modified.For example, we can take a HEX color and add opacity using the rgb() color function and the from keyword. [data-sample] div { ...

Day 91: a previous sibling selector with :has()
30 Jan 2023 | original ↗

I’ve already shown much appreciation for the :has() pseudo-class in this series, but that we can use it as a previous sibling selector tops it all of.Since this is not an official selector, but more something like a hack, it can be hard to read and interpret. So, let’s start nice and easy. We have three buttons. If we hover/focus one button and...

Day 90: scoped styles in container queries
27 Jan 2023 | original ↗

Rules within a container query only apply to descendants of that container.If you write a media query and you put rules in the media block, the rules apply to the entire document. Apply rules @media (min-width: 1024px) { * { outline: 4px solid } } @media (min-width: 1024px) { .demo1, .demo1 * { outline: 4px solid } } .demo4...

Day 89: higher-order custom properties
26 Jan 2023 | original ↗

Style queries may change the way we write CSS significantly. Caution: If you’re a fan of Tailwind or similar utility frameworks, you might find this post offensive because it suggests using fewer classes instead of more. On day 80 I’ve introduced you to container style queries. I’ve showed you a practical example from a project I was working on...

Day 88: CSS Motion Path
25 Jan 2023 | original ↗

CSS Motion path allows you to position any graphical object and animate it along a specified path. .square { background: hsl(93deg 75% 49%); height: 2em; width: 2em; position: absolute; inset-inline-start: 0; inset-block-start: 0; } .sample2 .square { offset-path: path("m4,139c0,-1.31731 7.78207,-137...

Day 87: mask properties
24 Jan 2023 | original ↗

You can use mask properties to apply a mask to an element. .post img { border: none; } .mask { -webkit-mask-image: url(/blog/2023/100daysof-day87/htmhell_logo.svg); mask-image: url(/blog/2023/100daysof-day87/htmhell_logo.svg); } .mask-size { -webkit-mask-size: contain; mask-size: contain; -webkit-mask-repeat:...

Day 86: the initial-letter property
23 Jan 2023 | original ↗

The initial-letter property specifies size and sink for initial letters.@supports (-webkit-initial-letter: 1) or (initial-letter: 1) { p::first-letter { -webkit-initial-letter: 3; initial-letter: 3; } } The property takes two arguments. The first one defines the size of the initial letter in terms of how many lines it occupies. The...

Day 85: typed custom properties in container style queries
20 Jan 2023 | original ↗

Registering typed custom properties can be useful in container style queries.The following container style query matches because the computed value of both --bg and --color is “red”. html { --color: red; } .card { --bg: red; } /* Condition is true, styles applied */ @container style(--bg: var(--keyword)) { h1 { border: 10px dotted...

Day 84: the @property at-rule
19 Jan 2023 | original ↗

The @property rule allows you to register custom properties.You can already define custom properties, but the difference between defining and registering is that the at-rule allows you to specify the type and other attributes. @property --hue { /* The type. */ syntax: ''; /* Is it an inhertiable property? */ inherits: false; /* The...

Day 83: computed values in container style queries
18 Jan 2023 | original ↗

On day 80, I’ve explained that we can check whether a container has a specific property and value assigned and apply additional styles based on this condition. On day 82, I’ve explained that the value of a property can come from different sources, undergo adjustments before it becomes the actual value, and take on different forms along the way....

Day 82: value processing
17 Jan 2023 | original ↗

This post differs from most of the other posts because it’s not about modern CSS, but about CSS fundamentals. When I was writing about custom properties and especially about container style queries, I realized that I had to understand some of the basics of the language first before I could comprehend how certain properties and rules worked.The...

Day 81: the order of individual transform properties
16 Jan 2023 | original ↗

On day 66, I’ve introduced you to individual transform properties. An interesting detail about these properties is the order in which transforms are applied compared to the transform property.If you use the transform property, transformation functions are applied in the order of appearance, from left to right. .button1 { transform:...

Day 80: container style queries
13 Jan 2023 | original ↗

Container style queries allow querying the computed values of a query container.No browser supports it yet, but we should be able to do something like this: .card { aspect-ratio: 1 / 1; } .card--wide { aspect-ratio: 16 / 9 } @container style(aspect-ratio: 16 / 9) { img { object-fit: cover; } } We can check whether a container has a...

Day 79: font-tech() and font-format()
12 Jan 2023 | original ↗

You can use the @supports rule to check whether a browser supports a specified font technology or font format.font-tech() @supports font-tech(palettes) { .palette { display: block; } } @supports not font-tech(incremental) { .incremental { display: block; } } @supports font-format(woff2) { .woff { ...

CSS color functions and custom properties
12 Jan 2023 | original ↗

I know I’m really late to the party, but I finally understood why people find color functions like hsl(), hwb(), or lab() so appealing.There are many reasons, but one of them is that in combination with custom properties, working with color functions is so much easier, cleaner, and understandable compared to working with hex colors or rbg()....

Day 78: container query units
11 Jan 2023 | original ↗

Container queries come with their own units. [data-sample] div { outline: 10px solid; overflow: auto; margin: 1rem; } .sample2 div { container-type: inline-size; } [data-sample] h2 { background-color: yellow; border: 5px solid; padding: 1rem; margin: 1rem; inline-size: 80cqi; } Container query units...

Day 77: block-size, inline-size, vi, and vb
10 Jan 2023 | original ↗

There are logical properties for width and height values.width and height The logical alternative for width is inline-size and the alternative for height is block-size. Here’s an example of how using inline-size over width makes a difference. [data-sample] h1 { border: 1rem solid; padding: 1rem; } [data-sample] h1:not(:last-child)...

Day 76: overwriting colors in font palettes
9 Jan 2023 | original ↗

You can use the override-colors property to override colors in a font palette.Color fonts come with one or more predefined color palettes. You can select them by using the font-palette property. You can also define your own color palettes or change specific colors in a palette using the override-colors property. @font-face { font-family:...

Day 75: font palettes
6 Jan 2023 | original ↗

Apparently, multicolored typefaces on the web are a thing. You can use and modify them in CSS. @font-face { font-family: 'Rocher'; src: url('/blog/2023/100daysof-day76/RocherColorGX.woff2'); } @font-palette-values --pink { font-family: 'Rocher'; base-palette: 1; } @font-palette-values --green { font-family: 'Rocher'; base-palette: 2;...

Day 74: using !important in cascade layers
5 Jan 2023 | original ↗

In order to understand how !important works in cascade layers, you have to understand how !important works generally. The conclusion of this post might not be what you expect. .sample1 h1 { color: green; } .sample1 h1 { color: red; } .sample2 h1 { color: green !important; } .sample2 h1 { color: red; } @layer base...

Day 73: size container features
4 Jan 2023 | original ↗

In my previous posts about size container features I’ve only used the min-width feature, but there’s actually more you can query.container-type: inline-size establishes size containment only on the inline axis. There is no block-size option because it wasn’t possible for browsers to implement, but there is a size option, which establishes size...

Day 72: the masonry-auto-flow property
3 Jan 2023 | original ↗

If you’re creating a masonry layout, the packing algorithm puts items into the column with the most space by default. This can cause accessibility issues. The masonry-auto-flow property gives us control over the automatic placement of items in a masonry layout.In the following layout, you can see how the tile for “Day 63” is placed in the middle...

A year in review: 2022
3 Jan 2023 | original ↗

I started my last year in review post with the words “2021 was wild!”. If 2021 was wild, then I don’t know what 2022 was because so much stuff was going on last year.Personal Our daughter was born in 2021, and suddenly she’s 19 months old. It’s killing me how fast time flies. It’s still amazing to watch her grow and learn new things. Looking at...

Day 71: the masonry keyword
2 Jan 2023 | original ↗

The masonry keyword allows you to create masonry grid layouts.If you want to create a masonry layout, all you have to do is turn one of the grid axes into a masonry axis using the masonry keyword. Day 70: the defined pseudo-class Day 69: width in container queries Day 68: cascade layers...

Day 70: the defined pseudo-class
30 Dec 2022 | original ↗

:defined represents any element that has been defined. This includes standard elements and custom elements that have been successfully defined. [data-sample] :defined { background-color: #000; color: #fff; } class BasicComponent extends HTMLElement { constructor() { super(); } } customElements.define('de-fined', BasicComponent);...

Day 69: width in container queries
29 Dec 2022 | original ↗

In a media query, it’s obvious what width means. It always refers to the width of the viewport. With size container queries it’s not that obvious./* Kicks in when the viewport has a minimum width of 500px */ @media (min-width: 500px) { body { background-color: hotpink; } } width in a size container query queries the width of the...

Day 68: cascade layers and browser support
28 Dec 2022 | original ↗

Cascade layers are one of the most interesting and useful additions to CSS recently. It will change the way we write CSS, how we use selectors, naming conventions, and probably also more things that I can’t think of right now.If you’re as excited about using cascade layers as I am, you have to consider browser support before you get started....

Day 67: counting children
27 Dec 2022 | original ↗

There are a lot of interesting things you can do with the :has() pseudo-class. I’ve already covered some of them on day 26.If you want to style an element based on the number of direct children it has, you can do that with just CSS. Let's say you want to style a list in a certain way when it contains at least three items. You use the :has()...

Day 66: individual transform properties
26 Dec 2022 | original ↗

From now on you can transform elements with the translate, rotate, and scale properties.Let’s say you apply several transforms to an element, and on :hover and :focus you only want to change one of them, for example, scale. Transform button { transform: translateX(20px) rotate(15deg) scale(1); } button:is(:hover, :focus) { transform:...

Day 65: using the em unit in container queries
23 Dec 2022 | original ↗

Relative units used in container queries work differently than relative units in media queries.If you use em in a media query, the font-size of the , , or any other element on the page doesn't matter. That's because relative length units in media queries are based on the initial value, which means that units are never based on results of...

Day 64: the revert-layer keyword
22 Dec 2022 | original ↗

With cascade layers comes a new CSS-wide property value, revert-layer.You can use the revert-layer keyword to roll back the cascade to a value defined in a previous layer. In the following example, the base layer defines a black color for the border. The theme layer sets the border color to fuchsia. In a print media query within the theme layer...

Day 63: explicit defaulting with inherit, initial, unset, and revert
21 Dec 2022 | original ↗

There are several CSS-wide property values you can use to specify a particular defaulting behavior for a property explicitly.Okay, okay, I know, these keywords aren't new at all, except for revert maybe which is newish, but if I want to write about revert-layer, which is brand new, I need a basic understanding of all keywords. Also, I had the...

Day 62: the container shorthand
20 Dec 2022 | original ↗

On day 56 you've learned that you have to define a container-type when working with size containers and on day 59 you've learned that you can name containers using the container-name property.The container shorthand allows you to define both properties in a single property, [name] / [type]. section { container: wrapper / inline-size; /* ...

Day 61: color-scheme
19 Dec 2022 | original ↗

The color-scheme property allows you to indicate which color schemes an element can be rendered in.This post is inspired by Sara Wallén’s article “Do you know color-scheme?” in the HTMHell advent calendar 2022. Read it to learn more about the feature and other ways of using it. If you create an HTML document, it comes with default styles that are...

Day 60: the ::part() pseudo-element
16 Dec 2022 | original ↗

You can use the ::part CSS pseudo-element to style an element within a shadow tree.Let's have a look at the following web component. There's a heading and a paragraph in the shadow DOM and we can pass content via light DOM. class NewsTeasers extends HTMLElement { constructor() { super(); this.attachShadow({mode: 'open'}); ...

Day 59: naming containers
15 Dec 2022 | original ↗

When you add a container query, it will look for the nearest ancestor container, by default. If you have multiple nested containers or if you just want to make sure that your query uses the right container, you can name containers and query them specifically.Let's say, we have 2 size containers, .wrapper and . Latest news Hey,...

Day 58: ordering nested layers
14 Dec 2022 | original ↗

On day 43, we've learned how to group layers and on day 46, how to order them. In this post, we’ll look into ordering grouped layers.If we take the following layer, the background color of the will be red because the last defined layer has precedence over previously defined layers. @layer base { @layer reset { p { background-color:...

Restart
14 Dec 2022 | original ↗

Like many others, I’ve been thinking a lot about Twitter, social media in general, and what being on a social media platform means for me.The other day I logged into Twitter with my HTMHell account and I looked at the feed. It was full of opinions by “tech personalities” (men), funny tweets, and random videos. It felt like being on Reddit or...

Day 57: media queries: range syntax
13 Dec 2022 | original ↗

With CSS Media Queries Level 4, it's possible to use mathematical comparison operators in media queries.Instead of (min-width: 768px) you can now write (width >= 768px). Before @media(min-width: 768px) { body { background-color: aqua; } } After @media(width >= 768px) { body { background-color: aqua; } } Before @media(min-width:...

Day 56: container queries
12 Dec 2022 | original ↗

You can use media queries to style elements based on features of the browser viewport, for example, min-width, max-height, or orientation. With container queries, you can now do the same but with any parent element. Instead of the viewport, you can now listen to properties and features of a containing element.You can query all kinds of things,...

Day 55: anonymous layers
9 Dec 2022 | original ↗

In all previous posts about cascade layers I’ve used named layers in the demos, but it’s actually not required to name them.Using @layer without a name works just as well. The downsides are that you can’t append styles elsewhere in the document to the same layer and you can’t define a custom order since you don’t have a name to reference them....

Day 54: testing for the support of a selector
8 Dec 2022 | original ↗

Support for a CSS property isn’t the only thing you can check with @supports(), you can also check support for a selector.I knew you can check whether a property is supported by the current browser and apply styles accordingly. @supports (display: grid) { .grid { display: block } } @supports selector(:has(a)) { .has { display: block }...

Day 53: disabling pull-to-refresh
7 Dec 2022 | original ↗

On day 47, I introduced you to the overscroll-behavior property, and I showed you how to use it to disable scroll-chaining. There’s another feature we can disable using this property.In some mobile browsers, you can refresh the page by swiping down when the page is scrolled to the very top. That's called pull-to-refresh. This is a great feature,...

Day 52: declaring multiple layer lists
6 Dec 2022 | original ↗

On day 46, I’ve explained how you can order layers by defining them in a comma-separated list first. The first layer in the list has the lowest priority and the last layer the highest.@layer base, components, theme, framework; You can create as many lists as so you want, but the important thing to remember is that layers are stacked based on the...

Day 51: aspect-ratio and replaced elements
5 Dec 2022 | original ↗

Most elements have no preferred aspect ratio. On day 42 I’ve explained how you can use the aspect-ratio property to define a ratio for these elements. Replaced elements like , , , or , on the other hand, have an intrinsic aspect ratio. This means that you don’t have to define one using the aspect-ratio property and they will scale naturally. ...

Day 50: :has(:not()) vs. :not(:has())
2 Dec 2022 | original ↗

Something I was tripping over when I began learning about :has() was the combination with :not().Let me show you what I got wrong by using an example. Let's say we have two cards, each with a heading and some text. One of them also contains an image. Card with image text Card without image text .democard.card { border: 4px solid; ...

Day 49: layering entire style sheets
1 Dec 2022 | original ↗

You can use @import to load entire style sheets into a cascade layer.@import url("path/to/the/styles.css") layer(layername); For example, you could load something like Bootstrap into a dedicated third-party layer. @layer third-party, base, components, utility; @import...

Day 48: inset 0
30 Nov 2022 | original ↗

On day 9 I’ve talked about the inset shorthand properties inset, inset-inline, and inset-block. I don’t believe that I will need those often, but inset can come in handy when you want one element to fill another element entirely.If you have an outer element and an inner element and you want the inner element to fill its parent, you can use...

Day 47: the overscroll-behavior property
29 Nov 2022 | original ↗

You can use the overscroll-behavior property to disable scroll-chaining.If you scroll the inner box in the following example to the end and you keep scrolling, the outer box starts scrolling, too, and finally the whole page. .demo.outer, .demo .inner { padding: 1rem; border: 10px solid; overflow: auto; font-size: 1rem; } .demo.outer...

Day 46: ordering layers
28 Nov 2022 | original ↗

By default, cascade layers are stacked in the order they are defined, but you don’t have to rely on it. You can determine the order in one place.In the following example, the border color of the paragraph is first red, then blue, then rebeccapurple, and finally green. @layer base { p { border: 10px solid red; } } @layer framework { p...

Day 45: the specificity of ::slotted() content
25 Nov 2022 | original ↗

When you pass an element to a web component through a , you can select that element using the ::slotted() pseudo-element and apply additional styles.Let's take the following component. There's a paragraph in the shadow DOM and another paragraph coming from the light DOM, passed through a , and there's a global style turning the background color...

Day 44: logical floating and clearing
24 Nov 2022 | original ↗

Thanks to Flexbox and CSS Grid no one seems to talk about float and clear anymore,…except for me now because there's news.Floating and clearing has lost its importance for layout, but they are still useful properties. Just like for margin or border, you can now use logical properties for floating and clearing. img { float: inline-start; /* or...

Day 43: grouping layers
23 Nov 2022 | original ↗

Cascade layers can be grouped by nesting layer rules.If you work on a large style sheet, you might want to create cascade layers to group different types of declarations. In order to give your layers even more structure and control, you can also group declarations within layers. Consider the following example. We have a layer for reset styles,...

Day 42: aspect-ratio
22 Nov 2022 | original ↗

Yes, I know, aspect-ratio is not the hottest shit, but Safari only starting supporting it in version 15 and there’s a lot I didn’t know about the property. That’s reason enough for me to write about it. :)Defining ratios You can use the aspect-ratio property to define the preferred aspect ratio for a box by defining a preferred width and height....

Day 41: custom properties and url()s
21 Nov 2022 | original ↗

Let’s say you want to swap the background image of an element based on a certain condition, like whether it’s pressed, using custom properties.button { --background-image: "/not-pressed.svg"; background: url(var(--background-image)); } button[aria-pressed="true"] { --background-image: "/pressed.svg"; } This looks fine, but it doesn't work...

Day 40: unlayered styles
18 Nov 2022 | original ↗

On day 37 we learned that we can get more control over specificity by creating layers. That first, simple example is pretty straightforward, but what happens if we mix layered and unlayered styles?Let's start nice and simple with a single layer. The border of this quote is red. There's only one Return, okay, and it ain't of the king... @layer...

Day 39: comma-separated functional color notations
17 Nov 2022 | original ↗

On day 11 I've introduced you to space-separated functional color notations. Early color functions like rgb() and hsl() support both the old comma-separated and the new space-separated syntax./* ✅ works */ div { background-color: rgb(255, 210, 210); color: hsl(150, 76%, 20%); } /* ✅ works */ div { background-color: rgb(255 210 210); ...

Day 38: vh, svh, lvh, and dvh
16 Nov 2022 | original ↗

Using the viewport unit vh in desktop browsers is usually straight-forward, 100vh matches the height of the viewport. On mobile that's different because the viewport height changes depending on whether or not certain user interface elements are visible, 100vh doesn't always match the height of the viewport.On mobile we have the small viewport and...

Day 37: cascade layers
15 Nov 2022 | original ↗

Cascade layers introduce a new way of managing specificity in CSS.Let’s say we’re using a combination of a tag and an attribute selector for styling e-mail input fields. This declaration is part of our base stylesheet and comes early in the stylesheet. Later in the document, we want to use a class to overwrite parts of the base styling:...

Day 36: :has() and pseudo-elements
14 Nov 2022 | original ↗

We already know that we can select an element based on the presence of a certain child element (in Chrome/Edge 105+ and Safari 15.4+), but there are limitations. World! p:has(strong) { background-color: aqua; } .p:has(strong) { background-color: aqua; } .p2::before, .p3::before{ content: "Hello"; } .p3:has(:hover) { ...

Day 35: forgiving selectors
11 Nov 2022 | original ↗

There's a difference between listing selectors in :where(), :is(), and :has() and listing them in a regular selector list.Let's say you have a button with the class .button and you apply the following styles. .button:hover { background-color: hwb(100 0% 20%); } I'm a button .button1:hover { background-color: hwb(100 0% 20%); } ...

Day 34: :is() or :where()
10 Nov 2022 | original ↗

Thoughts on when it’s better to use :is() over :where() and vice versa.The other day, I posted this code snippet on social media, asking people whether it was readable. summary:where(:hover, :focus-visible)::after { transform: rotate(180deg); } Some people responded they prefer :is() over :where() because it’s shorter or less typing. Others...

Day 33: Mathematical expressions in min(), max(), clamp()
9 Nov 2022 | original ↗

You can use full math expressions in the comparison functions min(), max(), and clamp(). There’s no need to nest a calc() function inside.Writing… div { border: max(20px, calc(1vw + 10px)) solid; } …is the same as writing… div { border: max(20px, 1vw + 10px) solid; } You can also use custom properties. .var { --extra: 10px; border-width:...

Day 32: the clamp() function
8 Nov 2022 | original ↗

The clamp() function defines a minimum value, a preferred value, and a maximum value. .div { border: 1em solid hwb(200 0% 0%); padding: 1rem; } .minmax { width: max(300px, min(90%, 700px)); } .clamp { width: clamp(300px, 90%, 700px); } .max { width: max(300px, 90%); } .min { width: min(90%, 700px); } A quick recap of min() and max()...

Workshop: Deep Dive on Accessibility Testing
8 Nov 2022 | original ↗

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...

Day 31: logical border properties
7 Nov 2022 | original ↗

Just like for margin or padding, there are also logical property variations for border properties.Originally there were 4 shorthand properties we could use for defining borders. border - 1, 2, or 3 values (size, style, color) border-width - 1, 2, 3, or 4 size values for the different sides border-style - 1, 2, 3, or 4 style values for the...

Day 30: the hwb() color function
4 Nov 2022 | original ↗

Like the lab() color function, hwb() is one of the more recent methods for defining colors in CSS. Just like rgb() and hsl() it uses colors from the sRGB color space. HWB, which stands for hue-whiteness-blackness, describes colors with a starting hue, then a degree of whiteness and blackness to mix into that base hue.The function takes 3...

Day 29: !important custom properties
3 Nov 2022 | original ↗

Using !important with custom properties might not work as you expect.If you look at the following example, which color does the text have? .example1 { --color: red; color: var(--color) !important; color: blue; } .example2 { --color: red !important; color: var(--color); color: blue; } .example3 { --color:...

Day 28: custom properties and web components
2 Nov 2022 | original ↗

We already know that we can encapsulate styles within a web component and we know that web components inherit styles. Another interesting feature of web components in terms of CSS is that custom properties used in a web component can be modified from the outside.Let's take this basic alert component. class Alert extends HTMLElement { ...

Day 27: the font-variation-settings property
1 Nov 2022 | original ↗

Adjustable features of a variable font are called axes. You can use the font-variations-settings property to change these features by specifying the four letter axis name along with a value. @font-face { font-family: 'Saira'; font-style: normal; font-weight: 400; font-stretch: 100%; font-display: swap; src:...

Your account is permanently suspended
1 Nov 2022 | original ↗

On October 23rd I got shadowbanned on Twitter, followed by a permanent suspension on October 25th. As someone who was very active on Twitter, I was surprised, shocked, and sad that this happened. Especially because I didn’t know why it happened. Some of you might think, “Who cares, it’s just social media?!”, and yeah, you’re right, it is just...

Day 26: using combinators in :has()
31 Oct 2022 | original ↗

You already know that the :has() pseudo-class allows you to check whether a parent element contains certain children, but you can also make this selector more specific, or check other relations the element might have.Child combinators You can check whether an element contains a specific direct child element. For example, if you have a fieldset...

Day 25: scrollbar gutters in body and html
28 Oct 2022 | original ↗

When I wrote about the scrollbar-gutter property, my first thought was “omg! I'll put this in my reset stylesheet and use it on the by default”. I wanted to do that in order to prevent the page from “jumping” when switching from a long to a short page, a page with overflow to one without.Here's a quick demo to illustrate the issue. When...

Day 24: the backdrop-filter property
27 Oct 2022 | original ↗

The backdrop-filter property allows you to apply CSS filters to the area behind an element. This could be the background of an element or the backdrop of a dialog.In the following example, the parent element has a background image, nothing special about it, but the inner elements all have a backdrop-filter applied which changes how the image...

Day 23: the lab() color function
26 Oct 2022 | original ↗

The lab() color function allows you to pick colors from the CIELAB color space, which is device-independant and covers the entire gamut (range) of human color perception.Currently, the CSS colors we can define are in the sRGB color space. For the longest time, professional monitors weren’t able to display all possible colors in this range. So,...

Day 22: the ::backdrop pseudo-element
25 Oct 2022 | original ↗

You can use the ::backdrop pseudo-element to style the backdrop of modal dialogs and elements which have been placed in fullscreen mode using the Fullscreen API. ::backdrop { background-color: rgb(0 0 155 / 0.5); } .dialog2::backdrop { background: conic-gradient(red, orange, yellow, green, red); outline: 20px solid white; ...

I broke the rules.
25 Oct 2022 | original ↗

When I opened Twitter on Monday morning, I saw this: After careful review, they determined that my account broke the Twitter Rules. Okay, let's have a look at the rules to get an idea of what could've caused this ban. You break the rules if your tweets contain content related to anything in this list: Violence Terrorism/violent extremism Child...

Day 21: conic gradients
24 Oct 2022 | original ↗

You can create gradients with color transitions rotated around a center point, rather than radiating from the center, by using the conic-gradient() function.There are many options to customize conic gradients. .uno { background-image: conic-gradient(aqua, fuchsia, salmon, aqua); } .due { background-image: conic-gradient(aqua,...

Day 20: the scrollbar-gutter property
21 Oct 2022 | original ↗

The scrollbar-gutter property allows you decide whether content within an element fills the total available space or if it stops at the scrollbar gutter. The scrollbar gutter is the space between the inner border edge and the outer padding edge of an element used by the scrollbar.By default, if the content in an element is not overflowing,...

Day 19: the placeholder-shown pseudo-class
20 Oct 2022 | original ↗

You can use the :placeholder-shown pseudo-class to select input fields with a placeholder that haven't been filled out yet.input:placeholder-shown { outline: 5px solid blue; } Name E-Mail input:placeholder-shown { outline: 5px solid blue; } Name E-Mail PS: Yeah, I know, that one has been around for quite a while...

Day 18: inheritable styles and web components
19 Oct 2022 | original ↗

We already know that we can encapsulate styles within a web component by adding elements along with the styles to the shadow DOM. Global style declarations from outside don’t overwrite styles inside the web component. Shadow DOM doesn't provide total encapsulation, though.If you look at the following component, you’ll notice that it uses the same...

Day 17: the :picture-in-picture pseudo-class
18 Oct 2022 | original ↗

You can use the :picture-in-picture pseudo-class to style an element, usually a , which is currently in picture-in-picture mode (PIP).Clicking the following button puts the video in picture-in-picture mode in supporting browsers (Chrome, Edge, Safari, Opera). Firefox doesn't support the API, but you can right-click the video and select “Watch in...

Day 16: the specificity of :has()
17 Oct 2022 | original ↗

Just like with :is() and :not(), the specificity of :has() is replaced by the specificity of the most specific selector in its selector list argument. Unlike :nth-child() or :link, :has() itself doesn't add to the specificity. yo! /* A tag and a class */ div:has(.child) { background: red; } /* A tag: specificty too low */ div { background:...

Day 15: the :modal pseudo-class
14 Oct 2022 | original ↗

There are two methods you can use to open a element, show() and showModal(). show() opens a dialog on top of the rest of the content, but you can still interact with content beneath. showModal() opens a modal dialog with a backdrop on top of the rest of the content, and you can’t interact with the rest of the page.You can use the :modal...

Day 14: the difference between :is() and :where()
13 Oct 2022 | original ↗

There's an important difference between :is() and :where().Let's take the following example. We have two buttons and we use :where() on the first button to apply a background color and :is() on the second button. button { border: none; color: #fff; font: inherit; font-size: 1.2rem; padding: 0.5rem 1rem; } ...

Day 13: the :where() and :is() pseudo-classes
12 Oct 2022 | original ↗

The :where() and :is() pseudo-classes allow you to write large lists of selectors in a more compact form. You can combine selectors instead of writing repetitive lists.Combining input types /* Before */ input[type="text"], input[type="email"], input[type="url"], input[type="tel"], input[type="password"], input[type="search"] { border: 2px...

Day 12: max() trickery
11 Oct 2022 | original ↗

I saw this interesting one-liner in a demo by Temani Afif..wrapper { margin-inline: max(0px, ((100% - 64rem) / 2)); } It’s basically a shorter way of writing this: .wrapper { max-width: 64rem; margin: 0 auto; width: 100%; } It’s not up to me to decide whether it’s smart to use this in production or not, but I want to break it down to...

Day 11: space-separated functional color notations
10 Oct 2022 | original ↗

Functional color notations that existed before CSS Color Module Level 4 (rgb(), rgba(), hsl(), hsla()) used to only except comma-separated lists of arguments. That changes with Module Level 4, now you can also provide space-separated arguments. .div { width: 100px; height: 100px; } .div1 { background-color: rgb(255 0 0);} .div2 {...

Day 10: global styles and web components
7 Oct 2022 | original ↗

I was wondering what happens with HTML elements in web components when I add styles to the document. Under which circumstances do global styles defined in a style element or external stylesheet apply to these elements?As it turns out, it depends on how you create and use the components. In my test setup I have an HTML document, a stylesheet and...

Day 9: the inset shorthand property
6 Oct 2022 | original ↗

The inset property is a shorthand for the top, right, bottom, and/or left properties. It implements the same multi-value syntax like margin. At bottom right with 20px offset .parent { width: 12rem; height: 12rem; position: relative; } .child { position: absolute; /* top: auto; right: 20px; bottom: 20px; left: auto */ inset:...

Day 8: nesting :has()
5 Oct 2022 | original ↗

The :has() pseudo-class cannot be nested; :has() is not valid within :has(). I have a red and blue border in supporting browsers. /* valid */ div:has(p) { border: 4px solid red; } /* valid */ p:has(strong) { border: 4px solid blue; } /* invalid */ div:has(p:has(strong)) { border: 4px solid green; } .div:has(p) { border: 4px...

Day 7: subgrids
4 Oct 2022 | original ↗

Subgrid allows a grid-item with its own grid to align with its parent grid (currently only in Firefox 71+ and Safari 16+).In the following example, the div elements use the grid defined in the dl element. The result is that all the dt and dd elements are aligned in the same “columns” respectively, even though they’re not on the same level in the...

Day 6: the :has() pseudo-class
3 Oct 2022 | original ↗

:has() allows you to check whether a parent element contains specific children.In the following example, each .form-item that contains/has a child with the aria-invalid attribute set to “true” displays text in red color. (currently only in Chrome/Edge 105+ and Safari 15.4+) .form-item { --color: #000; color: var(--color); } input { border:...

Day 5: the max() function
30 Sept 2022 | original ↗

The max() function takes a comma separated list of expressions. The largest value in the list will be selected.div { width: max(400px, 200px, 300px); /* width = 400px */ } This example doesn’t make much sense because the value will always be 400px. max() shows its true power when you use relative units. div { width: max(300px, 50vw); } If...

Day 4: the min() function
29 Sept 2022 | original ↗

The min() function takes a comma separated list of expressions. The smallest value in the list will be selected.div { width: min(400px, 200px, 300px); /* width = 200px */ } This example doesn’t make much sense because the value will always be 200px. min() shows its true power when you use relative units. div { width: min(100%, 800px); } If...

Day 3: logical property shorthands
28 Sept 2022 | original ↗

If you use a shorthand property like margin with all 4 values, the properties will always be applied in the direction top - right - bottom - left, no matter the reading direction.Physical margin Physical margin rtl button { margin: 20px 40px 10px 100px; } /* LTR: 20px 40px 10px 100px RTL: 20px 40px 10px 100px */ .physical { margin: 20px 40px...

Day 2: logical properties
27 Sept 2022 | original ↗

Logical properties are a new way of working with directions and dimensions, one that allows you to control layout through logical, rather than physical mappings. This is especially useful, if you’re dealing with websites that are presented in different languages and writing modes, like right-to-left.Physical properties We're used to working with...

100 Days Of More Or Less Modern CSS
26 Sept 2022 | original ↗

It’s time to get me up to speed with modern CSS. There’s so much new in CSS that I know too little about. To change that I’ve started #100DaysOfMoreOrLessModernCSS. Why more or less modern CSS? Because some topics will be about cutting-edge features, while other stuff has been around for quite a while already, but I just have little to no...

Day 1: custom properties and fallbacks
26 Sept 2022 | original ↗

You can pass a second value to the var() CSS function which acts as a fallback for when the property has not been set.Fallbacks .demo { width: 5rem; height: 5rem; border: 5px solid; } .one { background-color: var(--not-set, #000); } .two { background-color: var(--not-set, var(--also-not-set, #00F)); } .three { background-color:...

Buttons and the Baader–Meinhof phenomenon
15 Sept 2022 | original ↗

Shortly after we got our new car, a Volkswagen T5, I noticed many people seemed to have the same car. Actually, it was everywhere.It felt like everyone had the same car. While sales of camping vans and cars that can be used for camping in fact have increased during the pandemic, there’s another reason I saw so many of them, the Frequency illusion...

Parents counting children in CSS
29 Aug 2022 | original ↗

The other day I was driving home when suddenly it hit me: We can use :has() to determine how many children a parent element has.You might be thinking that Heydon Pickering already solved that 7 years ago in Quantity Queries for CSS, but that's not what I'm talking about. /* Quantity Queries for CSS by Heydon Pickering */ /* Three or more items...

outline is your friend
17 Aug 2022 | original ↗

If you open a plain HTML document with no CSS and you focus an interactive element like a button, link, or textarea, you’ll see that by default browsers use the outline property to highlight these elements. A blue outline around a focused button in Firefox outline is great The outline property is the perfect candidate for this job for several...

Analyzing pages in a particular state with Lighthouse
27 Jun 2022 | original ↗

Historically, Lighthouse has analyzed the cold pageload of a page only. Clicking the “Generate report” button reloads the page before Lighthouse runs its tests. This can be problematic when you want to run tests on parts of the UI that are only visible when the user interacts with it. For example, a fly-out navigation, a modal window, or the...

Divs are bad!
11 May 2022 | original ↗

Yes, clickbait, I’m so sorry! Of course, divs are not bad. For example, they can be really useful,… …when you need additional elements for styling. …for structuring content, when there’s no other suitable element. …when you need custom landmarks. Even though there’s nothing wrong with the div per se, some people, including me, still like to...

Please, stop disabling zoom
5 May 2022 | original ↗

I know that you’re not supposed to tell people what to do, but in this particular case I’m really tempted because recently I’ve noticed that a lot of websites are preventing users on mobile to zoom.I don’t know whether this is a trend, or just a coincidence, but I see a lot of these meta tags on sites: This prevents users from being able to...

Bonn Meetup 7: Introduction to web accessibility and deceitful Lighthouse scores
21 Feb 2022 | original ↗

This week I’ll be speaking at the Bonn Code Meetup about accessibility testing. I’m joining Konstantin Tieber who’ll talk about the What, Why, Who and How of building accessible web applications. I’ll show you how I built “The Most Inaccessible Site Possible With A Perfect Lighthouse Score”.Join us Online at 7pm CEST on Wednesday, February 23rd...

Web Security Basics: XSS
16 Feb 2022 | original ↗

I decided to learn more about areas of web development I don’t know a lot about. You know,…stuff like SEO and web security. I’ll share my findings here on my blog and I’ll try to do as much research as possible, but please keep in mind that I’m a noob concerning these topics.I began watching Feross Aboukhadijeh’s fantastic Web Security lecture,...

Cascade Layers: First Contact
28 Jan 2022 | original ↗

Earlier this week I learned about CSS Cascade Layers and now I’m all hyped up because I really like the concept. I’m eager to find out how we can use them to improve and rethink the architecture of our styles.I will not explain how CSS Cascade Layers work because Bramus and Stephanie have already done that and they did it much better than I ever...

CSS Specificity Demo
26 Jan 2022 | original ↗

I built an interactive demo to illustrate how specificity in CSS works. main { background: rgb(250 250 250 /0.6) !important; } Press the “Add selector” and “Remove selector” buttons to add or remove a selector in the list of declarations and see how the background color changes accordingly. Each selector will be added to the top of the list to...

Here’s what I didn’t know about :where()
25 Jan 2022 | original ↗

This is part 4 of my series Here’s what I didn’t know about… in which I try to learn new things about CSS. This time I'm trying to find out what I didn’t know about the :where() pseudo-class. Okay, I’ll be honest. When I heard about the :where() pseudo-class for the first time, I wasn’t impressed because reading a rule like the following hurt my...

A year in review: 2021
9 Jan 2022 | original ↗

2021 was wild! That’s why I’ve decided to write an “A year in review” post for the first time.Personal Let me start with the most important thing that happened in 2021: Our daughter Johanna was born on May 19th. I can’t describe how beautiful the entire experience was and still is. For the first two days, I wasn’t able to look at her for longer...

Workshop: Deep Dive on Accessibility Testing
2 Oct 2021 | original ↗

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...

Element diversity
2 Sept 2021 | original ↗

Did you know that there are 112 elements in HTML?! Heading The markup above is something I see a lot on websites I audit professionally or when I just look under...

Browser support: focus pseudo classes
7 Jul 2021 | original ↗

I don’t know who needs to hear this, but that’s the current browser support for :focus-visible and :focus-within, and I love it!:focus-visible browser support :focus-within browser support My blog doesn't support comments yet, but you can reply via blog@matuzo.at.

My current HTML boilerplate
9 Apr 2021 | original ↗

Every element I use for the basic structure of a HTML document, with explanations why.Traducción a Español by www.ibidemgroup.com. Usually when I start a new project, I either copy the HTML structure of the last site I built or I head over to HTML5 Boilerplate and copy their boilerplate. Recently I didn’t start a new project, but I had to...

Highlighting columns in HTML tables
20 Mar 2021 | original ↗

The col element allows us to style columns in tables.In the past, I’ve used the colgroup and col elements to define max-widths for columns in tables when I didn’t want to rely on the default algorithm for distribution of widths, usually when building templates for e-mail newsletters. A simple table with dummy content First...

Dev Tools: Debugging DOM Tree modifications
29 Jan 2021 | original ↗

“Break on Subtree Modification” allows you to debug dynamically added and removed DOM nodes.The other day I was debugging a Drag’n’Drop component, and I noticed that it added a DOM node every time I dragged an element. I wanted to inspect the node and see what’s going on in the CSS panel, but as soon as I dropped the element I was dragging, the...

More or less burger-less navigation
7 Jan 2021 | original ↗

For your and my inspiration: A collection of websites that don’t hide the navigation on mobile behind a burger/menu button. Show some, hide the rest Single row, centered Single row, space-between Single row, scrollable Multiple rows Vertical navigation Single row, additional icons Multiple rows,...

Ordering CSS properties
4 Jan 2021 | original ↗

I haven’t thought about ordering CSS properties in a while, but I began to work on the redesign of HTMHell recently and I decided to challenge my current approach.How I’m ordering CSS properties now Honestly, I don’t know. It’s a mix of logical grouping, alphabetical order and just no order at all. It kinda has some structure, but I guess you...

Slow Movement
16 Dec 2020 | original ↗

My answer to the question “What is one thing you learned about building websites this year?”My blog doesn't support comments yet, but you can reply via blog@matuzo.at.

The lang attribute: browsers telling lies, telling sweet little lies
19 Oct 2020 | original ↗

The lang attribute is an essential component in the basic structure of an HTML document. It’s important that we define it correctly because it affects many aspects of user experience. Unfortunately, the negative effects a missing or wrong attribute can have aren’t always evident. Austrian news site orf.at learned that the hard way...

Writing even more CSS with Accessibility in Mind, Part 2: Respecting user preferences
12 Oct 2020 | original ↗

In the first article of this series, I explained how important progressive enhancement is for web accessibility. Building websites layer by layer allows for a cleaner separation of concerns and more resilient experiences. This second article is about user preferences and how to respect them when writing CSS.In this series This series of articles...

Writing even more CSS with Accessibility in Mind, Part 1: Progressive Enhancement
9 Sept 2020 | original ↗

About 4 years ago, I began to focus on web accessibility professionally. I read many articles and books, watched talks, followed experts, and I also shared my knowledge at meet-ups and online. The first 3 articles I wrote were Writing HTML with Accessibility in Mind, Writing JavaScript with Accessibility in Mind, and Writing CSS with...

Accessible to some
24 Jun 2020 | original ↗

According to WebAims annual accessibility analysis, 98.1% of home pages of the top 1,000,000 websites have detectable WCAG 2.0 failures. Some of these sites may only have minor contrast issues or maybe just a single missing id, while others are highly inaccessible. However, this number is pretty damn high, considering the fact that automatic...

Reverse ordered lists
4 Jun 2020 | original ↗

I’m working on a project where I have a list of items in reverse order. The list starts with the latest item and ends with the oldest. I wanted to express that both semantically and visually. I did some research and found interesting solutions, some of them good, others not so much.The result should look a little like this. 3. C 2. B 1. A Let’s...

Here’s what I didn’t know about “content”
26 May 2020 | original ↗

This is part 3 of my series Here’s what I didn’t know about… in which I try to learn new things about CSS. This time I'm trying to find out what I didn’t know about the content property.A few weeks ago Stefan published a post on his website called “The CSS "content" property accepts alternative text”, which blew my mind. He showed that the...

The beauty of progressive enhancement
28 Apr 2020 | original ↗

Nokia released an updated version of its iconic Nokia 3310 about 3 years ago. It was affordable for me (€60/$65), so I had to get one. It came with a 2 MP camera, a battery that lasts 30 days (up to 22 hours talk time), 2G, 16 MB storage, the original Snake game, and a browser. Screenshot: Nokia. Opera Mini You can access the worldwide web on the...

Blogging is one of the best ways of learning
19 Apr 2020 | original ↗

I can’t stress enough how important it is to blog if you want to become better at web development. You learn so much more by explaining something in your own words than by just reading and copying & pasting.I overcame my fear of writing and speaking, because I realized that… It doesn’t matter if someone else has written about the same topic....

Here’s what I didn’t know about “color”
19 Apr 2020 | original ↗

This is part 2 of my series Here’s what I didn’t know about… in which I try to learn new things about CSS. This time I'm trying to find out what I didn’t know about the color property.When setting the CSS color property, 2 things happen. The foreground color value of an element's text changes. The currentcolor value changes. a { color: #237680;...

How many browsers do you know?
12 Mar 2020 | original ↗

While testing a new feature recently, I realised that I don’t know too many browsers. I can list some, but I don‘t really know them like I know Firefox or Chrome. I want to change that, and I invite you to do the same.Firefox Developer Tools have improved so much in the last few years that I naturally switched from Chrome as my main development...

Why 543 KB keep me up at night
26 Feb 2020 | original ↗

The question how good good enough is and at which point a website is ready to go online is keeping me busy lately. The web is in bad shape and it’s because we’re making it too easy on ourselves. “It’s online and works in most browsers” is not enough - we have to be much more considerate of what we’re putting online.Some background: About three...

Eines meiner Lieblingswerkzeuge für Barrierefreiheit-Checks: Die Tabulator-Taste.
20 Feb 2020 | original ↗

Ich bin seit etwa einem Jahr angestellt und viele Dinge sind anders als bei meiner freiberuflichen Tätigkeit zuvor. Eine interessante Neuerung ist, dass ich regelmäßig die Zugänglichkeit von Tools Dritter bewerten muss. Dabei bleibt normalerweise keine Zeit für eine vollständige Prüfung, ich muss mir so schnell wie möglich einen guten Überblick...

One of my favourite accessibility testing tools: The Tab Key.
20 Feb 2020 | original ↗

I’ve been employed for about a year now and many things are different compared to being a freelancer. One interesting thing in my specific situation is that I have to evaluate the accessibility of third-party tools regularly. Usually there’s no time for a full audit, I have to gain a good overview of the quality of a product as quickly as...

Reading recommendations: Animation on the web and vestibular disorders
11 Feb 2020 | original ↗

It’s 7:25 a.m. and I’ve already learned so much. Actually, I just wanted to write a few paragraphs for an article about accessibility in CSS before I go to work, but I got caught up reading about animation on the web and vestibular disorders.The articles I read written by Eric W. Bailey and Shell Little, Val Head, and Facundo Corradini are so...

Here’s what I didn’t know about…
28 Jan 2020 | original ↗

Recently, it feels like I see a property, a property value or a selector I haven’t heard about pop up every day. Often these things I learn aren’t even that new, which makes me wonder how much I don’t know about CSS.In this series of articles I’m (re)visiting CSS properties and selectors, trying to find out what I didn’t know about them. Here’s...

Here’s what I didn’t know about list-style-type
28 Jan 2020 | original ↗

At the CSS-in-Vienna meet-up last week Ulrich told me that starting with Chrome 79 it's possible to define a string value for the list-style-type property. I was surprised because I thought ::marker was supposed to solve that. That's why I did some research, here’s what I learned.list-style-type accepts a string value In Chrome 79+, Firefox 39+,...

CSS pro tip for mac users: always show scroll bars in macOS.
20 Jan 2020 | original ↗

I built a quite complicated component in HTML and CSS last week and I was happy with the result. After testing in different browsers and operating systems, I realised that I had to rewrite the whole thing because I didn’t consider that by default scroll bars don’t take up space on macOS, but on Windows they do. I tweeted about a similar issue...

matuzo.at from scratch #1 - Designing and finding inspiration
17 Jan 2020 | original ↗

The this video I explain how I approach design and how I find inspiration, both online and offline. Subscribe to the YouTube channel. In this page Video Transcript Intro Required skills you'll need How I approach design Finding inspiration Outro Video Transcript...

Bad accessibility equals bad quality
15 Jan 2020 | original ↗

When I talk about web accessibility at meet-ups and conferences, it’s safe to assume that at least one person will ask me something like “Yeah, accessibility sounds nice, but how many people are actually disabled? How many of my users are blind? And why would a blind person visit my website?”1. Who gives a fuck?! We’re not building websites for...

matuzo.at from scratch #0 - introduction
9 Jan 2020 | original ↗

I'm redesigning and building my website from scratch. In this first video I introduce myself and I describe what my plans are for the following weeks and months. Watch it to see if this series of videos is for you or not. In this page Video Transcript Video Transcript [Introduction] Hello and welcome to this first video in a...

Beyond automatic accessibility testing: 6 things I check on every website I build
15 Oct 2019 | original ↗

I just finished an accessibility audit for a client and I decided to share some quick checks I perform in every site I audit and build. It’s something that you can apply to your project right away, you don’t have to learn a tool or a software.Step 0: Automatic tests The first thing I do is run accessibility checks in Lighthouse to figure out if...

Please write and talk more about CSS
25 Sept 2019 | original ↗

I saw a lot of JavaScript today considering that I was at a CSS conference.It absolutely makes sense because for many people writing CSS means writing JS but I've seen enough pro/con talks about CSS-in-JS. I do enjoy talks that are more advanced and show how to optimize the CSS people write in JS but I'd really love to see a CSS only talk or read...

Don't be afraid to share
20 Aug 2019 | original ↗

I don’t consider myself a web accessibility expert but I’ve learned enough in a relatively short time to feel comfortable enough to share my knowledge in blog posts, workshops and talks. Here’s some advice, if you want to share stuff but are wary about doing it.1. Find something that interests you and stick to it. Fullstack is bullshit and so is...

Building the most inaccessible site possible with a perfect Lighthouse score
31 May 2019 | original ↗

It’s always nice to see when people post their Lighthouse scores on social media to highlight how well they’ve optimised their own or their client's website. It shows that they care about the quality of what they build. .lighthouse-test { position: relative; } .lighthouse-test button { position: absolute; z-index: 111; left: 0; right:...

The Dark Side of the Grid (Part 2)
11 May 2019 | original ↗

CSS Grid layout is powerful and flexible. It's great for our development experience, but it may come at the cost of user experience and accessibility if we don’t use it responsibly. This article series gives you an overview of potential implementation pitfalls; or, in other words, the dark side of the...

12 Tips for More Accessible React Apps (Slides, React Finland 2019)
25 Apr 2019 | original ↗

If you want to improve the accessibility of your React apps but you don't know how or where to start, this talk is just what you need. Manuel shares 12 tips that will help you build web sites and applications that can be used by anyone. Each tip fits on one slide and you'll be able to put them into practice right away without having to learn...

Improving the keyboard accessibility of Embedded CodePens
7 Mar 2019 | original ↗

I'm a huge fan of CodePen (No, they didn’t pay me to write this). I'm using it for prototyping, experimenting, sharing code, and in my latest blog post, The Dark Side of the Grid, I'm also making use of their Embedded Pens. CodePen allows you to customize syntax highlighting, and background and text colors of UI elements in Embedded Pens. As a...

The Dark Side of the Grid (Part 1)
7 Feb 2019 | original ↗

CSS Grid Layout is one of the most exciting recent CSS specifications because of its flexibility, extent, and power. It makes our lives so much easier but it also creates new dangers regarding user experience and accessibility. Preface It has already been two years since the first browsers, Chromium 57 and Firefox 52, shipped CSS Grid Layout...

Hello World!
4 Jan 2019 | original ↗

It happened. I finally have a website. Of course, it's not my first website but the first one in a long time. My very first personal site went online about 17 years ago. It was a table-based layout with no CSS at all. All styling happened by adding HTML attributes. ... It was online for about 2 years. After that, the only thing I did...

I Threw Away my Mouse
16 Dec 2018 | original ↗

Last year I attended JS Conf Budapest and I watched many great talks but “YES! Your site can (and should) be accessible” by Laura Carvajal was the most thought-provoking talk for me. Laura explained how the Financial Times made accessibility a core part of their development process and she shared several lessons she and her team had learned. In...

Another Collection of Interesting Facts about CSS Grid Layout
13 Apr 2018 | original ↗

Last year, I assembled A Collection of Interesting Facts about CSS Grid Layout after giving a workshop. This year, I worked on another workshop and I've learned some more exciting facts about the layout spec we all so love. Of course, I'm not going to keep my knowledge to myself. I'm happy to share my findings once again with you, the CSS-Tricks...

My Accessibility Journey: What I’ve Learned So Far
6 Feb 2018 | original ↗

Last year I gave a talk about CSS and accessibility at the stahlstadt.js meetup in Linz, Austria. Afterward, an attendee asked why I was interested in accessibility: Did I or someone in my life have a disability? I’m used to answering this question—to which the answer is no—because I get it all the time. A lot of people seem to assume that a...

Writing CSS with Accessibility in Mind
17 Sept 2017 | original ↗

About a year ago I started to focus more on web accessibility. The most effective method of learning for me is teaching others. That’s one of the reasons why I’m talking at meetups and conferences and why I’m writing articles about the topic. I wrote about Progressive Enhancement for Smashing Magazine and about accessibility basics here on...

The Difference Between Explicit and Implicit Grids
10 Aug 2017 | original ↗

Grid Layout finally gives us the ability to define grids in CSS and place items into grid cells. This on its own is great, but the fact that we don't have to specify each track and we don't have to place every item manually makes the new module even better. Grids are flexible enough to adapt to their items. This is all handled by the so called...

Progressively Enhancing CSS Layout: From Floats To Flexbox To Grid
24 Jul 2017 | original ↗

When can I start using CSS grid layout?” “Too bad that it’ll take some more years before we can use grid in production.” “Do I need Modernizr in order to make websites with CSS grid layout?” “If I wanted to use grid today, I’d have to build two to three versions of my website.” The CSS grid layout module is one of the most exciting developments...

A Collection of Interesting Facts about CSS Grid Layout
21 Jul 2017 | original ↗

A few weeks ago I held a CSS Grid Layout workshop. Since I'm, like most of us, also pretty new to the topic, I learned a lot while preparing the slides and demos. I decided to share some of the stuff that was particularly interesting to me, with you.My blog doesn't support comments yet, but you can reply via blog@matuzo.at.

Writing JavaScript with accessibility in mind
12 Feb 2017 | original ↗

Tips on how to improve the accessibility of your JavaScript components and provide users with more and better ways to interact with your website or web app.My blog doesn't support comments yet, but you can reply via blog@matuzo.at.

Writing HTML with accessibility in mind
13 Dec 2016 | original ↗

An introduction to web accessibility. Tips on how to improve your markup and provide users with more and betters ways to navigate and interact with your site.My blog doesn't support comments yet, but you can reply via blog@matuzo.at.

I totally forgot about print style sheets
15 Nov 2016 | original ↗

A small collection of useful CSS techniques and a quick reminder that print style sheets are still a thing. another old post (who cares?) that was originally on medium and now is on the author's domain blah blah -Random reply guy on Hacker News Aaron Gustafson recently sent a tweet to Indiegogo in which he pointed out that their order details...

Getting started with CSS Font Loading
12 Oct 2016 | original ↗

I was in the mood to learn something new and so I decided to take a look at the CSS Font Loading API.My blog doesn't support comments yet, but you can reply via blog@matuzo.at.

↑ These items are from RSS. Visit the blog itself at https://www.matuzo.at/blog to find everything else and to appreciate author's digital home.