Is CSS a Programming Language?

I have a real distaste for this question. It might seem like a fun question to dig into on the surface, but the way it enters public discourse rarely seems to be in good faith. There are ulterior motives at play involving respect, protective emotions, and desires to break or maintain the status quo.

If someone can somehow prove that CSS isn’t a programming language (this is such a gray area that if that was your goal, it wouldn’t be terribly hard to do) then they get to keep on feeling superior in their “real” programming skills and rationalize the fact that they are (likely) paid more than a front-of-the-front-ender specializing in CSS. This is maintaining the status quo.

The reverse can also be true. If you can prove that CSS is a programming language, perhaps you can shift your own company or the industry at large toward equal respect and pay toward front-of-the-front-end developers. This is breaking the status quo.

Let’s say we could all agree on a boolean true or false on if CSS is a programming language. What now? If true, is pay normalized among all web workers? If false, do CSS specialists deserve pay cuts? If true, does everyone start respecting each other in a way they don’t now? If false, do CSS people have to eat lunch in the boiler room? I have doubts that anything will change; hence my distaste for the discussion at all.

Whatever the facts, it’s unlikely most people are going to accept even the possibility that CSS is a programming language. I mean, programs execute, don’t they? Nobody doubts that JavaScript is a programming language, because it executes. You write code and then execute that code. Perhaps you open a terminal window and write:

node my-program.js

Sure as eggs is eggs, that program will execute. You can make “Hello, World!” print to the terminal with console.log("Hello, World!");.

CSS can’t do that! Um, well, unless you write body::after { content: "Hello, World!"; } in style.css

Links on Typography

A few links that I’ve been holding onto:

  • How to pick a Typeface for User Interface and App Design?” by Oliver Schöndorfer. I like the term “functional text” for everything that isn’t display or body type. Look for clearly distinct letters, open shapes, and little contrast. This reminds me of how we have the charmap screen on the Coding Fonts site, but still need to re-shoot most of the screenshots so they all have it.
  • Uniwidth typefaces for interface design by Lisa Staudinger. “Uniwidth typefaces, on the other hand, are proportionally-spaced typefaces, but every character occupies the same space across different cuts or weights.” So you can change the font-weight but the box the type occupies doesn’t change. Nice for menus! This is a different concept, but it reminds me of the Operator typeface (as opposed to Operator Mono) which “is a natural width family, its characters differing in proportion according to their weight and underlying design.”
  • Should we standardize the naming of font weights?” by Pedro Mascarenhas. As in, the literal names as opposed to font-weight in CSS where we already have names and numeric values but are at the mercy of the font. The image of how dramatically different fonts, say Gilroy Heavy and Avenir Heavy, makes the point.
  • About Legibility and Readability” by Bruno Maag. “Functional accessibility” is another good term. We can create heuristics like specific font-sizes that make for good accessibility, but all nuance is lost there. Good typography involves making type readable and legible. Generally, anyway. I realize typography is a broad world and you might be designing a grungy skateboard that is intentionally neither readable nor legible. But if you do achieve readability and legibility, it has sorts of benefits, like aesthetics and me-taking-you-seriously, but even better: accessibility.
  • Font size is useless; let’s fix it” by Nikita Prokopov. “Useless” is maybe strong since it, ya know, controls the font size. But this graphic does make the point. I found myself making that same point recently.

Apparently, You Can Use Route53 as a Blazingly Fast Database

Route53 is DNS management service by AWS. DNS is absolutely not a database, and yet here’s Nicholas Martin writing up some very clever trickery originally done by Corey Quinn:

When you think about it, DNS configuration is actually a very rudimentary NoSQL database. You can view and modify it at any time quite easily through your domain provider’s website, and you can view each “record” just like a row in a database table.

Many services use DNS TXT records to verify domain ownership. You would essentially add or modify a TXT record to store a key/value pair, which the service will then query.

Why? It’s super fast and costs $0.50 + $0.40 per million queries.

There are even libraries (ten34, diggydb) to help do it. I wouldn’t do it just because I’d be scared Amazon wouldn’t like it and cut it off. Plus, ya know, there isn’t exactly auth.

Direct Link to ArticlePermalink

The post Apparently, You Can Use Route53 as a Blazingly Fast Database appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

from CSS-Tricks…

Custom State Pseudo-Classes in Chrome

There is an increasing number of “custom” features on the web platform. We have custom properties (--my-property), custom elements (<my-element>), and custom events (new CustomEvent('myEvent')). At one point, we might even get custom media queries (@media (--my-media)).

But that’s not all! You might have missed it because it wasn’t mentioned in Google’s “New in Chrome 90” article (to be fair, declarative shadow DOM stole the show in this release), but Chrome just added support for yet another “custom” feature: custom state pseudo-classes (:--my-state).

Built-in states

Before talking about custom states, let’s take a quick look at the built-in states that are defined for built-in HTML elements. The CSS Selectors module and the “Pseudo-classes” section of the HTML Standard specify a number of pseudo-classes that can be used to match elements in different states. The following pseudo-classes are all widely supported in today’s browsers:

