<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alvaro Montoro</title>
    <description>The latest articles on DEV Community by Alvaro Montoro (@alvaromontoro).</description>
    <link>https://dev.to/alvaromontoro</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F161327%2F2ff05281-db58-4dcb-946a-4b679e4a266b.jpeg</url>
      <title>DEV Community: Alvaro Montoro</title>
      <link>https://dev.to/alvaromontoro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alvaromontoro"/>
    <language>en</language>
    <item>
      <title>10 Cool CodePen Demos (August 2026)</title>
      <dc:creator>Alvaro Montoro</dc:creator>
      <pubDate>Mon, 21 Sep 2026 14:19:26 +0000</pubDate>
      <link>https://dev.to/alvaromontoro/10-cool-codepen-demos-august-2026-2nmm</link>
      <guid>https://dev.to/alvaromontoro/10-cool-codepen-demos-august-2026-2nmm</guid>
      <description>&lt;h2&gt;
  
  
  sibling-index staggered animations
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;sibling-count()&lt;/code&gt; and &lt;code&gt;sibling-index()&lt;/code&gt; got support on Firefox this month of August, and &lt;a href="https://codepen.io/collinsworth/" rel="external nofollow noopener noreferrer"&gt;Josh Collinsworth&lt;/a&gt; used them to create this animation in which squares rotate and turn into circles (and vice versa). Something that would have required highly specific CSS rules can now be achieved with 40 lines of code. Nice.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/collinsworth/embed/01a0395c-56cb-7c4a-bcb1-8069254d32f5?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Wave header
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://codepen.io/thebabydino/" rel="external nofollow noopener noreferrer"&gt;Ana Tudor&lt;/a&gt; used the &lt;code&gt;shape()&lt;/code&gt; function to create wavy patterns in the header and its pseudo-elements, which combined with different colors and the header content positioning creates a beautiful experience. Also, the code for the shape has many comments making this a great demo for learning about that function.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/thebabydino/embed/YPZzmZE?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Analog Email Alert
&lt;/h2&gt;

&lt;p&gt;As part of a CodePen Challenge, &lt;a href="https://codepen.io/zerdebek" rel="external nofollow noopener noreferrer"&gt;Zerde Turdybek&lt;/a&gt; created this interactive animation with ThreeJS. Move the mouse around to see the letter follow the pointer, then click on the mailbox to drop the letter, and the mailbox will animate. I really like how the demo and the shadow details.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/zerdebek/embed/019ffcaf-a4bd-7436-9063-bea36afa1b94?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Elastic macOS Traffic Lights
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://codepen.io/BalintFerenczy" rel="external nofollow noopener noreferrer"&gt;Bálint Ferenczy&lt;/a&gt; reimagines the MacOS window buttons and crafts a new interactive version using vanilla HTML, CSS, and JavaScript. Play around with them: move mouse over, click, pull them (yes, pull them). The micro-interactions it has are really smooth. I enjoyed the bounce effects.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/BalintFerenczy/embed/zxNVyMJ?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Div Shuffling
&lt;/h2&gt;

&lt;p&gt;If you've worked drawing with CSS and doing 3D with CSS, you know how difficult it is to simulate a curved shape without looking weird or fake. But this demo with cards shuffling does exactly that and in such a easy-looking way (just using a ton of divs). Of course, it had to be &lt;a href="https://codepen.io/amit_sheen" rel="external nofollow noopener noreferrer"&gt;Amit Sheen&lt;/a&gt;, who does magic with 3D CSS, who did it. Amazing! &lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/amit_sheen/embed/01a002cd-8546-71c8-beba-2a312f0b2674?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Banana - Peel Study
&lt;/h2&gt;

&lt;p&gt;An interesting infinite cycle with the word "banana" getting carved and uncarved from a three-dimensional banana. Scan, carve, dissolve, loop. &lt;a href="https://codepen.io/daniel-mu-oz/" rel="external nofollow noopener noreferrer"&gt;Daniel Muñoz&lt;/a&gt; is the author of this original (and a little bit weird) animation with ThreeJS and GreenSock.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/daniel-mu-oz/embed/019fce60-a6bd-799c-84f2-1ff0b2a24bfc?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Plant Shop - a 3D game about growing and selling plants
&lt;/h2&gt;

&lt;p&gt;I had fun playing this game by &lt;a href="https://codepen.io/JoshuaVB/" rel="external nofollow noopener noreferrer"&gt;Joshua van Boxtel&lt;/a&gt;, although I must admit that I didn't go beyond level 2 (and a half). Grow your greenhouse and your business by taking care of the plants and buying newer/better seeds at the market. The 3D is impressive, I wish the transitions were a bit smoother (having to reset the camera each time, ouch!)&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/JoshuaVB/embed/emgXabd?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Evil Eye
&lt;/h2&gt;

&lt;p&gt;I haven't seen many Lord of the Rings demos lately, so this one by &lt;a href="https://codepen.io/BlackStar1991/" rel="external nofollow noopener noreferrer"&gt;Andry Zirka&lt;/a&gt; caught my attention. The tower is a WebP image, but the fiery eye that follows the mouse is coding into a canvas. Really impressive result. Time to so stop messing around and get back to work... but first, two more demos.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/BlackStar1991/embed/019fbdaf-a0d3-7a6c-ab7e-9710e7f32a5a?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Your Package Could Not Be Delivered
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://codepen.io/grauconejo13/" rel="external nofollow noopener noreferrer"&gt;Vanessa Victorino&lt;/a&gt; coded the template for this "deceptive" demo. It is a realistic-looking Amazon email that tries to trick the viewer to perform an action. The main elements of phishing are present and a short description of them pops up (when you fail and end up clicking what you shouldn't).&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/grauconejo13/embed/019fcd33-7d70-76d5-87a2-2def1ee5c97a?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Creative login robot
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://codepen.io/itayko" rel="external nofollow noopener noreferrer"&gt;Itay haephrati&lt;/a&gt; coded this robot-login form that interacts with the user as they enter the information. I like this type of high micro-interactions demos that are practical enough to be put on a website even if they are a big goofy. This is fun and friendly.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/itayko/embed/019fc70d-b75a-73b9-a643-f75d58b3199b?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




</description>
      <category>html</category>
      <category>css</category>
      <category>showdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>La Liga's Web Accessibility Table: How Do Clubs Actually Score?</title>
      <dc:creator>Alvaro Montoro</dc:creator>
      <pubDate>Sun, 06 Sep 2026 20:13:44 +0000</pubDate>
      <link>https://dev.to/alvaromontoro/la-ligas-web-accessibility-table-how-do-clubs-actually-score-21ib</link>
      <guid>https://dev.to/alvaromontoro/la-ligas-web-accessibility-table-how-do-clubs-actually-score-21ib</guid>
      <description>&lt;p&gt;I should start by saying that I'm not a web accessibility expert. I work in web development and deal with accessibility features regularly, but I've never had formal training in the field.&lt;/p&gt;

&lt;p&gt;To practice and learn, I ran a series of accessibility audits, and at the same time explored whether there's any correlation between digital quality and success on the soccer field (though I presumed superior finances would drive both). And honestly, analyzing the web standards of top‑level clubs just sounded like a fun challenge.&lt;/p&gt;

&lt;p&gt;All of this is to say: take this article with a grain of salt. It's one person running tests, with the level of scientific rigor you'd expect from that. And yes, just like AI, I can make mistakes.&lt;/p&gt;

&lt;p&gt;Each team has a card like the one shown below, providing the core results at a glance. The surrounding text includes commentary and a short summary of what the card reveals.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe9m46alwamt0nr5iizl7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe9m46alwamt0nr5iizl7.png" alt="Team card showing overall score, and then manual accessibility, automated accessibility, performance, and structure scores." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;
All numbers are rounded to keep things readable.&lt;br&gt;&amp;nbsp;



&lt;p&gt;I started with automated tools (the criteria and process are described at the end of the article), but those results felt incomplete. So I added a more "human" layer by manually testing and scoring accessibility features. These may not be the criteria everyone uses, but they're the ones I followed. If you prefer different ones, I encourage you to run your own tests and write about them. I'd genuinely love to read it.&lt;/p&gt;

&lt;p&gt;Here are the results…&lt;/p&gt;




&lt;h2&gt;
  
  
  Alavés
&lt;/h2&gt;

&lt;p&gt;If I recall correctly, this was the only home page with a form in it (not counting the search box), and that introduced some new issues that took points from them. Automated accessibility tests gave a high score (e.g., all images had alt attribute) but manual test proved things were not what they seemed (e.g., all images had alt attribute with "null" as value). Using the screenreader there were a lot of "link, image, null" messages.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://deportivoalaves.com/es/" rel="noopener noreferrer"&gt;https://deportivoalaves.com/es/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftd6esplgbga7hjilx4wz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftd6esplgbga7hjilx4wz.png" alt="results for Alaves. Overall score: 52. Manual accessibility: 48. Automated accessibility: 72. Performance: 37. Structure: 42." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Athletic
&lt;/h2&gt;

&lt;p&gt;Athletic's site relies heavily on images that contain text (many of them with alt=""), including several inside links that have no other content. Combine that with long, non‑skippable sections that seem to go on forever, plus a menu that remains reachable even when hidden, and the accessibility score takes a predictable hit. On the positive side, the site handles zoom surprisingly well.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.athletic-club.eus/" rel="noopener noreferrer"&gt;https://www.athletic-club.eus/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe7phs6fc9448d4l68gk5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe7phs6fc9448d4l68gk5.png" alt="results for Athletic. Overall score: 60. Manual accessibility: 69. Automated accessibility: 50. Performance: 65. Structure: 40." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Atlético
&lt;/h2&gt;

&lt;p&gt;The language menu on Atlético's site is confusing when using a keyboard. You can open it normally, but then you're forced to tab through the entire main menu before reaching the popup with alternative languages (this happened with several teams). It's not a feature people use often, but the one time you need it, the experience shouldn't be disorienting. The site follows the reduced‑motion setting strictly, which is rare: if reduced motion is enabled, all animations and transitions stop completely.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.atleticodemadrid.com/" rel="noopener noreferrer"&gt;https://www.atleticodemadrid.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6fnzkwwdfagxl8g71kv3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6fnzkwwdfagxl8g71kv3.png" alt="results for Atletico. Overall score: 76. Manual accessibility: 83. Automated accessibility: 71. Performance: 60. Structure: 75.n" width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Barcelona
&lt;/h2&gt;

