Class-light CSS blades inspired by Pico.css
Table of Contents
Install
Install CSS blades via CDN or npm
Via CDN:
<link href="https://cdn.jsdelivr.net/npm/@anydigital/blades@^0.27.0-alpha/assets/blades.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/@anydigital/blades@^0.27.0-alpha/assets/blades.theme.min.css" rel="stylesheet" /><!-- optional -->
Via npm:
npm install @anydigital/blades
Then import in your .css:
@import "@anydigital/blades";
@import "@anydigital/blades.theme"; /* optional */
Living example: /anydigital/build-awesome-starter/blob/main/_styles/styles.css
Layout
Global styles:
html {
/* Prevent horizontal overflow and scrolling, modern way. */
overflow-x: clip;
}
body {
/* Ensure `body` takes at least the full height of the viewport (using dynamic viewport height for better mobile support). */
min-height: 100dvh;
}
🥷 Breakout elements
Framework-agnostic utilities for breaking out images and figures beyond their container width.
Use the .breakout class to allow elements to extend beyond their parent container.
Auto-columns
.columns,
[data-is-toc] > ul,
[data-is-toc] > ol {
columns: 30ch auto; /* 2 cols max for 65ch container */
/* Avoid breaking inside elements, such as nested lists */
> * {
break-inside: avoid;
}
}
Table of contents ([data-is-toc]) has auto-columns by default.
Jump to top
[data-jump-to="top"] {
position: fixed;
bottom: 0;
right: 0;
padding-top: 50vh;
opacity: 25%;
&:hover {
opacity: 75%;
}
}
Content
Global styles:
html {
/* Enable font smoothing */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
/* Enable global hyphenation */
hyphens: auto;
/* ... except for links and tables which are better (safer) without hyphenation */
a,
table {
hyphens: none;
}
}
🥷 Link [fav]icons
Use Blades' <i>-helper to wrap emojis, favicons, or simply drop Font Awesome icons inside links. It automatically handles sizing and alignment while preventing underline on icons.
Heading anchors
Set data-is-anchor attribute on anchors inside headings to position them absolutely, and show only on hover (when supported):
How it works:
h1,
h2,
h3,
h4,
h5,
h6 {
position: relative;
[data-is-anchor] {
position: absolute;
right: 100%;
top: 50%;
transform: translateY(-50%);
padding-right: 0.2ch;
color: silver;
text-decoration: none;
visibility: hidden;
}
/* Avoid double-tap on touch devices */
@media (hover: hover) {
&:hover {
[data-is-anchor] {
visibility: visible;
}
}
}
}
PRO-TIP for 11ty + markdown-it-anchor:
/anydigital/eleventy-blades/blob/main/src/eleventy.config.js
List markers
Use inline style="--list-marker:'🥷 '" on <ul>/<ol> or even individual <li> to customize list markers:
- Customize
- list
- markers
- with Blades CSS
How it works:
ul,
ol {
&[style*="--list-marker:"] {
list-style-type: var(--list-marker);
> li {
list-style-type: inherit;
}
}
li[style*="--list-marker:"] {
list-style-type: var(--list-marker);
}
li[data-marker]::marker {
/* ⚠️ `data-marker` works only in Chrome and Firefox */
content: attr(data-marker) " ";
}
}
Unlist
Helper class to remove list styling at all:
.unlist {
padding-inline-start: 0;
> li {
list-style: none;
}
}
Code
Extends /picocss/pico/blob/main/scss/content/_code.scss
pre {
padding: 1rem 1.5rem;
padding-inline-end: 2rem;
@media screen and (max-width: 767px) {
border-radius: 0;
}
}
code {
/* Code block caption via data-attr (to display filename, etc.) */
&[data-caption] {
&::before {
content: attr(data-caption);
display: block;
margin-bottom: 1rem;
opacity: 50%;
font-style: italic;
}
}
&:where(pre > *) {
padding: 0;
}
}
/*** Extends https://github.com/PrismJS/prism/blob/master/plugins/treeview/prism-treeview.css ***/
.token.treeview-part {
.entry-line {
width: 2.5em !important;
opacity: 25%;
}
.entry-name:last-child {
opacity: 50%;
&::before {
display: none !important;
}
}
}
Table
🥷 Responsive table without wrapper
<table class="responsive"> allows a table to full-bleed and scroll on mobile.
Horizontal expanders
Simply insert <hr> inside <th> to forcibly widen too narrow columns (especially useful in markdown):
<th>Col <hr></th>
Example table before:
| Wide tables | with many | columns might | get collapsed | and be really | hard to read! |
|---|
Same table after adding <hr>-expanders:
| Wide tables | with many | columns might | get collapsed | and be really | hard to read! |
|---|
Living examples of big tables with <hr>-expanders:
How it works:
table {
th {
hr {
width: 12ch; /* min ~65/12 = ~5 cols */
height: 0;
margin: 0;
visibility: hidden;
&.lg {
width: 18ch;
}
&.x2 {
width: 24ch;
}
}
}
}
Borderless table
<table class="borderless"> removes all default borders:
| Less | borders |
|---|---|
| more | fun |
Living example: /#minimal-dependencies table
Utilities
Auto-dark
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
.dark-auto {
filter: invert(100%) hue-rotate(180deg);
}
}
}
Faded
.faded {
opacity: 50%;
&:hover {
opacity: 87.5%;
}
}
Invert
/* Extends https://tailwindcss.com/docs/filter-invert */
.invert {
/* Fix the scrollbar color when inverted */
::-webkit-scrollbar {
filter: invert(1) !important;
}
}
Unreduce motion
@utility unreduce-animation-* {
@media (prefers-reduced-motion: reduce) {
&:not([aria-busy="true"]) {
animation-duration: --value([ *]) !important;
animation-delay: 0 !important;
animation-iteration-count: infinite !important;
}
}
}
Theme (optional)
How it works
@import "./float-label.theme";
body {
/* Make the `body` a flex container with column layout, and `main` to automatically fill available space. This is useful for creating sticky footers and full-height layouts. */
display: flex;
flex-direction: column;
> main {
flex-grow: 1;
}
}
a {
&:not([href^="#"]) {
text-decoration-thickness: 1px;
&:hover {
text-decoration-thickness: 2px;
}
}
}
h1 {
font-size: 2.5em; /* for pico.css & tw-typography */
margin-bottom: 1rem; /* for tw-typography */
}
/* Potential fix https://github.com/picocss/pico/blob/main/css/pico.css for the very first headings
:where(article, address, blockquote, dl, figure, form, ol, p, pre, table, ul) ~ :is(h1, h2, h3, h4, h5, h6) {
margin-top: var(--pico-typography-spacing-top);
}
h1,
h2,
h3,
h4,
h5,
h6 {
& ~ & {
margin-bottom: 2rem;
}
}
NOTE: be careful with wrapped headings, i.e. inside nav: https://blades.ninja/build-awesome-11ty/#usage
*/
hr {
margin-block: 2em; /* for pico.css & tw-typography */
}
ul {
ul {
font-size: 87.5%;
}
}
pre {
small {
opacity: 75%;
font-weight: lighter;
}
}
table {
th {
vertical-align: bottom;
font-weight: bold;
}
td {
vertical-align: top;
}
pre {
margin-bottom: 0.25rem;
}
}
[data-jump-to="top"] {
> i {
display: inline-block;
padding: 0.25rem 0.375rem;
margin: 0.5rem;
font-size: 0.75rem;
color: black;
border-color: black;
}
}
[data-is-toc] {
font-size: 87.5%;
a {
text-decoration: none;
}
> ul > * > a {
font-weight: 500;
}
}
.breakout,
.breakout-all {
> img,
> figure {
margin-bottom: 1rem;
}
}
.faded {
a {
text-decoration-style: dotted;
}
}
See also:
buildexcellentwebsit.es
/picocss/pico
/kevquirk/simple.css
/dbohdan/classless-css
/dohliam/dropin-minimal-css
/troxler/awesome-css-frameworks
/2026/03/21/heading-anchors-with-11ty
/2026/03/17/simple-timeline
/2026/03/05/you-dont-know-html-tables