• Stars
    star
    416
  • Rank 100,388 (Top 3 %)
  • Language
    HTML
  • License
    MIT License
  • Created 8 months ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

🌘 Scope your inline style tags in pure vanilla CSS! Only 16 lines. No build. No dependencies.

🌘 CSS Scope Inline

cover (Art by shahabalizadeh)

Why does this exist?

  • You want an easy inline vanilla CSS experience without Tailwind CSS.
  • Hate creating unique class names over.. and over.. to use once.
  • You want to co-locate your styles for ⚡️ Locality of Behavior (LoB)
  • You wish this would work in <style> tags.
  • Want all CSS features: Nesting, animations. Get scoped @keyframes!
  • You wish @media queries were shorter for responsive design.
  • Only 16 lines. No build step. No dependencies.
  • Pairs well with htmx and Surreal
  • Want fewer layers, less complexity. Are aware of the cargo cult. ✈️

✨ Want to also scope your <script> tags? See our companion project Surreal

👁️ How does it look?

<div>
    <style>
        me { background: red; } /* ✨ this & self also work! */
        me button { background: blue; } /* style child elements inline! */
    </style>
    <button>I'm blue</button>
</div>

See the Live Example! Then view source.

🌘 How does it work?

This uses MutationObserver to monitor the DOM, and the moment a <style> tag is seen, it scopes the styles to whatever the parent element is. No flashing or popping.

This method also leaves your existing styles untouched, allowing you to mix and match at your leisure.

🎁 Install

✂️ copy + 📋 paste the snippet into <script> in your <head>

Or, 📥 download into your project, and add <script src="script.js"></script> in your <head>

Or, 🌐 CDN: <script src="https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js"></script>

🤔 Why consider this over Tailwind CSS?

Use whatever you'd like, but there's a few advantages with this approach over Tailwind, Twind, UnoCSS:

  • No more repeating styles on child elements (..no @apply, no [&>thing] per style). It's just CSS!
  • No endless visual noise on every <div>. Use a local <style> per group.
  • No high risk of eventually requiring a build step.
  • No chance of deprecations. 16 lines is infinitely maintainable.
  • Get the ultra-fast "inspect, play with styles, paste" workflow back.
  • No suffering from FOUC (a flash of unstyled content).
  • Zero friction movement of styles between inline and .css files. Just replace me
  • No special tooling or plugins to install. Universal vanilla CSS.

⚡ Workflow Tips

  • Flat, 1 selector per line can be very short like Tailwind. See the examples.
  • Use just plain CSS variables in your design system.
  • Use the short @media queries for responsive design.
    • Mobile First (flow: above breakpoint): 🟢 None sm md lg xl xx 🏁
    • Desktop First (flow: below breakpoint): 🏁 xs- sm- md- lg- xl- 🟢 None
    • 🟢 = No breakpoint. Default. See the Live Example!
    • Based on Tailwind breakpoints. We use xx not 2xl to not break CSS highlighters.
    • Unlike Tailwind, you can nest your @media styles!
  • Positional selectors may be easier using div[n1] for <div n1> instead of div:nth-child(1)
  • Try tools like- Auto complete styles: VSCode or Sublime

👁️ CSS Scope Inline vs Tailwind CSS Showdowns

Basics

Tailwind verbosity goes up with more child elements.

<!-- CSS Scope Inline -->
<div>
    <style>
        me { background: red; }
        me div { background: green; }
        me div[n1] { background: yellow; }
        me div[n2] { background: blue; }
    </style>
    red
    <div>green</div>
    <div>green</div>
    <div>green</div>
    <div n1>yellow</div>
    <div n2>blue</div>
    <div>green</div>
    <div>green</div>
</div>

<!-- Tailwind -->
<div class="bg-[red]">
    red
    <div class="bg-[green]">green</div>
    <div class="bg-[green]">green</div>
    <div class="bg-[green]">green</div>
    <div class="bg-[yellow]">yellow</div>
    <div class="bg-[blue]">blue</div>
    <div class="bg-[green]">green</div>
    <div class="bg-[green]">green</div>
</div>

CSS variables and child styling