&lt;p&gt;Overall, Barcelona's site performed reasonably well compared to the rest of La Liga… but given the club's history, resources, and global reach, the results feel underwhelming. Especially considering the types of issues that surfaced: a poor heading hierarchy, a sticky header that consumes half the screen when zoomed, and focus indicators that clip or jump to hidden elements creating confusion.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.fcbarcelona.es/es/" rel="noopener noreferrer"&gt;https://www.fcbarcelona.es/es/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwxbngee63uhfuattxwc7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwxbngee63uhfuattxwc7.png" alt="results for Barcelona. Overall score: 68. Manual accessibility: 74. Automated accessibility: 53. Performance: 75. Structure: 64." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Betis
&lt;/h2&gt;

&lt;p&gt;Betis' homepage presents several accessibility challenges: carousels that animate and slide even with reduced‑motion enabled, menus that open but can't be reached until you tab through a sea of unrelated items, and a noticeable amount of text with low contrast against its background. In their defense, green is a notoriously tricky color when it comes to contrast… but still. I expected more from a team like Betis.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.realbetisbalompie.es/" rel="noopener noreferrer"&gt;https://www.realbetisbalompie.es/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fohca6waz86m046nuyzzh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fohca6waz86m046nuyzzh.png" alt="results for Betis. Overall score: 54. Manual accessibility: 54. Automated accessibility: 54. Performance: 61. Structure: 41." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Celta
&lt;/h2&gt;

&lt;p&gt;I liked the grid in the header of Celta's website, and the page performed decently in automated tests. But manual testing quickly brought the score down: no level‑1 heading, and only a single level‑2 heading (buried at the bottom in the merchandise store)? The page is in Spanish, yet somehow the button labels appear in English (the risks of copy‑paste)? And videos in the video carousel that aren't reachable via keyboard navigation?&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://rccelta.es/" rel="noopener noreferrer"&gt;https://rccelta.es/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fra0wjkc55igifvr4n2zw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fra0wjkc55igifvr4n2zw.png" alt="results for Celta. Overall score: 62. Manual accessibility: 54. Automated accessibility: 81. Performance: 69. Structure: 44." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Deportivo
&lt;/h2&gt;

&lt;p&gt;The 95 in structure can be misleading. The site earned it thanks to strong automated test results and only three HTML errors. Unfortunately, structure is the metric with the least weight, and the manual tests (which carry the most weight) yielded the lowest score of any team. Issues included faint or missing outlines, images with alt attributes equal to the file name (ouch!), or components that only worked with a mouse. And that's just to name a few; the list goes on.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.rcdeportivo.es/es" rel="noopener noreferrer"&gt;https://www.rcdeportivo.es/es&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5ursvg0jk1djfk2k3s72.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5ursvg0jk1djfk2k3s72.png" alt="results for Deportivo. Overall score: 57. Manual accessibility: 46. Automated accessibility: 64. Performance: 58. Structure: 95." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Elche
&lt;/h2&gt;

&lt;p&gt;Elche's landing page is so minimal that it earns points almost by default because many of the tested metrics simply don't apply (note to self: revise grading criteria for next year). There are some nice touches: gradients used to boost contrast, and a carousel that respects reduced‑motion settings (the same widget many other teams use). But there are also questionable choices; most notably, the page doesn't contain a single heading!&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.elchecf.es/" rel="noopener noreferrer"&gt;https://www.elchecf.es/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5df3umxmeneh36k0dcaj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5df3umxmeneh36k0dcaj.png" alt="results for Elche. Overall score: 73. Manual accessibility: 83. Automated accessibility: 70. Performance: 61. Structure: 46." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Espanyol
&lt;/h2&gt;

&lt;p&gt;Espanyol was the only team to score below 50 overall (a failing grade in Spain). From missing outlines to menus accessible only by mouse, to images without alt attributes and a broken navigation that traps the keyboard, the site struggled across the board. It failed every automated test except Lighthouse… which brought the scores up!&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.rcdespanyol.com/es/" rel="noopener noreferrer"&gt;https://www.rcdespanyol.com/es/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuaqlrvrclo9ft1s18r3s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuaqlrvrclo9ft1s18r3s.png" alt="results for Espanyol. Overall score: 49. Manual accessibility: 57. Automated accessibility: 36. Performance: 48. Structure: 41." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Getafe
&lt;/h2&gt;

&lt;p&gt;There are a few teams that use the same white‑labeled web template, customized only with club colors. Out of the box, it delivers solid SEO results and decent accessibility. But it also serves as a reminder that content and authoring choices can break even the most accessible template. Getafe seems to be one of the clubs using it, and fortunately, they handled their content reasonably well apart from some things: no proper headings (none at all, to be precise) and a handful of related screen‑reader issues… but little beyond that.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.getafecf.com/" rel="noopener noreferrer"&gt;https://www.getafecf.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2h957nbhi203k7acsrzj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2h957nbhi203k7acsrzj.png" alt="results for Getafe. Overall score: 77. Manual accessibility: 89. Automated accessibility: 77. Performance: 54. Structure: 54." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Levante
&lt;/h2&gt;

&lt;p&gt;Levante's landing page is a good example of how my scoring criteria can favor simpler pages with limited content. With little text, few images, and only a handful of widgets and components, the site is easy to use largely because of its simplicity. Still, there's room for improvement: making proper use of HTML landmarks and hierarchical elements (the page has only a single heading!) and ensuring that outlines don't break would improve accessibility.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.levanteud.com/" rel="noopener noreferrer"&gt;https://www.levanteud.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmqwj64w5kr6qczu6lbna.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmqwj64w5kr6qczu6lbna.png" alt="results for Levante. Overall score: 75. Manual accessibility: 83. Automated accessibility: 79. Performance: 57. Structure: 56." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Málaga
&lt;/h2&gt;

&lt;p&gt;Another example of a template that could be far more accessible if the content followed suit… but it doesn't. The homepage suffers from missing headings, clipped outlines, and poor image labeling. Still, Malage homepage's simplicity and low volume of content worked in its favor during scoring, landing the site in a respectable second place&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.malagacf.com/" rel="noopener noreferrer"&gt;https://www.malagacf.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3eqlzcqyky3a4h3e51ml.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3eqlzcqyky3a4h3e51ml.png" alt="results for Malaga. Overall score: 77. Manual accessibility: 86. Automated accessibility: 77. Performance: 63. Structure: 55." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Osasuna
&lt;/h2&gt;

&lt;p&gt;The disappearance of outlines across most elements on Osasuna's site dealt a major blow in manual testing. And that wasn't the only issue: carousels autoplay without pause or focus control, ignore reduced‑motion settings, and oddly mix Spanish content with English controls. These problems compounded to drag the score down. Overall, Osasuna's homepage has significant room for improvement, placing the team in the lower half of the accessibility rankings.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.osasuna.es/es" rel="noopener noreferrer"&gt;https://www.osasuna.es/es&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp7gk8q97d5ounch28aw2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp7gk8q97d5ounch28aw2.png" alt="results for Osasuna. Overall score: 57. Manual accessibility: 63. Automated accessibility: 53. Performance: 51. Structure: 50." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Racing
&lt;/h2&gt;

&lt;p&gt;Racing de Santander's homepage earned the highest score in manual testing, despite getting average or below‑average results in automated checks. "It's not easy being green" proved true here: the club's colors didn't help with contrast, and issues like missing headings, questionable alternative text values, and animated micro‑interactions that ignored reduced‑motion settings all dragged the score down. Yet, the site's simple structure and limited content balanced things out.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.realracingclub.es/" rel="noopener noreferrer"&gt;https://www.realracingclub.es/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn4znnj6xvqo76fu1ji68.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn4znnj6xvqo76fu1ji68.png" alt="results for Racing. Overall score: 75. Manual accessibility: 91. Automated accessibility: 61. Performance: 57. Structure: 55." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Rayo Vallecano
&lt;/h2&gt;

&lt;p&gt;These results weren't terrible (compared to other teams), but given the club's history and background, I expected more. Accessibility testing showed solid scores in both manual and automated checks, and SEO management was strong. The weaknesses came from structural issues: too many HTML errors, no headings, and most images with empty alt attributes (many of them decorative, though). As with other template‑based sites, many of these shortcomings are content‑related and could be fixed with closer attention to detail.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.rayovallecano.es/" rel="noopener noreferrer"&gt;https://www.rayovallecano.es/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F44id1dkif62qn22yrzzi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F44id1dkif62qn22yrzzi.png" alt="results for Rayo Vallecano. Overall score: 74. Manual accessibility: 86. Automated accessibility: 73. Performance: 56. Structure: 47." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Real Madrid
&lt;/h2&gt;

&lt;p&gt;The low score in structure came from numerous invalid HTML errors (a metric weighted heavily in that category.) Beyond that, the results were strong: only minor focus issues with inconsistent or missing outlines, tabbing sequences that didn't match the visual order, and minimal overlapping when zooming in. Despite having one of the most content-heavy homepages, Real Madrid's accessibility scores outperformed those of clubs with simpler sites. While there's still room to grow, that is commendable.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.realmadrid.com/es-ES" rel="noopener noreferrer"&gt;https://www.realmadrid.com/es-ES&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyq5luzspfhk4wrl33acc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyq5luzspfhk4wrl33acc.png" alt="results for Real Madrid. Overall score: 78. Manual accessibility: 83. Automated accessibility: 79. Performance: 81. Structure: 48." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Real Sociedad
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Real Sociedad's score could have been higher (up to 60), but a grading decision brought it down: the site blocks automated requests, so a couple of my tests couldn't run and therefore couldn't get points for them. To keep things consistent, I used the lowest score recorded by any team in both blocked metrics.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Visually, the site looks polished and neat, but digging deeper, many problems arise. The tabbing experience was problematic to the point of being partly unusable: outlines disappearing or clipped, inconsistent focus styles for similar elements, and components breaking when tabbing through them (looking at you, carousel). Add to that animations and transitions running even with reduced‑motion enabled, or the use of &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; elements as buttons, and the score speaks for itself.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.realsociedad.eus/es" rel="noopener noreferrer"&gt;https://www.realsociedad.eus/es&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flfwvv0n8u389bgem6v5j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flfwvv0n8u389bgem6v5j.png" alt="results for Real Sociedad. Overall score: 54. Manual accessibility: 60. Automated accessibility: 52. Performance: 47. Structure: 41." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Sevilla
&lt;/h2&gt;

