Simon Willison’s Weblog

Subscribe
Atom feed for css

157 items tagged “css”

2024

You can use text-wrap: balance; on icons. Neat CSS experiment from Terence Eden: the new text-wrap: balance CSS property is intended to help make text like headlines display without ugly wrapped single orphan words, but Terence points out it can be used for icons too:

A row of icons, without text-wrap balances just one is wrapped on the second line. With the propert they are split into two lines with equal numbers of icons.

This inspired me to investigate if the same technique could work for text based navigation elements. I used Claude to build this interactive prototype of a navigation bar that uses text-wrap: balance against a list of display: inline menu list items. It seems to work well!

Animated demo. A navigation menu with 13 items - things like Home and About and Services and a products. These are wrapped on four lines with 4, 4, 4 and then 1 item. Selecting the enable text-wrap: balances checkbox changes that to 3, 4, 3, 3 - a slider also allows the number of visible items to be changed to see the effect that has

My first attempt used display: inline-block which worked in Safari but failed in Firefox.

Notable limitation from that MDN article:

Because counting characters and balancing them across multiple lines is computationally expensive, this value is only supported for blocks of text spanning a limited number of lines (six or less for Chromium and ten or less for Firefox)

So it's fine for these navigation concepts but isn't something you can use for body text.

# 20th October 2024, 1:23 pm / css, claude-artifacts, anthropic, ai-assisted-programming, claude, terence-eden

HTML for People (via) Blake Watson's brand new HTML tutorial, presented as a free online book (CC BY-NC-SA 4.0, on GitHub). This seems very modern and well thought-out to me. It focuses exclusively on HTML, skipping JavaScript entirely and teaching with Simple.css to avoid needing to dig into CSS while still producing sites that are pleasing to look at. It even touches on Web Components (described as Custom HTML tags) towards the end.

# 11th October 2024, 1:51 am / css, html, web-components

Calling LLMs from client-side JavaScript, converting PDFs to HTML + weeknotes

Visit Calling LLMs from client-side JavaScript, converting PDFs to HTML + weeknotes

I’ve been having a bunch of fun taking advantage of CORS-enabled LLM APIs to build client-side JavaScript applications that access LLMs directly. I also span up a new Datasette plugin for advanced permission management.

[... 2,050 words]

Button Stealer (via) Really fun Chrome extension by Anatoly Zenkov: it scans every web page you visit for things that look like buttons and stashes a copy of them, then provides a page where you can see all of the buttons you have collected. Here's Anatoly's collection, and here are a few that I've picked up trying it out myself:

Screenshot showing some buttons I have collected, each with their visual appearance maintained

The extension source code is on GitHub. It identifies potential buttons by looping through every <a> and <button> element and applying some heuristics like checking the width/height ratio, then clones a subset of the CSS from window.getComputedStyle() and stores that in the style= attribute.

# 25th July 2024, 7:40 pm / css, chrome, extensions, javascript

So you think you know box shadows? (via) David Gerrells dives deep into CSS box shadows. How deep? Implementing a full ray tracer with them deep.

# 21st July 2024, 4:23 pm / css, javascript

Box shadow CSS generator (via) Another example of a tiny personal tool I built using Claude 3.5 Sonnet and artifacts. In this case my prompt was:

CSS for a slight box shadow, build me a tool that helps me twiddle settings and preview them and copy and paste out the CSS

I changed my mind half way through typing the prompt and asked it for a custom tool, and it built me this!

Box shadow CSS generator. Shows a preview, then provides sliders to set Horizontal Offset, Vertical Offset, Blur Radius,  Spread Radius,  Color and Opacity - plus the generated CSS and a Copy to Clipboard button

Here's the full transcript - in a follow-up prompt I asked for help deploying it and it rewrote the tool to use <script type="text/babel"> and the babel-standalone library to add React JSX support directly in the browser - a bit of a hefty dependency (387KB compressed / 2.79MB total) but I think acceptable for this kind of one-off tool.

Being able to knock out tiny custom tools like this on a whim is a really interesting new capability. It's also a lot of fun!

# 8th July 2024, 7:30 pm / css, anthropic, claude, generative-ai, projects, ai, llms, ai-assisted-programming, claude-artifacts, claude-3-5-sonnet

What You Need to Know about Modern CSS (Spring 2024 Edition) (via) Useful guide to the many new CSS features that have become widely enough supported to start using as-of May 2024. Time to learn container queries!

