Skip to content

Instantly share code, notes, and snippets.

View tomhodgins's full-sized avatar
Writing CSS

Tommy Hodgins tomhodgins

Writing CSS
View GitHub Profile
View browser-console-one-liners.js
/* JSON XPath search */ (await import('')).default(window.dataLayer, '//string')
/* cookie to object */ Object.fromEntries(document.cookie.split('; ').map(entry => entry.split('=')))
/* cookie to object */ (await import('')).default()
/* css elements search */ document.querySelectorAll ('*')
/* xpath element search */ (await import('')).queryXPathAll ('//*')
View css-clamp-usage.css
css clamp function usage at work {
font-size: clamp(12pt, 5vw, 15pt);
font-size: clamp(22pt, 2.5vw, 28pt);
font-size: clamp(20pt, 2.5vw, 28pt);
font-size: clamp(8pt, 6--ew, 10pt);
font-size: clamp(7pt, 6--ew, 9pt);
font-size: clamp(24px, 6vw, 36px);
font-size: clamp(var(--min), 4vw, var(--max));
font-size: clamp(var(--min), 5vw, var(--max));
font-size: clamp(var(--min), 3vw, var(--max));
View inactivity-timer.js
class InactivityCountdown {
callback = () => {},
duration = 10
) {
this.timer // to hold setTimeout ID = false // remember timer state
this.callback = callback // function to run when countdown completes
this.duration = duration // time in seconds to wait
View wait-for-react.js
// Wait for React
function hasReactProperty(tag = document.documentElement) {
return Object.keys(tag).some(key =>
function isReactRoot(tag) {
return hasReactProperty(tag)
View two-modules-zero-files.html
<script type=module src="data:text/javascript,
import {demo} from 'data:text/javascript,export const demo = `Howdy`';
View gist:b4f922049cace16e7401aebac0b45848
Sass (and Less and Stylus and other custom languages that compile to CSS) have some design flaws that end up limiting what you can do with CSS. If you have a codebase that still depends on them it would be a good time to isolate and minimize the code you have that uses them and strategize how you'll migrate away from them. If your project doesn't have have them, or you haven't yet learned them - it might be a good idea, thinking ahead, to just skip that and get into a pure CSS workflow. Don't worry, you can still preprocess CSS, the secret is writing and handling valid CSS at every step in your workflow so all the tools work together
Some flaws Sass has that get in the way:
- It's not actually compatible with CSS syntax. It's not a super-set, it's an entirely different syntax and because it's incompatible with real CSS, there's an infinite variety of things you might have or want in CSS that can't even be present in any stylesheet Sass looks at
- Some of the things Sass adds to its custom syntax are things
View id-overview.js
function html(strings, ...expressions) {
return document.createRange().createContextualFragment(
strings.reduce((output, string, index) =>
output + expressions[index - 1] + string

Ways to extend a language with custom stuff that works™

  • define stuff in the language to use (libraries)
  • if the language lets you define custom parts of syntax (macros, plugins, etc) use the built-in methods for extending the language itself
  • create an entirely separate DSL for working with solutions in this problem space and figure out how that maps to this language

Ways to extend a language with custom stuff that doesn't work™

  • try to add additional syntax as a thin layer on top of a separate, growing language still under development
View extract-custom-properties.js
const extractCustomProperties = (string = '') => Object.fromEntries(
([match, property, value]) => [property, value]
const css = `
:root {
--custom: property;