&lt;p&gt;Sevilla FC's site stood out for its handling of modals and panels (e.g., the Esc key actually closed them, and the focus looped in them avoiding wandering around.) The font choice is artistic and full of character, but readability suffers, and text can feel confusing at times. Still, Sevilla earns an honorable 5th place overall.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://sevillafc.es/" rel="noopener noreferrer"&gt;https://sevillafc.es/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxuzm1h1mkil7680f2pjx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxuzm1h1mkil7680f2pjx.png" alt="results for Sevilla. Overall score: 76. Manual accessibility: 74. Automated accessibility: 81. Performance: 61. Structure: 94." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Valencia
&lt;/h2&gt;

&lt;p&gt;Valencia's website has far more content than most teams, and while that doesn't automatically mean more issues, it does create more opportunities for error… which is exactly what happened here. But not always! Some of the issues were independent of content: not a single element showed an outline when focused, tab order didn't match the visual order, and headings were used for styling rather than defining the document hierarchy. Also, carousels and components animate and autoplay even when reduced‑motion settings are enabled. The result is a messy homepage that needs some major updates.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://www.valenciacf.com/" rel="noopener noreferrer"&gt;https://www.valenciacf.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft0yonmigbbn5fva0tnl0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft0yonmigbbn5fva0tnl0.png" alt="results for Valencia. Overall score: 54. Manual accessibility: 60. Automated accessibility: 49. Performance: 51. Structure: 43." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Villarreal
&lt;/h2&gt;

&lt;p&gt;Villarreal achieved some of the best overall results, finishing in third place(just hundredths of a point behind the second team.) Valid HTML, excellent performance scores, and solid manual test results helped offset weaker outcomes in automated accessibility checks. Still, issues with color contrast, empty buttons, and inconsistent focus and outline strategies held the site back. Addressing these areas could lift Villarreal into the first place.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://villarrealcf.es/es/" rel="noopener noreferrer"&gt;https://villarrealcf.es/es/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkqib7m04gasaqsrsilo0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkqib7m04gasaqsrsilo0.png" alt="results for Villarreal. Overall score: 77. Manual accessibility: 80. Automated accessibility: 60. Performance: 83. Structure: 95." width="799" height="274"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  And the winner&amp;nbsp;is…
&lt;/h2&gt;

&lt;p&gt;As an Atlético de Madrid supporter, it pains me to admit that &lt;strong&gt;the winner is Real Madrid&lt;/strong&gt;. They ousted Málaga and Villarreal by just 1.1 points each.&lt;/p&gt;

&lt;p&gt;Although Real Madrid came out on top and remains a serious contender for the title, I didn't find any meaningful correlation between web accessibility scores and on‑field performance. That would have been surprising anyway (about as logical as claiming that the decline of pirates causes global warming.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjcbo9cp21iye9ue9rd6p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjcbo9cp21iye9ue9rd6p.png" alt="All the cards together in a table, sorted by score descending. Real Madrid, Malaga, and Villarreal are in the top 3" width="800" height="1712"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One detail did catch my attention: the top four teams from the previous season all ranked within the top seven for SEO. Coincidence, or a hint that digital visibility matters more than we think? (At least, to bring fans and money with them, that can be used to sign better players?)&lt;/p&gt;

&lt;p&gt;Overall, the results weren't terrible, but La Liga teams still have plenty of room to grow in the web accessibility department. Many of the issues were straightforward to detect and, more importantly, relatively easy to fix. So, what happened?&lt;/p&gt;

&lt;p&gt;As a final thought, web accessibility may not decide championships, but it does decide who gets to join the game and enjoy the teams. &lt;strong&gt;Build accessible websites, everyone!&lt;/strong&gt;&lt;/p&gt;







&lt;h2&gt;
  
  
  Grading and Weighting Criteria
&lt;/h2&gt;

&lt;p&gt;This study evaluates the web accessibility of La Liga's first‑division soccer teams, focusing exclusively on the homepage, on desktop, and in Spanish‑language versions.&lt;/p&gt;

&lt;p&gt;To generate metrics, I used a mix of automated, semi‑automated, and manual tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WebAIM Wave&lt;/strong&gt; (extension): accessibility feedback and scoring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lighthouse&lt;/strong&gt; (in‑browser): accessibility, performance, usability, SEO, and structure data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GTMetrix&lt;/strong&gt;: performance and structure analysis, combining Lighthouse with proprietary scoring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility Insights for Web&lt;/strong&gt; (extension): manual accessibility testing guidance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Axe DevTools&lt;/strong&gt; (extension): manual accessibility testing guidance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VoiceOver&lt;/strong&gt;: screen reader evaluation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;W3C HTML Validator&lt;/strong&gt;: HTML error counts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All tests were performed in Chromium on a Mac, except for VoiceOver, for which I used Safari as the browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scoring Framework
&lt;/h3&gt;

&lt;p&gt;The evaluation was divided into four weighted categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Manual accessibility testing&lt;/strong&gt;: 50%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated accessibility testing&lt;/strong&gt;: 25%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance testing&lt;/strong&gt;: 15%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structure &amp;amp; SEO testing&lt;/strong&gt;: 10%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Performance impacts usability and accessibility, while proper structure and best practices boost accessibility by default. That's why these categories are included, even at lower weights.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I initially weighted the categories as 35–30–20–15, but later adjusted to 50–25–15–10 to prioritize accessibility testing (especially manual checks) in order to emphasize the "human side" of the user experience. This update in weights changed the ranking, but not by much.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The following sections explain how each category was scored.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manual Accessibility Testing&amp;nbsp;(50%)
&lt;/h3&gt;

&lt;p&gt;My initial weight for manual accessibility testing was 35%, so I created 35 distinct metrics: 1 metric, 1 point. Later, I adjusted the weighting (after testing the sites), but I kept the 35 metrics and simply pro‑rated them.&lt;/p&gt;

&lt;p&gt;Within this category, I tested seven different groups. Each site began with 35 points, and for every issue identified on the page, I deducted one point (only once per issue). There were a few exceptions to this rule, which I'll explain later.&lt;/p&gt;

&lt;h4&gt;
  
  
  Outline/Focus (5 points)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Missing (some): -1&lt;/li&gt;
&lt;li&gt;Inconsistent Outline: -1&lt;/li&gt;
&lt;li&gt;Clipped: -1&lt;/li&gt;
&lt;li&gt;Outline overlaps text/content: -1&lt;/li&gt;
&lt;li&gt;Hidden elements get focus: -1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If outlines are missing across all elements (or for a considerable number of them), this section automatically receives a score of 0.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tabbing (5 points)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Not in order: -1&lt;/li&gt;
&lt;li&gt;CTAs not tababble: -2&lt;/li&gt;
&lt;li&gt;Cannot exit modal/dialog: -2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the only section in which a metric has a value larger than 1.&lt;/p&gt;

&lt;h4&gt;
  
  
  Typography (5 points)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Low line height/Text lines too close: -1&lt;/li&gt;
&lt;li&gt;Wide paragraphs: -1&lt;/li&gt;
&lt;li&gt;Difficult to identify links/CTAs: -1&lt;/li&gt;
&lt;li&gt;Justified text/Wall of text: -1&lt;/li&gt;
&lt;li&gt;Use headings for styling: -1&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Color (5 points)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Low contrast on image (text or CTAs): -1&lt;/li&gt;
&lt;li&gt;Low contrast on video (text or CTAs): -1&lt;/li&gt;
&lt;li&gt;Use colors for status: -1&lt;/li&gt;
&lt;li&gt;Missing visual label in form: -1&lt;/li&gt;
&lt;li&gt;Missing high contrast: -1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I defined the metrics before starting the tests. I had in mind high‑contrast mode as implemented in Windows, but I couldn't replicate it on Mac. As a result, this metric became a free point for each team, ensuring that no site ended up with a score of zero.&lt;/p&gt;

&lt;h4&gt;
  
  
  Low motion (5 points)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Video autoplay: -1&lt;/li&gt;
&lt;li&gt;Auto carousel: -1&lt;/li&gt;
&lt;li&gt;Parallax effect: -1&lt;/li&gt;
&lt;li&gt;Micro-interactions movement: -1&lt;/li&gt;
&lt;li&gt;Marquee/Ticker: -1&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Zoom at 200% (5 points)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Horizontal scroll: -1&lt;/li&gt;
&lt;li&gt;Elements overlap: -1&lt;/li&gt;
&lt;li&gt;Unreadable text (no change): -1&lt;/li&gt;
&lt;li&gt;Clipped/broken menus: -1&lt;/li&gt;
&lt;li&gt;Sticky header/footer fill most of the screen: -1&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Screen reader (5 points)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Live regions not updating: -1&lt;/li&gt;
&lt;li&gt;Read more button/links (or similar): -1&lt;/li&gt;
&lt;li&gt;Landmark navigation: -1&lt;/li&gt;
&lt;li&gt;Update/error announcement: -1&lt;/li&gt;
&lt;li&gt;Proper alts/labels: -1&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Automated Accessibility Testing&amp;nbsp;(25%)
&lt;/h3&gt;

&lt;p&gt;For automated accessibility testing, I used two tools: &lt;strong&gt;WebAIM Wave&lt;/strong&gt; and the &lt;strong&gt;Lighthouse A11Y results&lt;/strong&gt;. Wave scores accessibility on a scale of 0–10, while Lighthouse uses a scale of 0–100. To normalize the results, I multiplied Wave scores by 10 and then averaged them with Lighthouse scores, giving each tool an equal 50% weight in the calculation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance Testing&amp;nbsp;(15%)
&lt;/h3&gt;

