@sreekotay/as-css
v1.0.0
Published
Component-scoped CSS that runs in the browser without build tooling.
Maintainers
Readme
as-css
Component-scoped CSS at runtime with zero build tooling.
Examples: Live | examples/demo.html | examples/edge-case-test.html
What It Does
- Scopes each component style block to a generated class (
as--1,as--2, ...) - Supports
<style as-css>and<as-style> - Rewrites keyframes/animation names to avoid collisions
- Supports reusable named styles via
as-nameandas-class - Supports runtime updates with
dynamic(rare, for JS mutation of stylesheet text/rules)
Install / Include
CDN
<script src="https://cdn.jsdelivr.net/npm/@sreekotay/as-css@1/dist/as-css.min.js"></script>or
<script src="https://unpkg.com/@sreekotay/as-css@1/dist/as-css.min.js"></script>npm + self-hosted
npm install @sreekotay/as-cssThen serve:
<script src="/assets/as-css.min.js"></script>Local dev (this repo)
<script src="./src/as-css.js"></script>Version guidance:
@1for major pinning@1.0.0for exact pinning- Avoid
@latestin production
Minimal Example
<script src="https://cdn.jsdelivr.net/npm/@sreekotay/as-css@1/dist/as-css.min.js"></script>
<div class="card">
<style as-css>
& { padding: 1rem; border: 1px solid #ccc; border-radius: 8px; }
.title { font-weight: 700; }
&:hover { box-shadow: 0 4px 8px rgba(0,0,0,.12); }
</style>
<h3 class="title">Scoped card</h3>
</div>Runtime behavior:
- Parent gets a scope class, e.g.
.as--1 &->.as--1.title->.as--1 .title&:hover->.as--1:hover
Core Rules
&and*reference the container- Selectors without
&are descendant-scoped :hoverbecomes descendant hover (.scope :hover)&:hovertargets container hover (.scope:hover)@media sm-lt,@container md-gt, etc. are expanded at runtime
Breakpoints:
xs-lt/gt->479/480sm-lt/gt->639/640md-lt/gt->767/768lg-lt/gt->1023/1024xl-lt/gt->1279/1280xx-lt/gt->1535/1536
Named Styles
Use named styles when you want to define scoped CSS once and reuse it across many elements.
Define a shared style:
<style as-css as-name="card-theme">
& { padding: 1rem; border-radius: 8px; }
.title { font-weight: 700; }
</style>Apply:
<div as-class="card-theme">
<h3 class="title">Reused</h3>
</div>How it works:
- Definition uses
as-name="theme-name" - Usage uses
as-class="theme-name"(space-separated values are allowed) - Definitions are hoisted and deduplicated, so duplicates do not re-register
- References receive the same generated scope classes as the definition
Strong + Dynamic
Strong scoping
Use strong when framework styles are winning on specificity.
<style as-css strong>
.btn { background: rebeccapurple; }
</style>Strong named styles are supported too:
<style as-css as-name="brand-card" strong>
& { border: 2px solid #6b46c1; }
</style>
<div as-class="brand-card">
<button class="btn">Inherited strong scope</button>
</div>What strong does:
- Adds
as-strongto the target element - Uses a chained scope selector (
.scope.as-strong ...) for higher specificity - For named styles, references inherit strong behavior from the definition
Dynamic updates
Use dynamic when JS mutates stylesheet text/rules after initial render (for example changing <style as-css> content). This is usually uncommon, but it does happen in theme engines, live editors, and generated runtime styles.
This is different from normal element inline-style updates (el.style.color = ...), which are common and do not require dynamic:
<style as-css dynamic>
& { background: steelblue; }
</style>
<script>
const styleEl = document.querySelector('style[as-css][dynamic]');
styleEl.textContent = '& { background: tomato; }';
</script>When to use dynamic:
- Theme/color changes driven by JS state
- Runtime component style generation
- Live playground/editor experiences
Internals
- Runtime internals:
docs/internals-runtime.md - Selector and rewrite notes:
docs/internals-selectors.md
Utility API:
as.css.resetAnimations(element);
as.css.resetAnimations(element, '.child');
as.css.replace(styleElementOrChild, newCssText);Compatibility / Caveats
- Chrome/Edge 88+, Firefox 78+, Safari 14+
- No IE11
- Shadow DOM already provides native style isolation
Project Scripts
npm run build-> build minified runtimenpm run pages-> build.pagesartifact for GitHub Pagesnpm run watch-> rebuild on source changes
Publish
npm run build
npm version patch
npm publishVerify:
https://www.npmjs.com/package/@sreekotay/as-csshttps://cdn.jsdelivr.net/npm/@sreekotay/as-css@latest/dist/as-css.min.jshttps://unpkg.com/@sreekotay/as-css@latest/dist/as-css.min.js