User action
:hover the mouse cursor hovers over the element
:active the element is being activated by the user
:focus the element has the focus
:focus-within the element has or contains the focus
:visited the link has been visited by the user
:target the element is targeted by the page URL’s fragment
:disabled the form element is disabled
:placeholder-shown the input element is showing placeholder text
:checked the checkbox or radio button is selected
:invalid the form element’s value is invalid
:out-of-range the input element’s value is outside the specificed range
:-webkit-autofill the input element has been autofilled by the browser
:defined the custom element has been registered

Note: For brevity, some pseudo-classes have been omitted, and some descriptions don’t mention every possible use-case.

Custom states

Like built-in elements, custom elements can have different states. A web page that uses a custom element may want to style these states. The custom element could expose its states via CSS classes (class attribute) on its host element, but that’s considered an anti-pattern.

Chrome now supports an API for adding internal states to custom elements. …


You can’t even look at code or documentation for Astro (publicly) yet — it’s an in-progress idea — but you can watch a video of Fred showing it off to Feross.

I gotta admit: it looks awesome. I’m bullish on two major parts of this:

  1. Jamstack is a good idea. Producing static, pre-rendered, minimal (or no) JavaScript pages is smart.
  2. Components are a good idea. Crafting interfaces from composable components is the correct abstraction. JavaScript does it best right now because of things like ES Modules, template literals, web components, deeply developed tooling, etc.

I’m a fan of Eleventy also, and this feels like Eleventy in a way, except that I don’t like any of the templating languages as much as I like JavaScript components.

Here’s a list of some interesting aspects:

  • Like Vue has .vue files and Svelte has .svelte files, Astro has .astro files in a unique format. I like how it enforces JavaScript-at-the-top in a Frontmatter-like format.
  • It doesn’t replace other JavaScript libraries. It’s like a site-builder framework on top of them. You can literally use React and JSX components, or Vue files, or Svelte files, including using that library’s state management solutions. You import them in your Astro files.
  • It has the-filesystem-is-the-default-router, like Next.
  • It has scoped-CSS-by-default like Vue’s <style scoped>, meaning it doesn’t even need CSS Modules since you get all the benefit anyway.
  • It ships no JavaScript to the front-end at all, unless you specifically opt-in to it (or use its :visible syntax, which injects just enough JavaScript to lazy load more as needed).
  • It embraces the idea of Islands Architecture — the idea that most sites are composed of static content with only parts of interactive/dynamic content.
  • The idea of only requesting JavaScript for interactive components if they are visible (via IntersectionObserver) is a first-class citizen of the framework — Kinda like loading="lazy" for anything interactive.
  • They credit Marko (the HTML/JavaScript-kind hybrid language) right on the homepage (for “asking the question”). Reminds me of approaches like Alpine or htmx.

Progress Delayed Is Progress Denied

The bombshell article of the week is from Alex Russell of Google/Chrome. Alex has long been super critical of Apple, particularly about how there is literally no option to run any other browser than Safari on iOS. This article isn’t just fist-waving about that, but a dissertation accusing Apple of real harm to the web platform by sluggish progress on Safari and a no-web-apps App Store.

Apple’s iOS browser (Safari) and engine (WebKit) are uniquely under-powered. Consistent delays in the delivery of important features ensure the web can never be a credible alternative to its proprietary tools and App Store.

I appreciate Alex’s take here. It gives credit where credit is due, it places blame where it feels most fair to place it, and brings data to a complex conversation that deserves it. It’s hard not to get through the article and think that the web would be in a better place should Apple…

  1. Allow alternative browsers on iOS
  2. Allow web apps in the App Store
  3. Move faster with web platform features in Safari

Taking them one at a time…

  1. Do I want this? Yes. It seems reasonable that my $1,000 extremely powerful computer phone should be able to run whatever browser I want, particularly one from a company that makes a really good one and very much wants to ship it on my phone. In reality, I’m sure the complications around this are far beyond my understanding. I always think about that Chrome update that literally broke macOS. Could that happen on iOS? While lack of features might abstractly make for unhappy customers, a bricked phone very directly makes for unhappy customers. I suspect it more boils down to the fact that Google is an advertising company that innovates on tracking technology and Apple is a hardware company that innovates on privacy. That’s a rock-and-hard-place situation and this browser situation is one of the consequences.
  2. Do I want this? Yes. I don’t even know how to make native apps aside from software that turns web apps into native

16px or Larger Text Prevents iOS Form Zoom

This was a great “Today I Learned” for me from Josh W. Comeau. If the font-size of an <input> is 16px or larger, Safari on iOS will focus into the input normally. But as soon as the font-size is 15px or less, the viewport will zoom into that input. Presumably, because it considers that type too small and wants you to see what you are doing. So it zooms in to help you. Accessibility. If you don’t want that, make the font big enough.

Here’s Josh’s exact Pen if you want to have a play yourself.