&lt;p&gt;For performance evaluation, I used two tools: &lt;strong&gt;GTMetrix&lt;/strong&gt; and the &lt;strong&gt;Lighthouse Performance results&lt;/strong&gt;. I averaged both scores, giving each tool an equal 50% weight.&lt;/p&gt;

&lt;p&gt;GTMetrix results tended to be lower than Lighthouse's, largely because GTMetrix loaded the page fresh each time, while Lighthouse (running in‑browser) preserved my cookie settings, language selection, and other modes. In practice, GTMetrix measured a first‑load experience, while Lighthouse reflected a page already loaded with user context.&lt;/p&gt;

&lt;h3&gt;
  
  
  Structure &amp;amp; SEO Testing&amp;nbsp;(10%)
&lt;/h3&gt;

&lt;p&gt;For this category, I combined several elements and weighted them differently. On one side, I averaged the &lt;strong&gt;GTMetrix structure score&lt;/strong&gt;, &lt;strong&gt;Lighthouse best practices&lt;/strong&gt;, and &lt;strong&gt;Lighthouse SEO results&lt;/strong&gt;. Together, these accounted for 50% of the category.&lt;/p&gt;

&lt;p&gt;The remaining 50% came from the &lt;strong&gt;W3C HTML Validator&lt;/strong&gt;, worth 5 points in total, awarded as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;0-5 errors: 5 points&lt;/li&gt;
&lt;li&gt;6-10 errors: 4 points&lt;/li&gt;
&lt;li&gt;11-20 errors: 3 points&lt;/li&gt;
&lt;li&gt;21-30 errors: 2 points&lt;/li&gt;
&lt;li&gt;31-50 errors: 1 point&lt;/li&gt;
&lt;li&gt;50 or more errors: 0 points&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Perhaps the weight for valid HTML was too high, but many accessibility and usability features depend on proper markup. For that reason, I chose to emphasize it.&lt;/p&gt;




&lt;p&gt;I liked combining different tools to avoid relying on a single source of truth. In some cases, this approach backfired: certain teams blocked specific tools, or sites were tested with a fresh reload each time, producing lower scores and a worse user experience. Still, I think that ultimately helped balance the results.&lt;/p&gt;

&lt;p&gt;To be honest, I expect to hear criticism of my method and the metrics I tested, and that's a good thing. I will learn better methods and metrics, adopt better practices, and improve the grading and weighting criteria for next year.&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>webdev</category>
      <category>html</category>
      <category>css</category>
    </item>
    <item>
      <title>The 4 Hs of HTML</title>
      <dc:creator>Alvaro Montoro</dc:creator>
      <pubDate>Wed, 26 Aug 2026 02:05:52 +0000</pubDate>
      <link>https://dev.to/alvaromontoro/the-4-hs-of-html-k1c</link>
      <guid>https://dev.to/alvaromontoro/the-4-hs-of-html-k1c</guid>
      <description>&lt;p&gt;There are a few web concepts that appear in every webpage, and they are a recurring source of confusion among designers and developers. Maybe it is because their names are really similar, maybe it is because some have overlapping roles... but they are always causing &lt;em&gt;trouble&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I am talking about &lt;strong&gt;the 4 Hs of HTML: Head, Header, Heading, and Headline&lt;/strong&gt;. Sometimes these names are used interchangeably, but nothing could be further from the truth. Each of them is its own thing and needs to be treated and called appropriately.&lt;/p&gt;

&lt;p&gt;It may seem trivial, but clarity is important because semantics, maintainability, and accessibility depend on it... and having a clear definition for them facilitates communication and helps people understand each other faster (and move projects forward just as quickly.)&lt;/p&gt;

&lt;p&gt;So, what are the 4 Hs of HTML?&lt;/p&gt;

&lt;h2&gt;
  
  
  Head: The Document's Brain
&lt;/h2&gt;

&lt;p&gt;The head of a document is &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/head" rel="noopener noreferrer"&gt;the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; element&lt;/a&gt;. &lt;strong&gt;It contains machine-readable information about the document itself&lt;/strong&gt; (metadata) and, because it is designed for machines and not humans, it is not part of the layout and &lt;strong&gt;it is not visible&lt;/strong&gt; on the browser.&lt;/p&gt;

&lt;p&gt;A common misunderstanding happens when designers and developers talk about the head of the document to refer to the header of the page or the hero section above the fold. That's not what the head is.&lt;/p&gt;

&lt;p&gt;Among other things, the head contains information like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The page title in the &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; tag.&lt;/li&gt;
&lt;li&gt;Links to scripts and style files.&lt;/li&gt;
&lt;li&gt;Meta tags with browser instructions and directions.&lt;/li&gt;
&lt;li&gt;Social media and SEO tags for web crawlers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although some of that information may be visible to the user (the title is displayed on the tab name, or a social media image is shown on posts), generally the data in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; is invisible to the site's visitors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Header: Introductions and&amp;nbsp;Banners
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The header of a page is an introduction section usually located at the top&lt;/strong&gt; that contains things like the title, a short description, navigation, a hero banner, or a search box. It can be represented by &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/header" rel="noopener noreferrer"&gt;the &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt; semantic HTML element&lt;/a&gt;, and it is very much visible.&lt;/p&gt;

&lt;p&gt;While normally every page has a "main header," there can be multiple headers on a page: an &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; may have a header, so may a &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; or the &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; content of the page, as well as an &lt;code&gt;&amp;lt;aside&amp;gt;&lt;/code&gt;. So a single page may have several headers, or none at all.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzvuv68kw6bii4opfz4wk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzvuv68kw6bii4opfz4wk.png" alt="DEV.to homepage with arrows pointing to different section headers" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Maybe because designers don't usually deal with the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; code, or because "head" is a shorter way of saying "header" (and after all, it usually sits on top of the page, but not always), they often use the terms interchangeably. That can be a bit confusing for developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Heading: The Content Hierarchy
&lt;/h2&gt;

&lt;p&gt;In essence, &lt;strong&gt;a heading is the title of the page or a section&lt;/strong&gt;. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/Heading_Elements" rel="noopener noreferrer"&gt;The &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;-&lt;code&gt;&amp;lt;h6&amp;gt;&lt;/code&gt; family of HTML elements&lt;/a&gt; represent headings.&lt;/p&gt;

&lt;p&gt;They are sometimes called headers, other times called headlines... and they are neither! A header may contain a heading, but doesn't have to (see the feed header in the picture above); And headlines may use a heading, but they are not defined by it, they tend to have other elements too (more about this on the next section).&lt;/p&gt;

&lt;p&gt;We use headings to define the outline of the content, providing hierarchy both for humans (text is larger and more identifiable) and machines (labeling each section for better accessibility and SEO results.)&lt;/p&gt;

&lt;p&gt;One important thing: &lt;strong&gt;use headings for structure, not for layout&lt;/strong&gt;. Do not use a &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;-&lt;code&gt;&amp;lt;h6&amp;gt;&lt;/code&gt; tag to make text look bigger or bolder. By doing that, we break the hierarchy of the page and it can be really confusing for assistive technology users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Headline: Editorial Content
&lt;/h2&gt;

&lt;p&gt;Usually, the headline is the big eye-catching text that introduces the page or section... just like on a newspaper! &lt;strong&gt;A headline is not an HTML concept, it is an editorial one&lt;/strong&gt;; but developers often try to interpret it as a header or even just a heading.&lt;/p&gt;

&lt;p&gt;And that is where confusion starts: a headline is for message delivery while headers and headings  are for structure and hierarchy, respectively. Yes, headlines may contain headings, but they are not defined by the headings. There's more to them: titles, subtitles, calls to action...&lt;/p&gt;

&lt;p&gt;There isn't a direct semantic HTML equivalent to a headline. The closest thing would be &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/hgroup" rel="noopener noreferrer"&gt;the &lt;code&gt;&amp;lt;hgroup&amp;gt;&lt;/code&gt; element&lt;/a&gt;, but it has gone through many semantic changes over time and would only represent a really basic version of a headline (with a heading and a paragraph)&lt;/p&gt;

&lt;p&gt;Some designers use "headline" as shorthand for "the big text at the top," even when it's a UI component instead of editorial content. Those cases are more of a combination of a heading and multiple buttons, which in my opinion would follow more into the header category... but I'm just a developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;And that's it! Those are &lt;strong&gt;the 4 Hs of HTML: Head, Header, Heading, and Headline&lt;/strong&gt;, and what each of them represents.&lt;/p&gt;

&lt;p&gt;Here's a quick summary table with all of them:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3hrtkyeq0qaxa7yzwzf5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3hrtkyeq0qaxa7yzwzf5.png" alt="table describing head, header, heading, and headline" width="798" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you may have noticed, their names are really close, and their functionality, while different, intertwines. They often go together or are combined in some manner.&lt;/p&gt;

&lt;p&gt;But it is really important to understand their differences and have clear naming conventions to avoid miscommunications (and extra work) between the design and the development teams.&lt;/p&gt;




&lt;p&gt;How about you? Have you ever "argued" or run into miscommunications with a designer or a developer who called a head a header?&lt;/p&gt;

</description>
      <category>html</category>
      <category>webdev</category>
    </item>
    <item>
      <title>comiCSS #255: Yellow</title>
      <dc:creator>Alvaro Montoro</dc:creator>
      <pubDate>Mon, 24 Aug 2026 23:10:34 +0000</pubDate>
      <link>https://dev.to/alvaromontoro/comicss-255-yellow-1bj</link>
      <guid>https://dev.to/alvaromontoro/comicss-255-yellow-1bj</guid>
      <description>&lt;p&gt;comiCSS is a side project I've been running for a while. I code (yes, code) comics about HTML and CSS in HTML and CSS. Every week, I publish a new cartoon (or at least I try).&lt;/p&gt;

&lt;p&gt;This week's cartoon was inspired by a &lt;a href="https://imgur.com/gallery/i-was-reminded-of-this-one-other-day-i-can-hardly-believe-i-first-posted-19-years-ago-its-like-they-say-time-flies-when-youre-wasting-online-W9esbWF" rel="noopener noreferrer"&gt;Jim Benton's cartoon from 20 years ago&lt;/a&gt;. It is goofy, it is absurd, but it is funny... or at least I found it funny enough to make a CSS-themed version (actually, two!)&lt;/p&gt;

