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
const extractCustomProperties = (string = '') => Object.fromEntries(
Array.from(
string.matchAll(/--(?<property>[^:]+?)\s*:\s*(?<value>.*?)\s*[;}]/gus),
([match, property, value]) => [property, value]
)
)
const css = `
:root {
--custom: property;
(async () => console.log(
(await import(`data:text/javascript,export default "Is this a safe way to eval?"`)).default
))()
`template string`
tagged`template string`
tagged('template', 'string')`with arguments before`
tagged`template string`('with', 'arguments', 'after')
class CustomElement extends HTMLElement {
constructor() {
super()
this.shadow = this.attachShadow({mode: 'open'})
this.stylesheet = `
:host,
:host * {
box-sizing: border-box;
text-rendering: optimizeLegibility;
// ==UserScript==
// @name CSS Overlay 2 | Ace Edition
// @namespace overlay
// @version 1.0
// @description For writing CSS stylesheets
// @author Tommy Hodgins
// @match *://*/*
// ==/UserScript==
if (document.querySelector('link[href^="https://fonts.googleapis.com/css?family="][href*="IBM+Plex+Mono"]') === null) {
// We can create a new empty HTML document
const htmlDocument = document.implementation.createHTMLDocument()
// And we can find the XML namespace of HTML (http://www.w3.org/1999/xhtml) in the browser too
const xmlns = new DOMParser().parseFromString(
new XMLSerializer().serializeToString(htmlDocument),
'text/html'
).documentElement.getAttribute('xmlns')
// Using the namespace for HTML we can create a new XML document in the HTML namespace like this
import * as parseCSS from 'https://tomhodgins.github.io/parse-css/index.js'
import jsincss from 'https://unpkg.com/jsincss/index.vanilla.js'
import eunit from 'https://unpkg.com/jsincss-element-units/index.vanilla.js'
async function getAllStylesheets() {
return [...getStyleTags(), ... await getLinkedStylesheets()]
}
function getStyleTags() {
return Array.from(
@tomhodgins
tomhodgins / automatic-clamp-fallback.css
Last active September 14, 2020 22:37
Is this a worthwhile fallback to support by parsing font-size: clamp() in stylesheets? The 1000px breakpoint would probably be hard-coded
/* input */
a {
font-size: clamp(10px, 10vw, 100px);
}
/* output */
a {
font-size: clamp(10px, 10vw, 100px);
}
@tomhodgins
tomhodgins / element-replace-children.js
Last active September 15, 2020 14:41
A polyfill for parentNode.replaceChildren()
// Polyfill for parentNode.replaceChildren()
// Spec: https://dom.spec.whatwg.org/#dom-parentnode-replacechildren
// Docs: https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/replaceChildren
// Gecko implementation: https://github.com/mozilla/gecko-dev/blob/master/dom/base/nsINode.cpp#L2027
// Webkit implementation: https://github.com/WebKit/webkit/blob/master/Source/WebCore/dom/ContainerNode.cpp#L958
// Source: https://gist.github.com/tomhodgins/14451f123e1878e766c9568ecce13878
if (typeof Element.prototype.replaceChildren !== 'function') {
Object.defineProperty(Element.prototype, 'replaceChildren', {
configurable: true,
writable: true,
@tomhodgins
tomhodgins / deno-or-browser-tagged-html-template-function.js
Created September 11, 2020 00:43
This tagged template for HTML literals works in all modern browsers and Deno
if ('Deno' in globalThis) {
globalThis.DOMParser = (await import('https://deno.land/x/deno_dom/deno-dom-wasm.ts')).DOMParser
}
function html(taggedTemplateString = [''], ...expressions) {
const nodes = []
const functions = new Map
const strings = typeof taggedTemplateString === 'string'
? [taggedTemplateString]
: taggedTemplateString