In general, I’d say I like this feature. It helps people see what they are doing and discourages super-tiny font sizes. What is a slight bummer — and I really don’t blame anyone here — is that not all typefaces are created equal in terms of readability at different sizes. For example, here’s San Francisco versus Caveat at 16px.

San Francisco on the left, Cavet on the right. Caveat looks visually much smaller even though the font-size is the same.

You can view that example in Debug Mode to see for yourself and change the font size to see what does and doesn’t zoom.

The post 16px or Larger Text Prevents iOS Form Zoom appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

from CSS-Tricks…

Jetpack Backup: Roll Back Your WooCommerce Site Without Losing Orders

Here’s a dilemma: what happens if your WooCommerce site has a problem and the quickest and best way to fix it is to roll back to a previous version? The dilemma is, if you roll back the database, you would lose literal customer orders that are stored in the database. That’s not acceptable for an eCommerce store.

Good news: Jetpack Backup won’t do you wrong like that. You can still restore to a prior point, but you won’t lose any customer order or product data.

Do you lose all the orders that came in since that last backup? Nope.

Will the inventory get all screwed up? Nope.

What about the new products that were added after the restore point? Still there.

All that data is treated as immutable. The way that it plays out is that the database is restored to that point (along with everything else) and that all the new product and order data that has changed since then is replayed on top of the database after the restore.

With Jetpack Backup, there’s absolutely no guesswork. Its real-time snapshots feature has a unique feature that protects WooCommerce customer and product data when rolling back things back so you get the best-case scenario: readily available backups that preserves customer orders and product information.

That’s just one of the magical benefits you get from such a deep integration between Jetpack and WooCommerce. There are others, of course! But you can imagine just what a big deal this specific integration for any WooCommerce-powered store.

And, hey, Jetpack Backup is sold à la carte. So, if backups are all you want from Jetpack, then you can get just that and that alone.

The post Jetpack Backup: Roll Back Your WooCommerce Site Without Losing Orders appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

from CSS-Tricks…

Number of Homes


  1. I’m not even sure what house I lived in when I was born. Something where my mom and dad lived together, for the few years before they divorced. Then after that probably a couple of different houses before my memory kicks in? I dunno, I’ll just list this as one.
  2. The Lynndale Rd. House in Madison, Wisconsin.
  3. The Fitchrona Rd. House in Verona, Wisconsin.
  4. Wells West dorms in Whitewater, Wisconsin.
  5. Wells East dorms in Whitewater, Wisconsin.
  6. Weird basement apartment in Whitewater, Wisconsin.
  7. Weird brick duplex thing in Whitewater, Wisconsin.
  8. The Yellow House in Whitewater, Wisconsin.
  9. The downtown house in Madison, Wisconsin.
  10. The suburban apartment complex thing in Whitewater, Wisconsin.
  11. The Farmhouse in Verona, Wisconsin.
  12. The Killingsworth house in NE Portland, Oregon
  13. The Alberta house in NE Portland, Oregon
  14. The flat in Logan Square, Chicago, Illinois.
  15. The house on the circle in Tampa, Florida.
  16. The house on the circle in Palo Alto, California.
  17. The Bay View house in Milwaukee, Wisconsin.
  18. The compound in South Miami Heights, Miami, Florida.
  19. The Northwest Crossing house in Bend, Oregon.
  20. The Aubrey Butte house in Bend, Oregon.

The post Number of Homes appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

from CSS-Tricks…

Let’s use (X, X, X, X) for talking about specificity

I was just chatting with Eric Meyer the other day and I remembered an Eric Meyer story from my formative years. I wrote a blog post about CSS specificity, and Eric took the time to point out the misleading nature of it (I remember scurrying to update it). What was so misleading? The way I was portraying specificity as a base-10 number system.

Say you select an element with ul.nav. I insinuated in the post that the specificity of that selector was 0011 (eleven, essentially), which is a number in a base-10 system. So I was saying tags = 0, classes = 10, IDs = 100, and a style attribute = 1000. If specificity was calculated in a base-10 number system like that, a selector like ul.nav.nav.nav.nav.nav.nav.nav.nav.nav.nav.nav (11 class names) would have a specificity of 0111, which would be the same as That’s not true. The reality is that it would be (0, 0, 11, 1) vs. (0, 1, 0, 1) with the latter easily winning.

That comma-separated syntax like I just used solves two problems:

  1. It doesn’t insinuate a base-10 number system (or any number system)
  2. It has a distinct and readable look

I like the (X, X, X, X) look. I could see limiting it to (X, X, X) since a style attribute isn’t exactly a selector and usually isn’t talked about in the same kind of conversations. The parens make it more clear to me, but I could also see a X-X-X (dash-separated) syntax that wouldn’t need them, or a (X / X / X) syntax that probably would benefit from the parens.

Selectors Level 3 uses dashes briefly. Level 2 used both dashes and commas in different places.

Anyway, apparently I get the bug to mention this every half-decade or so.

The post Let’s use (X, X, X, X) for talking about specificity appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

from CSS-Tricks…