&lt;p&gt;The original hand-drawn version has more character, but I am also fond of like the childish kawaii version I did... even when it doesn't fully make sense in CSS (the yellows are actually the values indicated by the bottles, but #pee isn't a color, and making it #fee wouldn't be obvious as a joke).&lt;/p&gt;

&lt;p&gt;I did a second version that I'm putting on the website as alternative. It is more CSS-oriented:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffxix3y6b7rz1ymddevgh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffxix3y6b7rz1ymddevgh.png" alt="cartoon with four cups filled with a yellow liquid, all look really happy (except the last one that looks in shock and concerned). The first one says 'I am oklab(93.4% -11.75% 46.5%)' The second one says 'I am oklab(96.8% -17.75% 49.75%)' The third one says 'I am oklab(95.6% -21.5% 46.5%)' And the last one says " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This version came second, but I like it more than the first one. Still goofy and a bit of a potty joke, but not as childish as the other one. And it uses more modern CSS too. So that’s nice.&lt;/p&gt;

&lt;p&gt;What do you think? Do you like any of the two versions?&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Permalink: &lt;a href="https://comicss.art/comics/255" rel="noopener noreferrer"&gt;https://comicss.art/comics/255&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Image link: &lt;a href="https://comicss.art/comics/255/yellow.png" rel="noopener noreferrer"&gt;https://comicss.art/comics/255/yellow.png&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Source code: &lt;a href="https://comicss.art/comics/255/yellow.html" rel="noopener noreferrer"&gt;https://comicss.art/comics/255/yellow.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>watercooler</category>
      <category>humor</category>
    </item>
    <item>
      <title>RGB is dead, long live RGB!</title>
      <dc:creator>Alvaro Montoro</dc:creator>
      <pubDate>Fri, 21 Aug 2026 18:05:59 +0000</pubDate>
      <link>https://dev.to/alvaromontoro/rgb-is-dead-long-live-rgb-2219</link>
      <guid>https://dev.to/alvaromontoro/rgb-is-dead-long-live-rgb-2219</guid>
      <description>&lt;p&gt;Wait a second! The original sentence is "&lt;em&gt;The king is dead, long live the king!&lt;/em&gt;" But in that case, the first king is not the same as the second king. So wouldn't it be better to say something like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;RGB is dead, long live&amp;nbsp;OKLCH!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's much better. It is clearer that RGB –and the "RGB-based" colors like HEX and even HSL– are no longer the things to use in CSS. There's a &lt;em&gt;new sheriff in town&lt;/em&gt;, that's OKLCH, and it's the color format that should be used moving forward.&lt;/p&gt;

&lt;p&gt;Except... is that really the case?&lt;/p&gt;

&lt;p&gt;OKLCH has many positive features that make it an ideal candidate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It supports more colors&lt;/strong&gt;: &lt;a href="https://lea.verou.me/blog/2020/04/lch-colors-in-css-what-why-and-how/#1.-we-actually-get-access-to-about-50%25-more-colors." rel="noopener noreferrer"&gt;50% more displayable colors than standard RGB&lt;/a&gt;! And that's a lot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It handles the &lt;a href="https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl#color-modifications-in-css" rel="noopener noreferrer"&gt;lightness in a more consistent way&lt;/a&gt; than RGB&lt;/strong&gt;: two colors with the same L value will have a similar perceived darkness/lightness.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It is &lt;a href="https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl#comparing-oklch-with-other-css-color-formats" rel="noopener noreferrer"&gt;more human-readable&lt;/a&gt;&lt;/strong&gt;: definitely true for lightness (refer to previous point), but debatable for hue and chroma.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It is &lt;a href="https://atmos.style/blog/lch-color-space" rel="noopener noreferrer"&gt;more focused in human perception than in the machine&lt;/a&gt;&lt;/strong&gt;: the way it represents colors is closer to how the human eye perceives them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More &lt;a href="https://blog.jim-nielsen.com/2023/ok-lch-im-convinced/" rel="noopener noreferrer"&gt;natural transformations between colors&lt;/a&gt;&lt;/strong&gt;: no more unexpected jumps in colors or gray in-betweens.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In summary, &lt;strong&gt;OKLCH is amazing&lt;/strong&gt;. More available colors, better perception, better transformations... It beats RGB in almost any aspect that we compare the two. But does that mean you should ditch RGB and update all your projects into OKLCH?&lt;/p&gt;

&lt;p&gt;Well... the answer is "it depends." RGB is not being removed from the standard and will always work in CSS. OKLCH provides brighter and more vibrant colors, but not all designs will require them.&lt;/p&gt;

&lt;p&gt;But it also comes with some baggage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It is widely supported... except by not-so-old browsers&lt;/strong&gt;: this problem will die down with old browsers but, at this moment, around &lt;a href="https://caniuse.com/?search=oklch" rel="noopener noreferrer"&gt;7% of the browsers online don't support OKLCH&lt;/a&gt;. It is small number, but big enough to consider fallbacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It requires heavier calculations than RGB&lt;/strong&gt;: color spaces like LCH have been around for decades, but they weren't implemented on the web earlier due to hardware limitations. OKLCH was created in late 2020 to solve some of those limitations and rendering issues, but &lt;a href="https://gradientshub.com/blog/getting-started-with-oklch-colors-and-useful-color-tools/#be-aware-of-oklchs-limitations" rel="noopener noreferrer"&gt;still requires more computation than other color spaces&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The support is changing rapidly as browsers get deprecated, and the heavier computational cost is not a big deal as modern browsers are optimizing this instantly, so it is a low price to pay.&lt;/p&gt;

&lt;p&gt;And you may be using OKLCH without knowing! &lt;a href="https://x.com/LeaVerou/status/1583121355813564421" rel="noopener noreferrer"&gt;Some &lt;strong&gt;browsers use OKLCH to interpolate transition colors&lt;/strong&gt;&lt;/a&gt; because, as mentioned above, the transition between colors is more natural. So, it doesn't matter if you use OKLCH, RGB, Lab, HEX, or HSL... behind the scenes, they'll be converted to OKLCH for color transitions.&lt;/p&gt;

&lt;p&gt;In summary, &lt;strong&gt;OKLCH is a superior format&lt;/strong&gt; in many aspects and should be the favorite choice moving forward, especially &lt;strong&gt;if you want to get vibrant colors, precise control, and more natural gradient interpolations&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But don't feel obligated to drop the color format that you love to jump into OKLCH! RGB (and all the other color formats in CSS) are here to stay. As with all things in web development, use the tool that you need. And in some cases, OKLCH may not be needed.&lt;/p&gt;

&lt;p&gt;I plan to still use RGB and hex in many of my sites to define font or background colors. They may seem &lt;em&gt;old and rusty&lt;/em&gt;, but that's just &lt;code&gt;#FFA500&lt;/code&gt; for you! And it just works nicely.&lt;/p&gt;

</description>
      <category>css</category>
      <category>html</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Fancy Clipping with CSS</title>
      <dc:creator>Alvaro Montoro</dc:creator>
      <pubDate>Mon, 17 Aug 2026 05:03:03 +0000</pubDate>
      <link>https://dev.to/alvaromontoro/fancy-clipping-with-css-4je7</link>
      <guid>https://dev.to/alvaromontoro/fancy-clipping-with-css-4je7</guid>
      <description>&lt;p&gt;&lt;strong&gt;I have been using &lt;code&gt;clip-path&lt;/code&gt; for ages, especially for CSS Art, but I was today years old when I learned some of the features that are available for the &lt;code&gt;polygon()&lt;/code&gt; function in &lt;code&gt;clip-path&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;The other day, &lt;a href="https://bsky.app/profile/css-only.dev" rel="noopener noreferrer"&gt;Temani Afif&lt;/a&gt; shared a demo that included some weird (to me) syntax for the &lt;code&gt;polygon()&lt;/code&gt; function that allowed creating rounded shapes. It included the keyword &lt;code&gt;round&lt;/code&gt; and a length. Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nl"&gt;clip-path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;polygon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="m"&gt;55%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;71%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;71%&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;55%&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10%&lt;/span&gt; &lt;span class="m"&gt;10%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have always used &lt;code&gt;polygon()&lt;/code&gt; specifying a series of points that were used to clip the element that ended with really sharp edges. So, the first thing I thought was "&lt;em&gt;This must be some Chrome-only experiment or something.&lt;/em&gt;" And I was partially correct. Yes, it only works on Chrome at the moment, but the &lt;a href="https://www.w3.org/TR/css-shapes/" rel="noopener noreferrer"&gt;rounded behavior is defined in the CSS specification&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have code that specifies roundness in the polygon, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;clip-path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;polygon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="m"&gt;55%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;71%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;71%&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;55%&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10%&lt;/span&gt; &lt;span class="m"&gt;10%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will get a rounded figure with &lt;code&gt;clip-path&lt;/code&gt;. For the code above, it would be this (only on Chrome):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8mkg8a2dwy5imv02sdmv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8mkg8a2dwy5imv02sdmv.png" alt="" width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;
A rounded star in Chrome using clip-path&amp;nbsp;:)&lt;br&gt;&amp;nbsp;



&lt;p&gt;I have to admit, for me this was a mind-blown type of moment. Getting rounded edges before this required masking with SVG, or coming up with relatively complex native CSS, including masks and gradients. (Although thee &lt;a href="https://www.w3.org/TR/css-shapes/#shape-function" rel="noopener noreferrer"&gt;the &lt;code&gt;shape()&lt;/code&gt; function&lt;/a&gt; makes this considerably easier now.)&lt;/p&gt;

&lt;p&gt;This feature is amazing, especially for the CSS Art that I like coding, but there's a big issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Support and Progressive Enhancement
&lt;/h2&gt;

&lt;p&gt;As I have mentioned a few times before, this rounded feature is in the specs but at the moment it is only supported by Chrome. So... what happens when it runs on other browsers like Firefox or Safari?&lt;/p&gt;