<!doctype html>
<html>
    <head>
        <style>
            :root {
                --color-1: hsl(0 0% 88%);
                --color-1-active: hsl(214 20% 70%);
            }
        </style>
        <script src="https://cdn.tailwindcss.com"></script>
        <script src="https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js"></script>
    </head>
    <body>
        <!-- CSS Scope Inline -->
        <div>
            <style>
               me { margin:8px 6px; }
               me div a { display:block; padding:8px 12px; margin:10px 0; background:var(--color-1); border-radius:10px; text-align:center; }
               me div a:hover { background:var(--color-1-active); color:white; }
            </style>
            <div><a href="#">Home</a></div>
            <div><a href="#">Team</a></div>
            <div><a href="#">Profile</a></div>
            <div><a href="#">Settings</a></div>
            <div><a href="#">Log Out</a></div>
        </div>

        <!-- Tailwind Example 1 -->
        <div class="mx-2 my-4">
            <div><a href="#" class="block py-2 px-3 my-2 bg-[--color-1] rounded-lg text-center hover:bg-[--color-1-active] hover:text-white">Home</a></div>
            <div><a href="#" class="block py-2 px-3 my-2 bg-[--color-1] rounded-lg text-center hover:bg-[--color-1-active] hover:text-white">Team</a></div>
            <div><a href="#" class="block py-2 px-3 my-2 bg-[--color-1] rounded-lg text-center hover:bg-[--color-1-active] hover:text-white">Profile</a></div>
            <div><a href="#" class="block py-2 px-3 my-2 bg-[--color-1] rounded-lg text-center hover:bg-[--color-1-active] hover:text-white">Settings</a></div>
            <div><a href="#" class="block py-2 px-3 my-2 bg-[--color-1] rounded-lg text-center hover:bg-[--color-1-active] hover:text-white">Log Out</a></div>
        </div>

        <!-- Tailwind Example 2 -->
        <div class="mx-2 my-4
            [&_div_a]:block [&_div_a]:py-2 [&_div_a]:px-3 [&_div_a]:my-2 [&_div_a]:bg-[--color-1] [&_div_a]:rounded-lg [&_div_a]:text-center
            [&_div_a:hover]:bg-[--color-1-active] [&_div_a:hover]:text-white">
            <div><a href="#">Home</a></div>
            <div><a href="#">Team</a></div>
            <div><a href="#">Profile</a></div>
            <div><a href="#">Settings</a></div>
            <div><a href="#">Log Out</a></div>
        </div>
    </body>
</html>

🔎 Technical FAQ

  • Why do you use querySelectorAll() and not just process the MutationObserver results directly?
    • Processing MutationObserver results will work well until you begin recieving subtrees (ex: DOM swap, htmx, ajax, jquery) which requires you to walk all subtree child elements to not miss a <style>. This can involve re-scanning thousands of repeated elements, and querySelectorAll() ends up the simplicty and performance winner.

More Repositories

1

surreal

🗿 Mini jQuery alternative. Dependency-free animations. Locality of Behavior. Use one element or arrays transparently. Pairs with htmx. Vanilla querySelector() but better!
JavaScript
641
star
2

simple-php-form

📝 Easily create and validate HTML forms in PHP 8.
PHP
26
star
3

nc-cms

💡 Embeddable, lightweight, simple PHP CMS. Content Management System.
PHP
25
star
4

csrf-starlette-fastapi

Dead simple CSRF security middleware for Starlette ⭐ and FastAPI ⚡
Python
24
star
5

text-to-speech-ubuntu

🙊 Setup "selectable" text to speech / TTS on Ubuntu Linux 24.04 22.04 22.10 23.04 23.10 . Ideal for speed reading, programming, editing and writing.
20
star
6

sublime-outline-notes-publisher

✒️ Publish HTML from markdown or tab indented notes. Static site generator in Sublime Text! Alternative to Obsidian.
Python
13
star
7

doit.sh

🏴‍☠️ Replaces your build system with 1 shell script.
Shell
11
star
8

awesome-surreal

🗿 A curated list of awesome Surreal examples, plugins, resources and other shiny things.
10
star
9

hyperscript-sublime

Hyperscript syntax highlighting for Sublime Text. (_hyperscript, HTMX)
10
star
10

css-reset-tiny

♻️ Under 12 line zero bullshit modern vanilla CSS reset.
CSS
10
star
11

sublime-invader-zim

🛸 Dark Color Theme for Sublime Text 4
9
star
12

send-to-discord.sh

💬 Message your Discord server. No setup. Zero dependencies. Just works on any of: bash, sh, curl, github actions, workflows, gitea... Uses webhooks api.
Shell
6
star
13

tetris-machine

🎮 3D Tetris in pure C using OpenGL & SDL.
C
6
star
14

super-score

🎯 Game leaderboards, currency log, and player data storage. REST API server in PHP 7.
PHP
5
star
15

expose-ubuntu-mate

👁️ Setup "overview screen" for Ubuntu MATE. Similar to: OS X Expose, KDE Overview, GNOME Activities.
4
star
16

stylus-inline

Zero build step version of Stylus CSS that runs in your browser. With inlined scopes! Written in vanilla JS. Also single file python version!
HTML
2
star
17

internet-ip-gui-linux

:godmode: Find your Internet IP & Local IP address in copy-paste format. (Global public IP for game servers).
Python
2
star
18

vscode-python-highlight-html-sql

Highlight HTML, SQL in Python Strings for VSCode, Codium. Embed HTML, PHP, Python Server Pages style.
2
star
19

sublime-python-html-sql

HTML + SQL highlighter extension for strings in Python for Sublime Text!
2
star
20

api.php

Easily build an Internet API in a single file using PHP
PHP
2
star
21

super-chatendo

💬 Real time Twitch-Slack chat in Node and Web Sockets using Socket.io.
JavaScript
1
star
22

python-replace-case-insensitive

🔍 Case insensitive string replace() alternative for Python 3. Does NOT use regex (regular expressions) in order to prevent ReDoS attacks.
Python
1
star
23

vscode-ghostbusters

👻 Dark Color Theme for VSCode / VSCodium
1
star
24

html-dialog-animated-demo

Minimalist animated HTML <dialog> element / tag demo.
HTML
1
star
25

salesforce-to-zendesk

🚚 Salesforce to Zendesk customer integration microservice.
PHP
1
star
26

rootless-docker-file-ownership

👤 Reclaim file ownership back to user who starts a rootless container (1000), from the container operating User (100998, 100000 ...)
Shell
1
star