View transitions are still mostly limited to Chrome—I can’t wait for those to land in Firefox and Safari.

# 5th May 2024, 2:08 pm / css

Printing music with CSS Grid (via) Stephen Bond demonstrates some ingenious tricks for creating surprisingly usable sheet music notation using clever application of CSS grids.

It uses rules like .stave > [data-duration="0.75"] { grid-column-end: span 18; } to turn data- attributes for musical properties into positions on the rendered stave.

# 2nd May 2024, 2:28 pm / css, music

Kobold letters (via) Konstantin Weddige explains a sophisticated HTML email phishing vector he calls Kobold emails.

When you forward a message, most HTML email clients will indent the forward by nesting it inside another element.

This means CSS rules within the email can be used to cause an element that was invisible in the original email to become visible when it is forwarded—allowing tricks like a forwarded innocuous email from your boss adding instructions for wiring money from the company bank account.

Gmail strips style blocks before forwarding—which it turns out isn’t protection against this, because you can put a style block in the original email to hide the attack text which will then be stripped for you when the email is forwarded.

# 4th April 2024, 12:43 pm / css, security, email

The Dropflow Playground (via) Dropflow is a “CSS layout engine” written in TypeScript and taking advantage of the HarfBuzz text shaping engine (used by Chrome, Android, Firefox and more) compiled to WebAssembly to implement glyph layout.

This linked demo is fascinating: on the left hand side you can edit HTML with inline styles, and the right hand side then updates live to show that content rendered by Dropflow in a canvas element.

Why would you want this? It lets you generate images and PDFs with excellent performance using your existing knowledge HTML and CSS. It’s also just really cool!

# 22nd March 2024, 1:33 am / css, typescript, webassembly, javascript

Upside down table trick with CSS (via) I was complaining how hard it is to build a horizontally scrollable table with a scrollbar at the top rather than the bottom and RGBCube on Lobste.rs suggested rotating the container 180 degrees and then the table contents and headers 180 back again... and it totally works! Demo in this CodePen.

# 24th February 2024, 9 pm / css

How To Center a Div (via) Josh Comeau: “I think that my best blog posts are accessible to beginners while still having some gold nuggets for more experienced devs, and I think I’ve nailed that here. Even if you have years of CSS experience, I bet you’ll learn something new.”

Lots of interactive demos in this.

# 13th February 2024, 7:51 pm / css, josh-comeau

2023

An Interactive Guide to CSS Grid (via) Josh Comeau’s extremely clear guide to CSS grid, with interactive examples for all of the core properties.

# 21st November 2023, 4:25 pm / css, josh-comeau

The anatomy of visually-hidden (via) James Edwards provides a detailed breakdown of the current recommended CSS for hiding content while keeping it available for assistive technologies in the browser accessibility and render trees. Lots of accumulated tricks and screenreader special cases in this.

# 11th February 2023, 12:37 am / css, screenreaders, accessibility

The Page With No Code (via) A fun demo by Dan Q, who created a web page with no HTML at all—but in Firefox it still renders content, thanks to a data URI base64 encoded stylesheet served in a link: header that uses html::before, html::after, body::before and body::after with content: properties to serve the content. It even has a background image, encoded as a base64 SVG nested inside another data URI.

# 21st January 2023, 6:59 pm / css, datauri, html

2022

An Interactive Guide to Flexbox. Joshua Comeau built this fantastic guide to CSS flexbox layouts, with interactive examples of all of the properties. This is a really useful tour of the layout model.

# 26th November 2022, 2:50 am / css

Inside the mind of a frontend developer: Hero section. Ahmad Shadeed provides a fascinating, hyper-detailed breakdown of his approach to implementing a “hero section” component using HTML and CSS, including notes on CSS grids and gradient backgrounds.

# 9th November 2022, 7:54 pm / css

Can :has Connect 4? (via) Spectacular CSS demo by Jhey Tompkins, implementing a working 3D Connect 4 game using just CSS (brilliant trickery with the new :has() selector) and not a single line of JavaScript.

# 7th October 2022, 5:49 pm / css

Supporting logical properties. A frustrating reminder from Jeremy Keith that Safari is not an evergreen browser: older iOS devices (1st gen iPad Air for example) get stuck on the last iOS version that supports them, which also sticks them with an old version of Safari, which means they will never get support for newer CSS properties such as inline-start and block-end. Jeremy shows how to use the @supports rule to hide this new syntax from those older browsers.

