The Design Squiggle

I think we all have an intuitive understanding that, at the beginning of projects that require our creativity (be it design or code), things feel uncertain and messy. Then, as we go, things tend to straighten out. There is still some wiggling and setbacks, but by the end, we find a single solution and ship it.

Apparently this feeling has a logo: The Design Squiggle

The Process of Design Squiggle by Damien Newman,

It comes from Damien Newman who says that a client gave him 30 seconds to sell them on the value of design, and this did the trick.

I find it a little funny to take this little concept and give it such a grandiose presentation. A dedicated website! A story with a boatload of name dropping! Very specific attribution instructions! But hey, I don’t have any famous doodles, and I gotta admit, this does a great job of expressing a complex thing quite quickly.

Reminds me of a boss a buddy of mine had who claims to have invented the Curiously Strong motto for Altoids, and didn’t mind telling people about it.

Direct Link to ArticlePermalink

The post The Design Squiggle appeared first on CSS-Tricks.



Thinking Through Styling Options for Web Components

Where do you put styles in web components?

I’m assuming that we’re using the Shadow DOM here as, to me, that’s one of the big draws of a web component: a platform thing that is a uniquely powerful thing the platform can do. So this is about defining styles for a web component in a don’t-leak-out way, and less so a way to get global styles to leak in (although that’s very interesting as well, which can be done via custom properties which we’ll look at later in the article).

If you’re building the template inside the JavaScript — which is nice because of template literals and how we can sprinkle our data into the template nicely — you need access to those styles in JavaScript.

const template = `   <style>$  {styles}</style>   <div class="$  {class}">     <h2>$  Thinking Through Styling Options for Web Components</h2>     $  {content}   </div> `;

Where does that style variable come from? Maybe also a template literal?

const style = `   :host {     background: white;   }   h2 {     font: 900 1.5rem/1.1 -system-ui, sans-serif;   } `;

I guess that’s fine, but it makes for a big messy block of code just dunked somewhere in the class where you’re trying to build this web component.

Another way is to <template> the template and make a <style> block part of it.

<template id="card-template">   <style>     :host {       background: white;     }     h2 {       font: 900 1.5rem/1.1 -system-ui, sans-serif;     }   </style>    <div id="card-hook">     <h2 id="title-hook"></h2>     <p id="desc-hook"></p>   </div> </template>

I can see the appeal with this because it keeps HTML in HTML. What I don’t love about it is that you have to do a bunch of manual shadowRoot.querySelector("#title-hook").innerHTML = myData.title; work in order to flesh out that template. That doesn’t feel like a convenient template. I also don’t love that you need to just chuck this template somewhere in your HTML. Where? I dunno. Just chuck it in there. Chuck it.

The CSS is moved out of the JavaScript too, but it just moved from one awkward location to another.

If we wanted to keep the CSS in a CSS file, we can sorta do that like this:

<template id="card-template">   <style>     @import "/css/components/card.css";   </style>    <div id="card-hook">     <h2 id="title-hook"></h2>     <p id="desc-hook"></p>   </div> </template>

(The use of <link rel="import" type="css" href=""> is deprecated, apparently.)

Now we have @import which is an extra HTTP Request, and notorious for being a performance hit. An article by Steven Lambert says it clocked in at half a second slower. Not ideal. I don’t suppose it would be much better to do this instead:

