Lea Verou’s blog: Recent Episodes

None

View Details

Reading Time: 2 minutesToday I am mourning. What am I mourning? Encapsulation. At least in my projects.

As a library author, I’ve decided to avoid private class fields from now on and gradually refactor them out of my existing libraries.

Why did I make such a drastic decision?

It all started a few days ago, when I was building a Vue 3 app that used Color.js Color objects. For context, Vue 3 uses proxies to implement its reactivity system, just like Mavo did back in 2016 (the first one to do so as far as I’m aware). I was getting several errors and upon tracking them down I had a very sad realization: instances of classes that use private fields cannot be proxied.

I will let that sink in for a bit. Private fields, proxies, pick one, you can’t have both. Here is a reduced testcase illustrating the problem.

Basically, because a Proxy creates a different object, it breaks both strict equality (obj1 === obj2), as well as private properties. MDN even has a whole section on this. Unfortunately, the workaround proposed is no help when proxies are used to implement reactivity, so when I tried to report this as a Vue bug, it was (rightly) closed as wontfix. It would not be possible to fix this in Mavo either, for the same reason.

I joined TC39 fairly recently, so I was not aware of the background when proxies or private class fields were designed. Several fellow TC39 members filled me in on the discussions from back then. A lot of the background is in this super long thread, some interesting tl;drs as replies to my tweet:

So it turns out that if you use private class fields, your instances are buggy when proxied .

See https://t.co/vversOncPK