&lt;p&gt;Unfortunately, the answer is not good: the function is considered invalid and it is completely ignored. Which means that not only do we not get a rounded polygon, we don't get a polygon at all!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6stog523nxenzr7h26f7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6stog523nxenzr7h26f7.png" alt="" width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;
The same rounded star on Safari and Firefox&amp;nbsp;:(&lt;br&gt;&amp;nbsp;



&lt;p&gt;In the future we could use the CSS &lt;code&gt;@if&lt;/code&gt; and &lt;code&gt;@function&lt;/code&gt; at rules to have a &lt;code&gt;rounded-polygon()&lt;/code&gt; function that would do this for us, but for now we need to find an alternative to progressively enhance the feature or gracefully degrade if it is not supported.&lt;/p&gt;

&lt;p&gt;But there is something that we can currently do: use the &lt;code&gt;@supports&lt;/code&gt; at-rule combined with custom properties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;--round-clip&lt;/span&gt;&lt;span class="p"&gt;:;&lt;/span&gt;

  &lt;span class="k"&gt;@supports&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;clip-path&lt;/span&gt;&lt;span class="nd"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;polygon&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;round&lt;/span&gt; &lt;span class="nt"&gt;1px&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;0&lt;/span&gt; &lt;span class="nt"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;0&lt;/span&gt; &lt;span class="nt"&gt;0&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;--round-clip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;round&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* notice the comma! */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;...
  &lt;/span&gt;&lt;span class="nl"&gt;clip-path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;polygon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;round-clip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="m"&gt;55%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;71%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;71%&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;55%&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10%&lt;/span&gt; &lt;span class="m"&gt;10%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, by default the variable will be empty, so we will get the "classic" clip-path with pointy edges. But, if rounded clipping is supported, the custom property will have a value that makes the clip-path have rounded edges:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5dlmdjfn82gz48dwn2cz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5dlmdjfn82gz48dwn2cz.png" alt="" width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;
Pointy star by default (left), and rounded star if supported (right)&amp;nbsp;:D&lt;br&gt;&amp;nbsp;



&lt;p&gt;I will not get into the weeds of how the roundness is calculated, but the CSS specification has a section with an explanation and many details on that.&lt;/p&gt;

&lt;h2&gt;
  
  
  But wait... there's&amp;nbsp;more!
&lt;/h2&gt;

&lt;p&gt;While the rounded paths are not supported by all browsers, there is another feature that I didn't know about and it is actually widely supported, even by Safari and Firefox: fill rules.&lt;/p&gt;

&lt;p&gt;When you define a &lt;code&gt;clip-path&lt;/code&gt;, all the area inside the path will be selected and visible, but developers can specify different keywords to have some control over that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;nonzero&lt;/code&gt; (default): the points inside the path will not be clipped.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;evenodd&lt;/code&gt;: everything outside the path will be clipped, but within the path, it will depend on the count of lines and path edges around each point. If it's even, it will be clipped; if it's odd, it won't and it will be visible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is an oversimplification. The SVG specification has a more detailed explanation of how both keywords work, and I encourage you to read it.&lt;/p&gt;

&lt;p&gt;Here's the example of the star from before using &lt;code&gt;nonzero&lt;/code&gt; (default, could be omitted) and &lt;code&gt;evenodd&lt;/code&gt; fill rules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.div1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;...
  &lt;/span&gt;&lt;span class="nl"&gt;clip-path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;polygon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nonzero&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="m"&gt;55%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;71%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;71%&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;55%&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10%&lt;/span&gt; &lt;span class="m"&gt;10%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.div2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;...
  &lt;/span&gt;&lt;span class="nl"&gt;clip-path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;polygon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;evenodd&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="m"&gt;55%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;71%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;71%&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;55%&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10%&lt;/span&gt; &lt;span class="m"&gt;10%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8fc9wd6e8j6ldaz6htxw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8fc9wd6e8j6ldaz6htxw.png" alt="" width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;
nonzero clipping (left) vs evenodd clipping&amp;nbsp;(right)&lt;br&gt;&amp;nbsp;



&lt;p&gt;The &lt;code&gt;nonzero&lt;/code&gt; and &lt;code&gt;evenodd&lt;/code&gt; fill rules would go before the &lt;code&gt;round&lt;/code&gt; keyword if we are applying rounded clip paths. No comma separating the two. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;...
  &lt;/span&gt;&lt;span class="nl"&gt;clip-path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;polygon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nonzero&lt;/span&gt; &lt;span class="n"&gt;round&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="m"&gt;55%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;71%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;71%&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fill-rules syntax not only works for &lt;code&gt;polygon()&lt;/code&gt;. It also works with &lt;code&gt;shape()&lt;/code&gt; and &lt;code&gt;path()&lt;/code&gt;, so it's nice to get acquainted with it.&lt;/p&gt;




&lt;p&gt;One of the fascinating things about CSS is how complete (and sometimes complex) it can be. You think you know about it and, boom! There's something different, and not necessarily new that you learn about it... even when you have used it continuously. You have to love that.&lt;/p&gt;

&lt;p&gt;Here's an interactive demo that lets you play with the values described above: roundness, fill rules, and fallbacks (will only make a difference on Safari and Firefox). Tweak the controls and see how the star changes.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/alvaromontoro/embed/yygdaXo?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>css</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Don't Use A Class For That!</title>
      <dc:creator>Alvaro Montoro</dc:creator>
      <pubDate>Fri, 07 Aug 2026 15:08:14 +0000</pubDate>
      <link>https://dev.to/alvaromontoro/dont-use-a-class-for-that-23l0</link>
      <guid>https://dev.to/alvaromontoro/dont-use-a-class-for-that-23l0</guid>
      <description>&lt;p&gt;Developers &lt;em&gt;love&lt;/em&gt; classes. They sprinkle them everywhere: &lt;code&gt;.hidden&lt;/code&gt;, &lt;code&gt;.loading&lt;/code&gt;, &lt;code&gt;.active&lt;/code&gt;... But HTML already gives us attributes that do the job better. Attributes that are semantic, standardized, and supported across browsers. So, why reinvent the wheel? Let the browser handle the heavy lifting, and improve SEO and accessibility in the process.&lt;/p&gt;

&lt;p&gt;Instead of adding more and more custom classes, embrace the platform and its versatility: use native attributes. Some times they may seem a little more verbose, but that's not always the case and the benefits justify it.&lt;/p&gt;

&lt;p&gt;Here are some common native HTML attributes that can be used instead of classes.&lt;/p&gt;

&lt;h2 id="hidden"&gt;[hidden]&lt;/h2&gt;

&lt;p&gt;Why defining a &lt;code&gt;.hidden&lt;/code&gt; class (globally or per component), when you can just use the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/hidden" rel="external nofollow noopener noreferrer"&gt;&lt;code&gt;hidden&lt;/code&gt; attribute&lt;/a&gt;? It's built into HTML, supported across browsers, and doesn't need extra CSS. The browser knows exactly what you mean.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmeqtnbiiktwbu6gjr44o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmeqtnbiiktwbu6gjr44o.png" alt="use the hidden attribute instead of a hidden class" width="799" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In some scenarios, you may need to redefine what &lt;code&gt;[hidden]&lt;/code&gt; will do in CSS, but even on those cases, using the native attribute is more semantic and provides additional context than a custom class.&lt;/p&gt;





&lt;h2 id="required"&gt;[required]&lt;/h2&gt;

&lt;p&gt;Form validation is the perfect ground for over-engineering. It is tempting to add a &lt;code&gt;.required&lt;/code&gt; class in a label or input; instead, rely on the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/required" rel="external nofollow noopener noreferrer"&gt;&lt;code&gt;required&lt;/code&gt; attribute&lt;/a&gt;. The browser enforces it, screen readers announce it, and you don't need JavaScript to validate it! An element with the required attribute can be easily targeted with CSS using &lt;code&gt;[required]&lt;/code&gt; so there's no need to duplicate attribute and class.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1xuvjvzsesl07g50k8yr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1xuvjvzsesl07g50k8yr.png" alt="use the required attribute instead of a required class" width="799" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you added the required class to the label associated with the required control, you can still style everything using &lt;a href="https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Styling_basics/Combinators" rel="external nofollow noopener noreferrer"&gt;combinators&lt;/a&gt; or the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:has" rel="external nofollow noopener noreferrer"&gt;&lt;code&gt;:has()&lt;/code&gt; pseudo-class&lt;/a&gt;.&lt;/p&gt;





&lt;h2 id="disabled"&gt;[disabled]&lt;/h2&gt;

&lt;p&gt;Buttons, inputs, and other form controls often get a &lt;code&gt;.disabled&lt;/code&gt; class, but the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/disabled" rel="external nofollow noopener noreferrer"&gt;&lt;code&gt;disabled&lt;/code&gt; attribute&lt;/a&gt; already exists. It prevents interaction, signals state to assistive technologies, and is baked into the platform.&lt;/p&gt;

&lt;p&gt;Again, why duplicate efforts and specify that a control is disabled using a non-semantic (class) and a semantic (attribute) option? Simplify the code, and keep only the semantic one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8af99li4bat5891do16z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8af99li4bat5891do16z.png" alt="use the disabled attribute instead of a disabled class" width="799" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id="inert"&gt;...or [inert]&lt;/h3&gt;

&lt;p&gt;If you want to "disable" more than just single controls, the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/inert" rel="external nofollow noopener noreferrer"&gt;&lt;code&gt;inert&lt;/code&gt; attribute&lt;/a&gt; is a powerful way to remove interactivity from entire regions. It's cleaner than disabling every child element manually, and easier to style, just using &lt;code&gt;[inert]&lt;/code&gt; to target the element.&lt;/p&gt;





&lt;h2 id="switch"&gt;[switch] or [role="switch"]&lt;/h2&gt;

&lt;p&gt;Another way to target elements without needing to use classes is relying on roles. For example, instead of creating your own &lt;code&gt;.switch&lt;/code&gt; class, use the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/switch_role" rel="external nofollow noopener noreferrer"&gt;ARIA "switch" role&lt;/a&gt; that can be targeted doing &lt;code&gt;[role="switch"]&lt;/code&gt; (or the &lt;code&gt;switch&lt;/code&gt; attribute once it's widely supported). Easy to style and it communicates semantics to assistive technologies. A win-win.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg0ifvhmo0edceill8hay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg0ifvhmo0edceill8hay.png" alt="use ARIA roles instead of a role classes" width="799" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: &lt;strong&gt;As with everything related to accessibility, tread carefully&lt;/strong&gt;. If done properly, it has many benefits for users and developers; but it can be a pain when not. This applies to roles and ARIA attributes like the ones we'll see next.&lt;/p&gt;





&lt;h2 id="aria-current"&gt;[aria-current]&lt;/h2&gt;

&lt;p&gt;A component that every website has is a main navigation menu. And usually, that menu has a highlighted item that is the current page or section. Many times, developers use an &lt;code&gt;.active&lt;/code&gt; class to be able to target that element, but there's an ARIA attribute that could be used to do the same: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-current" rel="external nofollow noopener noreferrer"&gt;&lt;code&gt;aria-current&lt;/code&gt;&lt;/a&gt;. It's semantic, accessible, and works across contexts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fefz8dv2zuwihtftro4sd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fefz8dv2zuwihtftro4sd.png" alt="use the aria-current attribute instead of an active class" width="799" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id="aria-selected"&gt;...or [aria-selected="true"]&lt;/h3&gt;

&lt;p&gt;If you are coding some tabs, instead of using &lt;code&gt;aria-current&lt;/code&gt; you can do &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-selected" rel="external nofollow noopener noreferrer"&gt;&lt;code&gt;aria-selected="true"&lt;/code&gt;&lt;/a&gt; for the current element. It signals which tab is active without relying on random class names.&lt;/p&gt;





&lt;h2 id="aria-busy"&gt;[aria-busy="true"]&lt;/h2&gt;

&lt;p&gt;Skeleton loaders and "loading" states often rely on &lt;code&gt;.loading&lt;/code&gt; or &lt;code&gt;.skeleton&lt;/code&gt; classes. But &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-busy" rel="external nofollow noopener noreferrer"&gt;&lt;code&gt;aria-busy="true"&lt;/code&gt;&lt;/a&gt; can be used for this. It tells assistive technologies the element is updating, and you can target it directly with &lt;code&gt;[aria-busy="true"]&lt;/code&gt; and style it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsqk0ncbti5o7fafo0fr3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsqk0ncbti5o7fafo0fr3.png" alt="use the aria-busy attribute instead of a skeleton or loading class" width="799" height="333"&gt;&lt;/a&gt;&lt;/p&gt;





&lt;h2 id="aria-invalid"&gt;[aria-invalid]&lt;/h2&gt;

&lt;p&gt;Validation errors often get an &lt;code&gt;.error&lt;/code&gt; class, But &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-invalid" rel="external nofollow noopener noreferrer"&gt;&lt;code&gt;aria-invalid&lt;/code&gt;&lt;/a&gt; exists for a reason. It communicates the error state to assistive technologies and gives you a styling hook with &lt;code&gt;[aria-invalid="true"]&lt;/code&gt;. Why not take advantage of it? This may be useful in radio fieldsets or groups of controls.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F05m49cmuesvq0rm5gmrn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F05m49cmuesvq0rm5gmrn.png" alt="use aria-invalid attribute instead of an invalid class" width="799" height="333"&gt;&lt;/a&gt;&lt;/p&gt;





&lt;h2 id="conclusion"&gt;Conclusion: Use Native Attributes&lt;/h2&gt;

&lt;p&gt;Using attributes instead of classes isn't just cleaner, it's more semantic, more accessible, and more future-proof. Classes are arbitrary labels that change from project to project; attributes are part of the language. When you use them, you're speaking HTML fluently instead of hacking around it. And the browser and assistive technologies will thank you for it.&lt;/p&gt;

&lt;p&gt;Stop overusing classes. Let the platform do the work.&lt;/p&gt;          




&lt;p&gt;These are but a sample of all the native attributes that could be used to replace classes. There are many more out there. Do you use attributes like these in your projects to simplify code or improve accessibility? Share them in a comment.&lt;/p&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>10 Cool CodePen Demos (July 2026)</title>
      <dc:creator>Alvaro Montoro</dc:creator>
      <pubDate>Sun, 02 Aug 2026 13:06:08 +0000</pubDate>
      <link>https://dev.to/alvaromontoro/10-cool-codepen-demos-july-2026-bg</link>
      <guid>https://dev.to/alvaromontoro/10-cool-codepen-demos-july-2026-bg</guid>
      <description>&lt;h2&gt;
  
  
  Cut Squares Tessellated Pattern - No Div - Pure CSS
&lt;/h2&gt;

&lt;p&gt;Josetxu used some conic and linear gradients along with custom properties to craft this three-dimensional pattern. It's simple and CSS-only. A nice way to practice backgrounds, sizes and positioning.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/josetxu/embed/RNKxVpv?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  WindowsXP Files
&lt;/h2&gt;

&lt;p&gt;As part of a CodePen challenge, Zerde Turdybek created this web version of a Windows XP folder in which you can open files. A demo for the nostalgic crew :)&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/zerdebek/embed/019f3e1d-f3bc-7b68-a9b5-6e735e912a89?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Inversive Geometry
&lt;/h2&gt;