class MyComponent extends HTMLElement {        constructor() {     super();     this.attachShadow({ mode: "open" });      fetch('/css/components/card.css')       .then(response => response.text())       .then(data => {         let node = document.createElement('style');         node.innerHTML = data;         document.body.appendChild(node);       });   }    // ... }

Seems like that would potentially be a Flash-of-Unstyled-Web-Component? I guess I should get off my butt and test it.

Now that I’m digging into this again, it seems like ::part has gotten some steam (explainer). So I can do…

const template = `   <div part="card">     <h2>$  Thinking Through Styling Options for Web Components</h2>     $  {content}   </div> `;

…then write styles in a global stylesheet that only apply inside that Shadow DOM, like:

my-card::part(card) {   background: black;   color: white; }

…which has a smidge of browser support, but maybe not enough?

These “part” selectors can only touch the exact element it’s connected to. You’d have to do all your styling by applying a part name to every single DOM node and then styling each entirely on its own. That’s no fun, particularly because the appeal of the Shadow DOM is this isolated styling environment in which we’re supposed to be able to write looser CSS selectors and not be worried our h2 { } style is going to leak all over the place.

Looks like if native CSS modules becomes a thing, that will be the most helpful thing that could happen.

import styles from './styles.css';  class MyElement extends HTMLElement {   constructor() {     this.attachShadow({mode: open});     this.shadowRoot.adoptedStyleSheets = [styles];   } }

I’m not sure, however, if this is any sort of performance boost. Seems like it would be a wash between this and @import. I have to say I prefer the clarity and syntax with native CSS modules. It’s nice to be writing JavaScript when working with JavaScript.

Constructable Stylesheets also look helpful for sharing a stylesheet across multiple components. But the CSS modules approach looks like it could also do that since the stylesheet has already become a variable at that point.

The post Thinking Through Styling Options for Web Components appeared first on CSS-Tricks.


, , , ,

A Web Component with Different HTML for Desktop and Mobile

Christian Schaefer has a great big write-up about dealing with web advertisements. The whole thing is interesting, first documenting all the challenges that ads present, and then presenting modern solutions to each of them.

One code snippet that caught my eye was a simple way to design a component that renders different HTML depending on the screen size.

<div class="ad">   <template class="ad__mobile">     // Mobile ad HTML code with inline script   </template>   <template class="ad__desktop">     // Desktop ad HTML code with inline script   </template>   <script>     const isMobile = matchMedia('(max-device-width: 20em)').matches;     const ad = document.currentScript.closest('.ad');     const content = ad       .querySelector(isMobile ? '.ad__mobile' : '.ad__desktop')       .content;          ad.appendChild(document.importNode(content, true));   </script> </div> 

Clever. Although note that Christian ends up going a totally different route in the article.

Here’s that same code where I use a custom element and move the JavaScript to JavaScript just ‘cuz.

See the Pen
A Web Component with Different HTML for Desktop and Mobile
by Chris Coyier (@chriscoyier)
on CodePen.

The post A Web Component with Different HTML for Desktop and Mobile appeared first on CSS-Tricks.


, , , ,

How We Tagged Google Fonts and Created

GooFonts is a side project signed by a developer-wife and a designer-husband, both of them big fans of typography. We’ve been tagging Google Fonts and built a website that makes searching through and finding the right font easier.

GooFonts uses WordPress in the back end and NuxtJS (a Vue.js framework) on the front end. I’d love to tell you the story behind and share a few technical details regarding the technologies we’ve chosen and how we adapted and used them for this project.

Why we built GooFonts

At the moment of writing this article, there are 977 typefaces offered by Google Fonts. You can check the exact number at any moment using the Google Fonts Developer API. You can retrieve the dynamic list of all fonts, including a list of the available styles and scripts for each family.

The Google Fonts website provides a beautiful interface where you can preview all fonts, sorting them by trending, popularity, date, or name. 

But what about the search functionality? 

You can include and exclude fonts by five categories: serif, sans-serif, display, handwriting, and monospace.

You can search within scripts (like Latin Extended, Cyrillic, or Devanagari (they are called subsets in Google Fonts). But you cannot search within multiple subsets at once.

You can search by four properties: thickness, slant, width, and “number of styles.” A style, also called variant, refers both to the style (italic or regular) and weights (100, 200, up to 900). Often, the body font requires three variants: regular, bold, and italic. The “number of styles” property sorts out fonts with many variants, but it does not allow to select fonts that come in the “regular, bold, italic” combo.

There is also a custom search field where you can type your query. Unfortunately, the search is performed exclusively over the names of the fonts. Thus, the results often include font families uniquely from services other than Google Fonts. 

Let’s take the “cartoon” query as an example. It results in “Cartoon Script” from an external foundry Linotype.

I can remember working on a project that demanded two highly stylized typefaces — one evoking the old Wild West, the other mimicking a screenplay. That was the moment when I decided to tag Google Fonts. 🙂

GooFonts in action

Let me show you how GooFonts works. The dark sidebar on the right is your  “search” area. You can type your keywords in the search field — this will perform an “AND” search. For example, you can look for fonts that are at once cartoon and slab. 

We handpicked a bunch of keywords — click any of them! If your project requires some specific subsets, check them in the subsets sections.  You can also check all the variants that you need for your font.

If you like a font, click its heart icon, and it will be stored in your browser’s localStorage. You can find your bookmarked fonts on the page. Together with the code, you might need to embed them.

How we built it: the WordPress part

To start, we needed some kind of interface where we could preview and tag each font. We also needed a database to store those tags. 

I had some experience with WordPress. Moreover, WordPress comes with its REST API,  which opens multiple possibilities for dealing with the data on the front end. That choice was made quickly.

I went for the most straightforward possible initial setup. Each font is a post, and we use post tags for keywords. A custom post type could have worked as well, but since we are using WordPress only for the data, the default content type works perfectly well.

Clearly, we needed to add all the fonts programmatically. We also needed to be able to programmatically update the fonts, including adding new ones or adding new available variants and subsets.

The approach described below can be useful with any other data available via an external API. In a custom WordPress plugin, we register a menu page from which we can check for updates from the API. For simplicity, the page will display a title, a button to activate the update and a progress bar for some visual feedback.

/**  * Register a custom menu page.   */ function register_custom_menu_page() {   add_menu_page(      'Google Fonts to WordPress',      'WP GooFonts',      'manage_options',      'wp-goofonts-menu',    function() { ?>             <h1>Google Fonts API</h1>     <button type="button" id="wp-goofonts-button">Run</button>     <p id="info"></p>             <progress id="progress" max="100" value="0"></progress>   <?php }   ); } add_action( 'admin_menu', 'register_custom_menu_page' );

Let’s start by writing the JavaScript part. While most of the examples of using Ajax with WordPress implements jQuery and the jQuery.ajax method, the same can be obtained without jQuery, using axios and a small helper Qs.js for data serialization.

We want to load our custom script in the footer, after loading axios and qs:

add_action( 'admin_enqueue_scripts' function() {   wp__script( 'axios', '' );   wp_enqueue_script( 'qs', '' );   wp_enqueue_script( 'wp-goofonts-admin-script', plugin_dir_url( __FILE__ ) . 'js/wp-goofonts.js', array( 'axios', 'qs' ), '1.0.0', true ); });

Let’s look how the JavaScript could look like:

const BUTTON = document.getElementById('wp-goofonts-button') const INFO = document.getElementById('info') const PROGRESS = document.getElementById('progress') const updater = {   totalCount: 0,   totalChecked: 0,   updated: [],   init: async function() {     try {       const allFonts = await axios.get('')       this.totalCount =       INFO.textContent = `Fetched $ {this.totalCount} fonts.`       this.updatePost(, 0)     } catch (e) {       console.error(e)     }   },   updatePost: async function(els, index) {     if (index === this.totalCount) {       return     }                     const data = {       action: 'goofonts_update_post',       font: els[index],     }     try {        const apiRequest = await, Qs.stringify(data))        this.totalChecked++        PROGRESS.setAttribute('value', Math.round(100*this.totalChecked/this.totalCount))        this.updatePost(els, index+1)     } catch (e) {        console.error(e)       }    } }  BUTTON.addEventListener('click', () => {   updater.init() })

The init method makes a request to the Google Fonts API. Once the data from the API is available, we call the recursive asynchronous updatePost method that sends an individual font in the POST request to the WordPress server.

Now, it’s important to remember that WordPress implements Ajax in its specific way. First of all, each request must be sent to wp-admin/admin-ajax.php. This URL is available in the administration area as a global JavaScript variable ajaxurl.

Second, all WordPress Ajax requests must include an action argument in the data. The value of the action determines which hook tag will be used on the server-side.

In our case, the action value is goofonts_update_post. That means what happens on the server-side is determined by the wp_ajax_goofonts_update_post hook.

add_action( 'wp_ajax_goofonts_update_post', function() {   if ( isset( $ _POST['font'] ) ) {     /* the post tile is the name of the font */     $ title = wp_strip_all_tags( $ _POST['font']['family'] );     $ variants = $ _POST['font']['variants'];     $ subsets = $ _POST['font']['subsets'];     $ category = $ _POST['font']['category'];     /* check if the post already exists */     $ object = get_page_by_title( $ title, 'OBJECT', 'post' );     if ( NULL === $ object ) {       /* create a new post and set category, variants and subsets as tags */       goofonts_new_post( $ title, $ category, $ variants, $ subsets );     } else {       /* check if $ variants or $ subsets changed */       goofonts_update_post( $ object, $ variants, $ subsets );     }   } });  function goofonts_new_post( $ title, $ category, $ variants, $ subsets ) {   $ post_id =  wp_insert_post( array(     'post_author'  =>  1,     'post_name'    =>  sanitize_title( $ title ),     'post_title'   =>  $ title,     'post_type'    =>  'post',     'post_status'  => 'draft',     )   );   if ( $ post_id > 0 ) {     /* the easy part of tagging ;) append the font category, variants and subsets (these three come from the Google Fonts API) as tags */     wp_set_object_terms( $ post_id, $ category, 'post_tag', true );     wp_set_object_terms( $ post_id, $ variants, 'post_tag', true );     wp_set_object_terms( $ post_id, $ subsets, 'post_tag', true );   } }

This way, in less than a minute, we end up with almost one thousand post drafts in the dashboard — all of them with a few tags already in place. And that’s the moment when the crucial, most time-consuming part of the project begins. We need to start manually add tags for each font one by one.
The default WordPress editor does not make much sense in this case. What we needed is a preview of the font. A link to the font’s page on also comes in handy.

custom meta box does the job very well. In most cases, you will use meta boxes for custom form elements to save some custom data related to the post. In fact, the content of a meta box can be practically any HTML.

function display_font_preview( $ post ) {   /* font name, for example Abril Fatface */   $ font = $ post->post_title;   /* font as in url, for example Abril+Fatface */   $ font_url_part = implode( '+', explode( ' ', $ font ));   ?>   <div class="font-preview">      <link href="<?php echo '' . $ font_url_part . '&display=swap'; ?>" rel="stylesheet">     <header>       <h2><?php echo $ font; ?></h2>       <a href="<?php echo '' . $ font_url_part; ?>" target="_blank" rel="noopener">Specimen on Google Fonts</a>     </header>     <div contenteditable="true" style="font-family: <?php echo $ font; ?>">       <p>The quick brown fox jumps over a lazy dog.</p>       <p style="text-transform: uppercase;">The quick brown fox jumps over a lazy dog.</p>       <p>1 2 3 4 5 6 7 8 9 0</p>       <p>& ! ; ? {}[]</p>     </div>   </div> <?php }  add_action( 'add_meta_boxes', function() {   add_meta_box(     'font_preview', /* metabox id */     'Font Preview', /* metabox title */     'display_font_preview', /* content callback */     'post' /* where to display */   ); });

Tagging fonts is a long-term task with a lot of repetition. It also requires a big dose of consistency. That’s why we started by defining a set of tag “presets.” That could be, for example:

{   /* ... */   comic: {     tags: 'comic, casual, informal, cartoon'   },   cursive: {     tags: 'cursive, calligraphy, script, manuscript, signature'   },   /* ... */ }

Next with some custom CSS and JavaScript, we “hacked” the WordPress editor and tags form by enriching it with the set of preset buttons. 

How we built it: The front end part (using NuxtJS)

The interface was designed by Sylvain Guizard, a french graphic and web designer (who also happens to be my husband). We wanted something simple with a distinguished “search” area. Sylvain deliberately went for colors that are not too far from the Google Fonts identity. We were looking for a balance between building something unique and original while avoiding user confusion.

While I did not hesitate choosing WordPress for the back-end, I didn’t want to use it on front end. We were aiming for an app-like experience and I, personally, wanted to code in JavaScript, using Vue.js in particular.

I came across an example of a website using NuxtJS with WordPress and decided to give it a try. The choice was made immediately. NuxtJS is a very popular Vue.js framework, and I really enjoy its simplicity and flexibility. 
I’ve been playing around with different NuxtJS settings to end up with a 100% static website. The fully static solution felt the most performant; the overall experience seemed the most fluid.That also means that my WordPress site is only used during the build process. Thus, it can run on my localhost. This is not negligible since it eliminates the hosting costs and most of all, lets me skip the security-related WordPress configuration and relieves me of the security-related stress. 😉

If you are familiar with NuxtJS, you probably know that the full static generation is not (yet) a part of NuxtJS. The prerendered pages try to fetch the data again when you are navigating.

That’s why we have to somehow “hack” the 100% static generation. In this case, we are saving the useful parts of the fetched data to a JSON file before each build process. This is possible, thanks to Nuxt hooks, in particular, its builder hooks.

Hooks are typically used in Nuxt modules:

/* modules/beforebuild.js */  const fs = require('fs') const axios = require('axios')  const sourcePath = 'http://wpgoofonts.local/wp-json/wp/v2/' const path = 'static/allfonts.json'  module.exports = () => {   /* write data to the file, replacing the file if it already exists */   const storeData = (data, path) => {     try {       fs.writeFileSync(path, JSON.stringify(data))     } catch (err) {       console.error(err)     }   }   async function getData() {         const fetchedTags = await axios.get(`$ {sourcePath}tags?per_page=500`)       .catch(e => { console.log(e); return false })        /* build an object of tag_id: tag_slug */     const tags =, cur) => {       acc[] = cur.slug       return acc     }, {})        /* we want to know the total number or pages */     const mhead = await axios.head(`$ {sourcePath}posts?per_page=100`)       .catch(e => { console.log(e); return false })     const totalPages = mhead.headers['x-wp-totalpages']    /* let's fetch all fonts */     let fonts = []     let i = 0     while (i < totalPages) {       i++       const response = await axios.get(`$ {sourcePath}posts?per_page=100&page=$ {i}`)       fonts.push.apply(fonts,     }      /* and reduce them to an object with entries like: {roboto: {name: Roboto, tags: ["clean","contemporary", ...]}} */     fonts = (fonts).reduce((acc, el) => {       acc[el.slug] = {         name: el.title.rendered,         tags: => tags[i]),       }       return acc     }, {})    /* save the fonts object to a .json file */     storeData(fonts, path)   }    /* make sure this happens before each build */   this.nuxt.hook('build:before', getData) }
/* nuxt.config.js */ module.exports = {   // ...   buildModules: [     ['~modules/beforebuild']   ], // ... }

As you can see, we only request a list of tags and a list posts. That means we only use default WordPress REST API endpoints, and no configuration is required.

Final thoughts

Working on GooFonts was a long-term adventure. It is also this kind of projects that needs to be actively maintained. We regularly keep checking Google Fonts for the new typefaces, subsets, or variants. We tag new items and update our database. Recently, I was genuinely excited to discover that Bebas Neue has joint the family. We also have our personal favs among the much lesser-known specimens.

As a trainer that gives regular workshops, I can observe real users playing with GooFonts. At this stage of the project, we want to get as much feedback as possible. We would love GooFonts to be a useful, handy and intuitive tool for web designers. One of the to-do features is searching a font by its name. We would also love to add a possibility to share the bookmarked sets and create multiple “collections” of fonts.

As a developer, I truly enjoyed the multi-disciplinary aspect of this project. It was the first time I worked with the WordPress REST API, it was my first big project in Vue.js, and I learned so much about typography.  

Would we do anything differently if we could? Absolutely. It was a learning process. On the other hand, I don’t think we would change the main tools. The flexibility of both WordPress and Nuxt.js proved to be the right choice. Starting over today, I would definitely took time to explore GraphQL, and I will probably implement it in the future.

I hope that you find some of the discussed methods useful. As I said before, your feedback is very precious. If you have any questions or remarks, please let me know in the comments!

The post How We Tagged Google Fonts and Created appeared first on CSS-Tricks.


, , , ,

Debunking the Myth: Accessibility and React

I find it notable when the blog of a major accessibility-focused company like Deque publishes an article called Debunking the Myth: Accessibility and React. Mark Steadman is essentially saying if a site has bad accessibility, it ain’t React… it’s you. The tools are there to achieve good accessibility.

React didn’t use a <div> for a <button>, but you did. React didn’t force extra markup all over the page when you decided to not use a Fragment. React didn’t forget to change the title of the page, because that was something you neglected.

Is it different how you have to do it in React versus how you have to do it in some other framework or CMS? Yes, it is. Different, but neither worse nor harder.

I’m optimistic that well-made React components focused on accessibility can have a positive impact on the web. Just today I was pair programming and looking at some HTML for a toggle UI in a Rails template. It had a little bug we wanted to fix, which required an HTML change. But this toggle wasn’t a component, it was a chunk of HTML used in dozens of places on the site. Gosh, did I wish this part of the site was architected with proper components instead, a practice that all JavaScript frameworks endorse?

Where did the bad wrap on React come from? Well, we could debate that for days. Is it that JavaScript-focused developers never got the HTML training they needed? Maybe. Was it gnarly, unsemantic React code that was written early on that others copy and pasted too many times? Maybe. I’m not sure we’ll ever know. The important thing is that we all do a better job now.

Direct Link to ArticlePermalink

The post Debunking the Myth: Accessibility and React appeared first on CSS-Tricks.


, , ,

The Deal with the Section Element

Two articles published the exact same day:

  1. Bruce Lawson on Smashing Magazine: Why You Should Choose HTML5 <article> Over <section>
  2. Adam Laki on Pine: The Difference Between <section> and <div> Element

They are comparing slightly different things, but they both involve the <section> element.

I find it pretty clear when you reach for a <div>: When you want that element to be essentially meaningless. You’re only using it for styling purposes.

I always think of RSS when I think of <article>: Would this little bit of stuff make sense as an entry (which doesn’t necessarily need to be the entire content of the article)? If yes, use <article>; if not, don’t.

Bruce has a go-to answer:

[…] think of <article> not just as a newspaper article, or a blog post, but as an article of clothing — a discrete entity that can be reused in another context. So your trousers are an article, and you can wear them with a different outfit; your shirt is an article, and can be worn with different trousers; your knee-length patent leather stiletto boots are an article.

More importantly, it has some actual functionality. Bruce mentions that Apple WatchOS specifically uses it to find content on pages.

But <section> is more nebulous. At one point, you were supposed to think of sections as places where your <h1><h6> headings would reset, but that never came to fruition because it required a thing called “HTML5 Outlining” which zero browsers support.

So should we use <section> it at all? According to Bruce, sometimes! Smashing Magazine’s design for articles has a summary at the beginning of the article. Visually, that’s fairly clear, but less-so for screen reader users. The solution was wrapping the summary in an element with an aria-label to make that clear. But you aren’t supposed to use aria-label unless that element also has a role. You could apply a role to a <div>, but <section> already has a good default role, so:

<section aria-label="quick summary">   Summary text </section>

Adam’s article (sorry, Adam) is very vague on the points.

The main difference comes from the semantic. If you have a part in your site or application which has its logic you need to use the <section> tag to declare it…

… use <section> when it is logically correct to make a part of your site or app readable to the assistive technology. It is an excellent approach if you keep in mind the screen readers.

So you get a role="region" automatically for sections, but I’m not sure that does anything for screen readers, sans the label. In a quick test (Chrome for desktop with VoiceOver enabled), a <section> without an aria-label just wasn’t there in the Landmarks section of the Web Rotor, but it showed up once it had an aria-label.

Point is: don’t just use <section> and assume you’re doing something good for accessibility. Its purpose is pretty limited and only useful for establishing landmarks. Even then, you aren’t helping that much. Leonie Watson in the comments:

When the choice is between a visually hidden heading and a section element with an accessible name there are a couple of things to consider before deciding which approach is the right one.

When a section element has an accessible name it becomes a navigable landmark element, so a screen reader user can use their screen reader’s shortcut key for navigating from one to the next – just like they can do with headings.

According to the most recent WebAIM screen reader user survey though, 68% of screen reader users prefer to navigate by headings compared to 2.9% who prefer landmarks.

So from a strict accessibility point of view, you could probably drop the heading, but from a usability point of view you really want to keep the heading – at least until more screen reader users express a preference for using landmarks to navigate content.

The post The Deal with the Section Element appeared first on CSS-Tricks.


, ,

Business Dad

Congrats to Chris Enns, our podcast editor on ShopTalk and CodePen Radio, for landing a really cool new podcast to edit: Business Dad. It’s Alexis Ohanian, the co-founder of Reddit, talking to dads. The first episode is with Hasan Minhaj(!)

Speaking of podcasting, Dave wrote up his thoughts on starting a podcast (you should), a beefier and more interesting version of my little writeup. I stand by my $ 1,000 podcasting setup though. I still use it and think it’s quite nice.

Direct Link to ArticlePermalink

The post Business Dad appeared first on CSS-Tricks.



How many CSS properties are there?

Tomasz Łakomy posted a joke tweet about naming all the CSS attributes and Tejas Kumar replied with a joke answer, going as far as making an npm module. You can even run a terminal command to see them:

npx get-all-css-properties

You’ll get 259 of them. The source code uses the website for the data, which I’d never heard of. 🤷‍♂️

I would have probably looked at MDN, where some quick querySelectorAll handiwork in the console yields a different number: 584. But ooops, that’s full of selectors, at-rules, and other stuff. Their reference only lists 72, but says it’s incomplete.

W3Schools lists 228 of them. HTML Dog lists 125. Our almanac has 176, and I know we omit stuff on purpose (e.g. we file margin-left under margin instead of making its own entry).

The horse’s mouth?

520 distinct property names from 66 technical reports and 66 editors’ drafts.

The post How many CSS properties are there? appeared first on CSS-Tricks.


, ,

Netlify High-Fives

We’ve got Netlify as a sponsor around here again this year, which is just fantastic. Big fan. Our own Sarah Drasner is Head of DX (Developer Experience) over there, if you hadn’t heard. And if you haven’t heard of Netlify, well, you’re in for a treat. It’s a web host, but for your jamstack sites, which means it’s static hosting, encouraging you to pre-build as much of your site as you can, then use JavaScript and APIs to do whatever else you need to. Heck, they’ll help you build serverless functions and auth.

Here’s a couple of Netlify-related things swirling around in my life.

  • I added open authoring to our conference site. So now, anybody can go to the admin area, auth with GitHub, and submit a conference. No coding required. Dream come true, if you ask me. The same thing is live on the serverless site.
  • I enjoyed Bryan Robinson’s take on jamstack in 2020. It’s about the connection between services and the power that brings.
  • It’s interesting how even not-particularly jamstack-y software like WordPress can totally live a jamstack life, when you combine it with something like Gatsby.
  • I have a new microsite idea cooking. I really wanna build a site that showcases all the things you can (and probably should) be doing with your build process. It will explain them and provide resources, but the whole site will dogfood itself and do all those things. Stuff like:
    1. Process all it’s code, keeping compiled code out of the repo
    2. Build a sitemap
    3. Optimize all the images
    4. Check for broken links
    5. Run accessibility tests
    6. Check the performance budget
    7. Run unit test
    8. Run end-to-end tests
    9. Run visual regression tests
    10. Trigger notifications

Wouldn’t that last one be cool?! We’d do it all with build plugins, at least that’s how it works in my mind. If you have a strong desire to contribute, lemme know — maybe we can make it a community effort.

The post Netlify High-Fives appeared first on CSS-Tricks.



In Defence of “Serverless” —the term

Ben Ellerby:

For now Serverless, to me at least, manages to do a hard job, defining the borders of a very fluid and complex space of possible solutions in which we can build next-generation architectures. It would help if there was not a framework of the same name, it would help if people didn’t first hear it synonymous with Lambda and it would help if people stopped saying “but you know there are servers…”. That being said, I’ve not heard a better proposal yet!

I like the term (we got the whole site and all) but rather than explain why, I’ll let my most popular tweet of all time take it from here:

Rather than alt text, here’s the whole conversation in the format of the
American Chopper Argument meme.

Why would you call it “serverless” when the architecture is anything but?

They aren’t yours. You don’t manage them. You barely think about them.


It’s just an effective buzzword. It evokes a whole ecosystem in a single word.


Direct Link to ArticlePermalink

The post In Defence of “Serverless” —the term appeared first on CSS-Tricks.


, , ,