# 1st October 2022, 1:03 am / css, jeremy-keith, safari, ios, web-standards

Shoelace (via) Saw this for the first time today: it’s a relatively new library of framework-agnostic Web Components, built on lit-html and covering a huge array of common functionality: buttons and sliders and dialogs and drawer interfaces and dropdown menus and so on. The design is very clean, the documentation is superb—and it looks like you can cherry pick just the components you are using for a pretty lean addition to your page weight. So refreshing to see libraries like this that really take advantage of modern web standards.

# 20th August 2022, 8:57 pm / web-components, css, web-standards, javascript, lit-html

viewport-preview (via) I built a tiny tool which lets you preview a URL in a bunch of different common browser viewport widths, using iframes.

# 26th July 2022, 12 am / css, testing, projects, mobile, iframes

Bringing page transitions to the web (via) Jake Archibald’s 13 minute Google I/O talk demonstrating the page transitions API that’s now available in Chrome Canary. This is a fascinating piece of API design—it works by effectively creating a static image screenshot of the before and after states of the transition, then letting you define CSS animations that animate a transition between the two static images. By default the screenshot encompasses the full viewport, but you can instead define multiple elements within the page and apply separate transitions to them. It’s only available for SPAs right now but the final design should include support for multi-page applications as well—which means transitions with no JavaScript needed at all!

# 13th July 2022, 4:26 pm / css, jake-archibald, transitions, javascript

Defensive CSS (via) Fantastic new site by Ahmad Shadeed describing in detail CSS patterns which can help build layouts that adapt well to unexpected content—things like overly long titles or strange aspect ratio images, common when you are designing against UGC.

# 6th July 2022, 5:16 pm / css, frontend

Announcing Parcel CSS: A new CSS parser, compiler, and minifier written in Rust! An interesting thing about tools like this being written in Rust is that since the Rust-to-WASM pipeline is well trodden at this point, the live demo that this announcement links to runs entirely in the browser.

# 13th January 2022, 8:40 pm / css, rust, webassembly

2021

The World of CSS Transforms. Comprehensive, clearly explained tutorial on CSS transforms by Josh W. Comeau, with some very neat interactive demos. I hadn’t understood how useful it is that the translate() transform treats percentages as applying to the dimensions of the element being transformed, not its parent. This means you can use expressions like transform: translateX(calc(100% + 4px)); to shift an element by its entire width plus a few more pixels.

# 9th August 2021, 2:30 pm / css, josh-comeau

APIs from CSS without JavaScript: the datasette-css-properties plugin

Visit APIs from CSS without JavaScript: the datasette-css-properties plugin

I built a new Datasette plugin called datasette-css-properties. It’s very, very weird—it adds a .css output extension to Datasette which outputs the result of a SQL query using CSS custom property format. This means you can display the results of database queries using pure CSS and HTML, no JavaScript required!

[... 891 words]

datasette-css-properties (via) My new Datasette plugin defines a “.css” output format which returns the data from the query as a valid CSS stylesheet defining custom properties for each returned column. This means you can build a page using just HTML and CSS that consumes API data from Datasette, no JavaScript required! Whether this is a good idea or not is left as an exercise for the reader.

# 7th January 2021, 7:42 pm / css, projects, datasette

Custom Properties as State. Fascinating thought experiment by Chris Coyier: since CSS custom properties can be defined in an external stylesheet, we can APIs that return stylesheets defining dynamically server-side generated CSS values for things like time-of-day colour schemes or even strings that can be inserted using ::after { content: var(--my-property).

This gave me a very eccentric idea for a Datasette plugin...

# 7th January 2021, 7:39 pm / css, apis

brumm.af/shadows (via) I did not know this trick: by defining multiple box-shadow values as a comma separated list you can create much more finely tuned shadow effects. This tool by Philipp Brumm provides a very smart UI for designing shadows.

# 6th January 2021, 4:12 pm / design, css

2020

datasette-ripgrep: deploy a regular expression search engine for your source code

Visit datasette-ripgrep: deploy a regular expression search engine for your source code

This week I built datasette-ripgrep—a web application for running regular expression searches against source code, built on top of the amazing ripgrep command-line tool.

[... 1,362 words]