クラス名を書かない
スタイルは要素そのものから決まります。命名規則を決める必要も、ユーティリティクラスを覚える必要もありません。
Just HTML, already styled.
SuCSSはクラスレスのCSSフレームワークです。<header>、<table>、<button> のような素のHTMLを書くだけで、リキッドグラスの見た目とダークモードとアクセシビリティがついてきます。クラス名も、カスタム属性も、ビルドも要りません。
このページ自体が見本です。class 属性は1つも使っていません。下の1行を <head> に貼れば、あなたのHTMLもこう表示されます。
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ryo9ra/su-css/dist-lib/sucss.min.css">
su(素)は「飾りのない、そのままの」という意味です。
スタイルは要素そのものから決まります。命名規則を決める必要も、ユーティリティクラスを覚える必要もありません。
prefers-color-scheme に追従します。data-theme を付ければどちらかに固定できます。
WCAG AA/AAA のコントラスト、見える :focus-visible リング、十分なタップ領域。prefers-reduced-motion と prefers-reduced-transparency にも従います。
面はすりガラスではなくレンズです。背景が透けたまま色がにじみ、縁には光の線が乗ります。
CSSが1枚だけ。minify + gzip で 6.6 KB。JavaScriptもビルドステップもありません。
色も角丸もリズムもCSSカスタムプロパティです。--hue を変えればページ全体が動きます — カスタマイザーで試す。
CDNから読み込むなら、上の1行をそのまま <head> に貼ります。バンドラを使うならnpmから入れられます。
npm install @ryo9ra/su-css
import '@ryo9ra/su-css/sucss.min.css';
| 読み込み指定 | ファイル | サイズ |
|---|---|---|
@ryo9ra/su-css |
dist-lib/sucss.css |
64 KB (gzip 16.1 KB) |
@ryo9ra/su-css/sucss.min.css |
dist-lib/sucss.min.css |
36 KB (gzip 6.4 KB) |
対象ブラウザは Chrome/Edge 111+、Safari 16.4+、Firefox 128+ です。backdrop-filter のないブラウザでは、面が半透明ではなくベタ塗りになります。
ここから下も class 属性を1つも使わない素のHTMLです。ページのソースを開いて見比べてみてください。
段落は --line-height と --max-width にしたがって組まれます。強調、強調(斜体)、太字、イタリック、下線、取り消し線、インラインコード、Ctrl + C、CSS、x、出力、定義語、下付き、上付き、そして リンク がそのまま揃います。
クラス名の設計に費やしていた時間は、そのままセマンティクスの設計に回せる。
— 素のHTMLに戻るという発想
ランドマークはタグだけでなくロールでも受けます。banner、navigation、main、complementary、contentinfo、region、search を <div> に付けたマークアップも、対応する要素と同じ見た目になります。
<div role="complementary">上の <aside> を描いているルールがそのまま適用されます。クラスも追加の CSS もありません。
<search>| プロパティ | 既定値 | 効くところ |
|---|---|---|
--hue |
262 | アクセント色と背景メッシュ |
--sat |
85% | アクセント色の彩度 |
--max-width |
860px | 本文カラムの幅 |
--radius |
1.375rem | 面の角丸 |
--glass-blur |
14px | ガラスが背景をぼかす量 |
すべて :root で上書きできます。
|
||
| 要素 | 属性 | 示すもの |
|---|---|---|
<details> |
[open] |
開閉の状態 |
<progress> |
[value] |
進捗の度合い |
<th> |
[aria-sort] |
どの列で並べ替えたか |
1列目に aria-sort="ascending" が付いているので、指標は上を向きます。"descending" なら下向きです。2列目は aria-sort="none"、3列目は属性なしで、どちらもこれまでどおりに描かれます。
ツールバーは Tab で一度入り、矢印キーで中を移動する操作を伴います。SuCSS が描くのはバーの見た目までで、そのキーボード操作は @ryo9ra/su-css/behaviors.js が書くか、自分で書くかです。どちらもできない場合は role="group" を使ってください。
安定版 MIT 依存ゼロ
開閉する領域も要素だけで組めます。
popovertarget を持つボタンは、スクリプトなしで [popover] パネルを開閉します。クリックの配線はブラウザがやります。やらないのは、ボタンの aria-expanded を揃えることです — それをタダでやってくれるのは <details> だけです。指標はその属性だけから描いていて、aria-sort と同じく文字ではなく境界線です。フォントもフォールバックも要りません。このページでは、この属性を揃えるためだけの短いスクリプトを走らせています — CSS 側はそのスクリプトの存在を前提にしていません。
このパネルは [popover] です。ガラスの見た目は <dialog> と共有していて、重複させていません。何をあえて外しているかは CSS 側を見てください。
[popover] をまだ知らないブラウザでは、このパネルはただのブロックとして常時開いたまま表示されます。これは新しい属性にスタイルを当てる代償として許容しています。ここでは :popover-open を使っていないので、宣言しているブラウザ対象は動きません。
選ばれたタブは aria-pressed と同じ塗りで描かれます — role="tab" が aria-selected を持つだけの違いです。トグルボタンと違うのは挙動のほうで、タブは矢印キーで移動した先がそのまま選択になり、対応する role="tabpanel" が切り替わります(WAI-ARIA APG の automatic activation)。
選択中のパネルの中身。role="tabpanel" は tabindex="0" を持ち、中の要素を一つずつ Tab で辿らなくても、パネルそのものをひとつの停止点として読めます。
2 番目のパネル。矢印キーでここまで来ると、CSS 側の見た目とこのパネルの表示・非表示が同時に切り替わります。
3 番目のパネル。Home / End で最初 / 最後のタブへ飛べます。
タブの見た目は CSS だけで完成しますが、矢印キーでの選択移動とパネルの表示切替は @ryo9ra/su-css/behaviors.js が担当します。読み込まなければ、選択が最初のタブに固定されたまま動かない、見た目だけのボタンの並びになります。
disabled はフォーム部品の属性で、リンクには付けられません。aria-disabled="true" なら何にでも同じことを言えます。SuCSS は同じ濃度で淡くします。
どちらもタブ順からは消えません。Tab はいまも両方に止まるので、スクリーンリーダーがたどり着いて「なぜ無効なのか」を読み上げられます。SuCSS は pointer-events: none を付けません。クリックを止めるのはハンドラの仕事で、ここで奪うと CSS では返せなくなります。
領域に inert を付けると、その中のすべてがフォーカス・クリック・選択の対象から外れます。ブラウザはそこまでやって見た目は何も変えないので、淡くするのはスタイルシートの担当です。
上のパネルは Tab がまるごと飛ばします。そちらはブラウザの担当です。
aria-busy="true" は、その要素の中身がまだ確定していないという作者の宣言です。支援技術はすでにこれを読むので、同じことをクラスなしで画面にも出せます。ボタンはラベルの前に、それより大きい領域は角に指標が出ます。角のものはフローの外にあるので、注釈している中身を押しのけません。
直近 10 件を取得しています…
busy は disabled ではありません。上のボタンは押せます。aria-busy が言っているのは「答えがまだ来ていない」であって「この操作は今できない」ではないからです。押させたくなければ disabled を併記します。prefers-reduced-motion では輪が回転を止めてその場に残るので、動きが消えても状態が形として残ります。
上の role="status" がバッジなのは、状態がひと言で済むからです。文章になるならブロックにします — 不具合は role="alert"、知っておくとよいことは role="note"。
直前のデプロイが完了しませんでした。公開はされておらず、ひとつ前のバージョンが動いています。
--hue を変えると、アクセントだけでなく背景のグラデーションも一緒に動きます。
この2つしかないのは、ロールで表せる深刻度がこの2つしかないからです。「成功」や「注意」はどちらなのかを class で言う必要があり、このフレームワークにはそれがありません。
コードブロックはページを押し広げず、横にスクロールします。<figure> と <figcaption> の組み合わせにも対応しています。
<article>
<h2>No classes needed</h2>
<p>Write the element and it is styled.</p>
</article>
assets/brand/ にあります。色・角丸・余白・書体はすべてカスタムプロパティです。:root に数行足せばページ全体が動きます。カスタマイザーでつまみを動かしながら決めることもできます。
:root {
--hue: 158; /* accent colour and background mesh */
--sat: 70%;
--radius: 0.5rem; /* calmer corners */
--max-width: 72ch; /* width of the body column */
--base-size: 1rem;
--font-sans: "Inter", sans-serif;
}
既定ではOSの設定に追従します。<html> の data-theme で固定できます。このページ上部のボタンがやっているのもそれだけです。
<html data-theme="dark"> <!-- always dark -->
<html data-theme="light"> <!-- always light -->
<html> <!-- follow the OS (default) -->