That’s …very unfortunate. It means you cannot use these objects in @vuejs for example (Vue testcase: https://t.co/fbLDhJ7xWp ) pic.twitter.com/9feLO10srs

— Lea Verou (@LeaVerou) April 24, 2023

After a lot of back and forth, I decided I cannot justify using private properties going forwards. The tradeoff is simply not worth it. There is no real workaround for proxy-ability, whereas for private fields there is always private-by-convention. Does it suck? Absolutely. However, a sucky workaround is better than a nonexistent workaround.

Also, I control the internal implementation of my classes, whereas proxying happens by other parties. As a library user, it must be incredibly confusing to have to deal with errors about access to private fields in a class you did not write.

This was one of the saddest PRs I have ever written https://github.com/LeaVerou/color.js/pull/306

It feels like such a huge step backwards. I’ve waited years for private fields to be supported everywhere and relished when they got there. I was among the first library authors to adopt them in library code, before a lot of tooling even parsed them properly.

Sure, they were kind of annoying to use (you usually want protected, i.e. visible to subclasses, not actually private), but they were better than nothing. I was not joking in the first paragraph; I am literally grieving.

I may still use private fields on a case by case basis, where I cannot imagine objects being proxied being very useful, for example in web components. But from now on I will not reach to them without thought, like I have been for the past couple of years.

View Details

Reading Time: 2 minutesIt has been over a decade when I launched contrast-ratio.com, an app to calculate the WCAG 2.1 contrast ratio between any two CSS colors. At the time, all similar tools suffered from several flaws when being used for CSS editing:

  • No support for semi-transparent colors (Since WCAG included no guidance for alpha transparency — I had to do original research to calculate the contrast ratio range for that case)
  • No support for color formats other than hex or (at best) RGB with sliders. I wanted something where I could just paste a CSS color just like I had it specified in my code (e.g. hsl(220 10% 90%), possibly tweak it a bit to pass, then paste it back. I didn’t want to use unintuitive hex colors, and I didn’t want to fiddle with sliders.
  • Poor UX, often calculating the actual ratio required further user actions, making iteration tedious

Over the years, contrast-ratio.com grew in popularity: it was recommended in several books, talks, and workshops. It basically became the standard URL developers would visit for this purpose.

However, I’ve been too busy to work on it further beyond just merging pull requests. My time is currently split between the dozens of open source projects I have started and maintain, my TAG work, my CSS WG work, and my teaching & research at MIT.

Therefore, when Ross and Drew from Siege Media approached me with a generous offer to buy the domain, and a commitment to take over maintainship of the open source project, I was cautiously optimistic. But now, after having seen some of their plans for it, I could not be more certain that the future of this tool is much brighter with them.

Please join me in welcoming them to the project and help them get settled in as new stewards!

View Details

Context: In 2020, I ran for the TAG election for the first time and had the great honor of being elected by the W3C membership. This year, I’m running for re-election. The W3C Technical Architecture Group (TAG) is the Working Group that ensures that Web Platform technologies are usable and follow consistent design principles, whether they […]

View Details

Take State of CSS 2022 survey A while ago I posted a call for feedback to inform the design of the State of CSS 2022 survey. The response has been overwhelming and it was glorious. We got quite a lot of proposals, feedback, votes. But that also meant we had to make some tough decisions […]

View Details

I always thought that the semantically appropriate way to represent a rating (e.g. a star rating) is a element. They essentially convey the same type of information, the star rating is just a different presentation. However, trying to style a element to look like a star rating is …tricky at best. Not to […]

View Details

Since 2019, the annual State of CSS survey has collected feedback from web developers from across the world to try and take the pulse of the CSS ecosystem, and it’s become a valuable resource not only for CSS developers, but also for browser vendors. This summer, one of my side projects is helping out with survey […]

View Details

A few days ago I asked Twitter a seemingly simple question (I meant aria-pressed, not aria-selected but Twitter doesn’t allow edits…): For background, I was implementing a web component for an app I’m working on at work and I was getting into some pretty weird rabbit holes with my approach of generating radios and labels. […]

View Details

I recently spoke at CSS Day in Amsterdam. It was only my second f2f talk after the pandemic. It went down really well, both in person, and recently that the video was released: Here is a sample of tweets about it that made me particularly warm and fuzzy inside: There’s a lot more where these […]

View Details

Related: Chris’ blog post for the release of Color.js This post has been long overdue: Chris and I started working on Color.js in 2020, over 2 years ago! It was shortly after I had finished the Color lecture for the class I was teaching at MIT and I was appalled by the lack of color […]

View Details

This week has been Yak Shaving Galore. It went a bit like this: I’ve been working on a web component that I need for the project I’m working on. More on that later, but let’s call it for now. Of course that needs to be developed as a separate reusable library and released as […]

View Details

When developing customizable components, one often wants to expose various parameters of the styling as custom properties, and form a sort of CSS API. This is still underutlized, but there are libraries, e.g. Shoelace, that already list custom properties alongside other parts of each component’s API (even CSS parts!). Note: I’m using “component” here broadly, […]

View Details

If you’ve been writing CSS for any length of time, you’re probably familiar with the em unit, and possibly the other type-relative units. We are going to refer to em for the rest of this post, but anything described works for all type-relative units. As you well know, em resolves to the current font size […]

View Details

Today I ran into an interesting problem. Interesting because it’s one of those very straightforward, deceptively simple questions, that after a fair amount of digging, does not appear to have a definite answer (though I would love to be wrong!). The problem was to determine if the current tab is active. Yes, as simple as […]

View Details

(I always wanted to do a clickbait title like this and when this chance came along I could not pass it up. 😅 Sorry!) While putting my ideas into slides for my Dynamic CSS workshop for next week, I was working on a slide explaining how the CSS wide keywords work with custom properties. inherit, […]

View Details

By now, you probably know that you can use custom properties for individual color components, to avoid repeating the same color coordinates multiple times throughout your theme. You may even know that you can use the same variable for multiple components, e.g. HSL hue and lightness: Here is a very simple page designed with this […]

View Details

One of the things I’ve been doing for the past few months (on and off—more off than on TBH) is rewriting Bliss to use ESM 1. Since Bliss v1 was not using a modular architecture at all, this introduced some interesting challenges. Bliss is essentially a collection of helper functions. Most of these functions have […]

View Details

A pattern that has come up a few times in my code is the following: an object has a property which defaults to an expression based on its other properties unless it’s explicitly set, in which case it functions like a normal property. Essentially, the expression functions as a default value. Some examples of use […]

View Details

Update: I got elected!! Thank you so much to every W3C member organization who voted for me. 🙏🏼 Now on to making the Web better, alongside fellow TAG members! Context: I’m running for one of the four open seats in this year’s W3C TAG election. The W3C Technical Architecture Group (TAG) is the Working Group […]

View Details

Earlier today, I was briefly entertaining the idea of writing a library to wrap and enhance querySelectorAll in certain ways. I thought I’d rather not introduce a Parsel dependency out of the box, but only use it to parse selectors properly when it’s available, and use more crude regex when it’s not (which would cover […]

View Details

Five years ago, I had written this extensive Smashing Magazine article detailing multiple different methods for creating simple pie charts, either with clever use of transforms and pseudo-elements, or with SVG stroke-dasharray. In the end, I mentioned creating pie charts with conic gradients, as a future technique. It was actually a writeup of my “The […]

View Details

What if I told you you could use a single property value to turn multiple different values on and off across multiple different properties and even across multiple CSS rules? What if I told you you could turn this flat button into a glossy skeuomorphic button by just tweaking one custom property --is-raised, and that […]

View Details

Web Components had so much potential to empower HTML to do more, and make web development more accessible to non-programmers and easier for programmers. Remember how exciting it was every time we got new shiny HTML elements that actually do stuff? Remember how exciting it was to be able to do sliders, color pickers, dialogs, […]

View Details

I made this chart in the amazing Excalidraw about two weeks ago: It only took me 10 minutes! Shortly after, my laptop broke down into repeated kernel panics, and it spent about 10 days in service (I was in a remote place when it broke, so it took some time to get it to service). […]

View Details

I’ve posted before about my work for the Web Almanac this year. To make it easier to calculate the stats about CSS selectors, we looked to use an existing selector parser, but most were too big and/or had dependencies or didn’t account for all selectors we wanted to parse, and we’d need to write our […]

View Details

For some of the statistics we are going to study for this year’s Web Almanac we may end up needing a list of CSS shorthands and their longhands. Now this is typically done by maintaining a data structure by hand or guessing based on property name structure. But I knew that if we were going […]

View Details

In case you haven’t heard, ECMAScript modules (ESM) are now supported everywhere! While I do have some gripes with them, it’s too late for any of these things to change, so I’m embracing the good parts and have cautiously started using them in new projects. I do quite like that I can just use import […]

View Details

First off, some news: I agreed to be this year’s CSS content lead for the Web Almanac! One of the first things to do is to flesh out what statistics we should study to answer the question “What is the state of CSS in 2020?”. You can see last year’s chapter to get an idea […]

View Details

Many of today’s web crafters were not writing CSS at the time Alex Walker’s landmark article The Cicada Principle and Why it Matters to Web Designers was published in 2011. Last I heard of it was in 2016, when it was used in conjunction with blend modes to pseudo-randomize backgrounds even further. So what is […]

View Details

Chinese translation by Coink Wang Now that optional chaining is supported across the board, I decided to finally refactor Mavo to use it (yes, yes, we do provide a transpiled version as well for older browsers, settle down). This is a moment I have been waiting for a long time, as I think optional chaining […]

View Details

One of my side projects these days is a color space agnostic color conversion & manipulation library, which I’m developing together with my husband, Chris Lilley (you can see a sneak peek of its docs above). He brings his color science expertise to the table, and I bring my JS & API design experience, so […]

View Details

It has been almost a decade since this blog last saw a redesign. In these 9 years, my life changed dramatically. I joined and left W3C, joined the CSS WG, went to MIT for a PhD, published a book, got married, had a baby, among other things. I designed dozens of websites for dozens of […]

View Details

Today I tried to help a friend who is a great computer scientist, but not a JS person use a JS module he found on Github. Since for the past 6 years my day job is doing usability research & teaching at MIT, I couldn’t help but cringe at the slog that this was. Lo […]

View Details

I was always interested in color science. In 2014, I gave a talk about CSS Color 4 at various conferences around the world called “The Chroma Zone”. Even before that, in 2009, I wrote a color picker that used a hidden Java applet to support ICC color profiles to do CMYK properly, a first on […]

View Details

tl;dr: If you just want to quickly get stats for a repo, you can find the app here. The rest of this post explains how it’s built with Mavo HTML, CSS, and 0 lines of JS. Or, if you’d prefer, you can just View Source — it’s all there! One of the cool things about […]

View Details

I like hand-editing my SVGs. Often I will create an initial version in Illustrator, and then export and continue with hand editing. Not only is it a bit of a meditative experience and it satisfies my obsessive-compulsive tendencies to clean up the code, it has actual practical benefits when you need to make certain changes […]

View Details

Today for a bit of code I was writing, I needed to be able to distinguish “x is not defined” ReferenceErrors from any other error within a try...catch block and handle them differently. Now I know what you’re thinking. Trying to figure out exactly what kind of error you have programmatically is a well-known fool’s […]

View Details

Almost 11 years ago, Paul Irish posted this brilliant bookmarklet to refresh all stylesheets on the current page. Despite the amount of tools, plugins, servers to live reload that have been released over the years, I’ve always kept coming back to it. It’s incredibly elegant in its simplicity. It works everywhere: locally or remotely, on […]

View Details

If you use regular expressions a lot, you probably also create them from existing strings that you first need to escape in case they contain special characters that need to be matched literally, like $ or +. Usually, a helper function is defined (hopefully this will soon change as RegExp.escape() is coming!) that basically looks […]

View Details

I just dealt with one of the weirdest bugs and thought you may find it amusing too. In one of my slides for my upcoming talk “Even More CSS Secrets”, I had a Mavo app on a

, and the app included a collection to quickly create a UI to manage pairs of values for […]