&lt;p&gt;Another demo by Zerde Turdybek. This time using P5.js to create something more interactive: pull the dots around to move the shapes and change the drawing.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/zerdebek/embed/019fa78c-a3cc-7b02-9a44-5f79a961081b?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  A love letter to Pachinko
&lt;/h2&gt;

&lt;p&gt;Liam Egan developed a Pachinko arcade game, but instead of balls falling into slots, it is letters, and you can control how many by clicking a button... even create some chaos by pressing multiple times quickly. And it is fun an entertaining seeing the letters fall and collide with the dots.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/shubniggurath/embed/ogBMbJK?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Monkey in the water
&lt;/h2&gt;

&lt;p&gt;A minimalist CSS Art by Cassidy. This animated monkey relaxing in water was drawn using only three HTML elements and some CSSS, which is pretty impressive.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/cassidoo/embed/019f439a-d42e-7c1b-a9c3-f17fec2c4f22?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  SKYDREAMS: A 3D 1K FEVER DREAM
&lt;/h2&gt;

&lt;p&gt;This 90s style game reminds of the classic Sonic mini-games. Frank Forece coded it using just 1024 bytes of JavaSCript! Use the mouse to move right and left and click to jump. Have fun! It's not as easy as it seems.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/KilledByAPixel/embed/azpjRdx?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Line Shadows (CSS)
&lt;/h2&gt;

&lt;p&gt;This animation is fully created with HTML and CSS. Figuring out timings, paths, and layers sounds complicated, but the code is incredibly simple. Although that's not surprising as Amit Sheen is world-class at creating 3D CSS animations.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/amit_sheen/embed/019f773a-90e4-7f8e-b51a-76a51c59ccaf?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Water - WebGL Shader
&lt;/h2&gt;

&lt;p&gt;This interactive shader (mouse over to "disturb" the water) by Tamino Martinius feels incredibly realistic. The liquid texture and the waves when moving around seem so natural and smooth. Great job.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/TaminoMartinius/embed/PwWBZYM?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  testing text-fit
&lt;/h2&gt;

&lt;p&gt;Right now, if you want text to expand and grow its size to occupy the whole line width, you need to do some math or resort to hacks (that generally include math or unnecessary animations). In this demo, Temani Afif showcases a new CSS feature landing on the latest Chrome that will simplify considerably that work: text-fit.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/t_afif/embed/WbRKEQr?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  file drawer carousel
&lt;/h2&gt;

&lt;p&gt;Vivi Tseng created this three-dimensional carousel/image gallery that performs really nicely. The transitions are smooth, the code is simple and small, and it can be customized and expanded to fit multiple purposes. I'm not a big fan of carousel, but this is a well-done component.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/vii120/embed/JoEBvya?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




</description>
      <category>html</category>
      <category>css</category>
      <category>showdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>It's always...</title>
      <dc:creator>Alvaro Montoro</dc:creator>
      <pubDate>Thu, 23 Jul 2026 14:48:10 +0000</pubDate>
      <link>https://dev.to/alvaromontoro/its-always-5hgg</link>
      <guid>https://dev.to/alvaromontoro/its-always-5hgg</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6i4cjp411yn0vq4rlzam.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6i4cjp411yn0vq4rlzam.png" alt="The CSS logo with arms, legs, and sad eyes saying: It's always :where() is CSS and never :how() is CSS" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Back after vacation and a short hiatus. Trying to get into speed and back into the routine of drawing comics and cartoons with CSS.&lt;/p&gt;

&lt;p&gt;I like this cartoon, I may put it on a t-shirt and wear it at conferences 😄&lt;/p&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Permalink: &lt;a href="https://comicss.art/comics/252" rel="noopener noreferrer"&gt;https://comicss.art/comics/252&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Image link: &lt;a href="https://comicss.art/comics/252/always.png" rel="noopener noreferrer"&gt;https://comicss.art/comics/252/always.png&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Source code: &lt;a href="https://comicss.art/comics/252/always.html" rel="noopener noreferrer"&gt;https://comicss.art/comics/252/always.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>humor</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>The Sword of Damocles at Work: The Human Cost of Delayed Layoffs</title>
      <dc:creator>Alvaro Montoro</dc:creator>
      <pubDate>Fri, 10 Jul 2026 19:50:17 +0000</pubDate>
      <link>https://dev.to/alvaromontoro/the-sword-of-damocles-at-work-the-human-cost-of-delayed-layoffs-2gon</link>
      <guid>https://dev.to/alvaromontoro/the-sword-of-damocles-at-work-the-human-cost-of-delayed-layoffs-2gon</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;Over a decade ago, my employer announced layoffs that would happen in waves. Every few months another round arrived. Nobody knew the criteria, who would be affected next, or when. The uncertainty was exhausting and took a toll on everyone. This week, Xbox announced a similar plan, and it brought those memories back.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fifteen years ago, the company I worked at announced 38,000 layoffs that would happen in different stages. That was a nerve-wracking experience. They started with 10,000, then months later another 8,000, then months later another 9,000... You never knew the criteria, how or when they would happen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I remember from then was the angst of not knowing what was going to happen.&lt;/strong&gt; The figurative sword of Damocles hanging over our heads, and the helplessness of it all. I don't wish that feeling on anyone.&lt;/p&gt;

&lt;p&gt;At one point, adding layoffs, early retirements, and turnover, they reached the magic number of 38,000. When asked if layoffs would stop then, the explanation we received was that the target referred to layoffs, not overall headcount reduction. So layoffs continued while hiring accelerated.&lt;/p&gt;

&lt;p&gt;During that period, many teams were involved in onboarding and training new employees and contractors, even as layoffs continued. Two weeks after training the new contractors, nearly my entire department was laid off, including myself. Only one person per project remained.&lt;/p&gt;

&lt;p&gt;It was the last batch of layoffs from the original 38,000 they had announced.&lt;/p&gt;

&lt;p&gt;My wife was 6-7 months pregnant. We lost our main source of income and the health insurance right at the moment we needed it the most. The company gave me a severance and offered $2,000 for not coming back in two years. I was interviewing internally so I rejected it. In hindsight, that was a mistake.&lt;/p&gt;

&lt;p&gt;The internal process was rejected after going through a few good interviews. I never received an explanation. So my only option was taking a severance that was shorter than what it could have been, and looking for a new job.&lt;/p&gt;

&lt;p&gt;But that was then.&lt;/p&gt;

&lt;p&gt;It was a hot job market for software developers, and I was lucky to get interviews within weeks, a couple of offers in a matter of a month, and start a new job in 2 months.&lt;/p&gt;

&lt;p&gt;Today, the situation is different.&lt;/p&gt;

&lt;p&gt;This week, &lt;a href="https://www.theverge.com/news/961528/microsoft-layoffs-july-2026-sales-xbox" rel="noopener noreferrer"&gt;Xbox announced 3,200 layoffs&lt;/a&gt;. About half took effect immediately, while the remaining cuts are expected to happen over the next 12 months. No one knows when, who, why, or how. And, from experience, delayed layoffs like this are tough. An unnecessary burden.&lt;/p&gt;

&lt;p&gt;The current job market for software engineers is... "interesting." While during my layoff I wasn't especially worried about finding a job (it was more of a matter of "when" than "if", and we had a baby waiting around the corner), the Xbox layoffs (as many of the current layoffs) come at a time in which "when" or "if" are blurry. There are jobs... but they are tougher to get and come with many conditions and changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layoffs are always painful. But spreading them over months, creates a different kind of burden: uncertainty.&lt;/strong&gt; It builds angst and stress that no one should have to endure, and that doesn't help anyone. Not the people who leave, and not the people who stay.&lt;/p&gt;

&lt;p&gt;To all impacted, I'm sorry you're going through this. Best of luck to everyone.&lt;/p&gt;

</description>
      <category>career</category>
      <category>leadership</category>
      <category>news</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>10 Cool CodePen Demos (June 2026)</title>
      <dc:creator>Alvaro Montoro</dc:creator>
      <pubDate>Sun, 05 Jul 2026 15:29:27 +0000</pubDate>
      <link>https://dev.to/alvaromontoro/10-cool-codepen-demos-june-2026-559</link>
      <guid>https://dev.to/alvaromontoro/10-cool-codepen-demos-june-2026-559</guid>
      <description>&lt;h2&gt;
  
  
  Sand bottle - WebGPU
&lt;/h2&gt;

&lt;p&gt;Remember those bottles filled with colored sand that you can find in many souvenir stores? Liam Egan created a digital version using JavaScript WebGPU API. Click to drop sand, use the arrows to tilt and shake the bottles, and relax while enjoying this sandy demo.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/shubniggurath/embed/QwdEKzb?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Button State Builder
&lt;/h2&gt;

&lt;p&gt;Margarita shared this button builder that allows to customize a control with icons, text, color, shape... even all the behavior in the different states of the button. Then you can easily get the HTML, CSS, and JS code to put it on any website. Pretty cool.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/Margarita-the-solid/embed/XJpgEXm?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  WebGL Switch Button
&lt;/h2&gt;

&lt;p&gt;In this demo, the whole page turns into a giant three-dimensional toggle switch that can be activated clicking anywhere on the viewport. Explore the component: mouse over to make the component tilt or scroll to zoom in and out. A nice job by Toc.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/ol-ivier/embed/emgEQma?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Animated radial gradient mask over text
&lt;/h2&gt;

&lt;p&gt;This demo is exactly what the title says: a radial gradient applied as a mask to some text. Cassidy aligned it perfectly with the hole in the O from "Hello" that makes this effect &lt;em&gt;chef's kiss&lt;/em&gt;. You will need to uncomment the animation property in CSS to see the demo in action.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/cassidoo/embed/QwdMQVm?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  221.
&lt;/h2&gt;

&lt;p&gt;ycw always creates impressive and original content. And this demo delivers. It's not only the effect in itself, but the use of light and shadows, and the perfecto choice of color that adds a timeless atmosphere. Beautiful.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/ycw/embed/NPddqdm?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  vRLbdoSAIsoSQvisac
&lt;/h2&gt;

&lt;p&gt;Mustafa Enes created different versions of this idea over the past month, all of them are great, but I picked this one as it is more interactive. Click on the screen to regenerate the pattern and move the mouse around to animate the colors. I don't know why, but there's a feeling of peace and joy while doing it.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/pavlovsk/embed/gbgxXMo?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  beach sunset
&lt;/h2&gt;

&lt;p&gt;I saw several demos by Vivi Tseng that caught my attention this month. Really enjoyed the general minimalistic style they all had and finally picked this animated one because it feels simple and pure, almost like a drawing a child would do during a vacation. I really enjoyed it.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/vii120/embed/vEgZPpR?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Color Name Wheel
&lt;/h2&gt;

&lt;p&gt;Mixing real CSS color names with invented ones (I'd fight for Tangerine Tango to be included in the specs), David Aerne sorts colors based on hue (angle) and lightness (radius) to create this colorful spinning spiral.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/meodai/embed/019f0e2a-86fc-7ab0-bb81-9fca26a7db6e?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Wiggly/Wavy Range Slider
&lt;/h2&gt;

&lt;p&gt;Temani Afif always comes with impressive CSS-only components, and this is an example of them. This demo ingeniously combines view transitions with shapes, offsets, and some properties to generate this squiggly component that should be, at least in theory, impossible. Note: this component only looks like this on Chromium.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/t_afif/embed/zxNwjKa?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Fun, animated link effects using paths and GSAP
&lt;/h2&gt;

&lt;p&gt;If these colors and effects look familiar, that's because you've probably seen some of Josh Dillon's work with toggles before (and if you haven't, check them out!). Interactive and fun text effects that can be easily created with GSAP.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/jdillon/embed/ZYBNamz?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




</description>
      <category>html</category>
      <category>css</category>
      <category>showdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>10 Cool CodePen Demos (May 2026)</title>
      <dc:creator>Alvaro Montoro</dc:creator>
      <pubDate>Tue, 23 Jun 2026 20:10:37 +0000</pubDate>
      <link>https://dev.to/alvaromontoro/10-cool-codepen-demos-may-2026-42ni</link>
      <guid>https://dev.to/alvaromontoro/10-cool-codepen-demos-may-2026-42ni</guid>
      <description>&lt;h2&gt;
  
  
  Rheinturm Lichtzeitpegel Clock
&lt;/h2&gt;

&lt;p&gt;Niklas Knaack drew this clock using HTML and CSS: gradients, paths, animations... and added a little JavaScript to change the lights so the clock is always in time. An impressive drawing.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/NiklasKnaack/embed/ByQjLor?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Bioluminescent Tree
&lt;/h2&gt;

&lt;p&gt;This virtual tree changes colors and shapes every time it is generated (and you can click on it to generate it faster). The game the colors pop up and illuminate the tree are mesmerizing. Great job by Mustafa Enes.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/pavlovsk/embed/azBLvma?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  theSymmetrishQuality
&lt;/h2&gt;

&lt;p&gt;Another generative art piece, this time by Sophia (fractal kitty), that is often in these lists with her demos. This time, the lines that form the spiral move hypnotically and peacefully... they kind of remind me of the wind lines in the news weather forecast on TV. Relaxing.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/fractalkitty/embed/qEqrqoW?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  The Never Ending Story
&lt;/h2&gt;

&lt;p&gt;This infinite scroll experience was crafted by Joe Ben Taylor using Lenis and GSAP. It is interesting because the parallax effect is not just a very high page, it really goes forever and snaps perfectly as you scroll.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/joebentaylor/embed/emBEyNa?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Light card
&lt;/h2&gt;

&lt;p&gt;Amit Sheen crafted this floating card using HTML and CSS only (the demo includes a little JS, but it is for updating a CSS custom property). The result is stunning, especially considering that all the lights and shadows are achieved using CSS.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/amit_sheen/embed/019e6bec-70b1-7a35-a0e2-733c6500e561?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  The Witching Hour
&lt;/h2&gt;

&lt;p&gt;More CSS art! This time it is Gemma Croad who coded this peaceful night scene with purple lilies. It is amazing what she can achieve by combining shapes and gradients.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/GemmaCroad/embed/OPbpbqx?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Infinite Animation Speed Control
&lt;/h2&gt;

&lt;p&gt;By using custom properties and the turn unit instead of hardcoded values, Temani Afif is able to spin these figures smoothly in either direction. Try it, mouse over them and check how the spinning changes naturally.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/t_afif/embed/pvNvdVX?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  shape() generator
&lt;/h2&gt;

&lt;p&gt;This demo is from a testing account by Miss Fox. It is a simple to use shape generator for the experimental shape() function in CSS. It is easy to use and convenient, and it can be used also to learn and understand the different possibilities of this feature.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/Miss-Fox/embed/019d8950-eae1-72dd-84c1-d62891d57798?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  FLIP text
&lt;/h2&gt;

&lt;p&gt;Steve Gardner creates amazing things with code. This animated words is an example of that. He expands, collapse, removes, and attaches letters to transform words smoothly with GSAP in this looping animation.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/ste-vg/embed/019dfa56-bc85-76f2-9c18-6ce734ecb515?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Another world
&lt;/h2&gt;

&lt;p&gt;A fantasy world from a the large windows of a castle or palace, that is as beautiful as it is dark. Created with WebGL, this demo by Liam Egan is impressive and evocative. I wish there was a way to move the camera to see more of the landscape.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/shubniggurath/embed/jEVWYOv?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




</description>
      <category>html</category>
      <category>css</category>
      <category>showdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
