Show HN: Sumi.css – CSS Framework
Show HN: Sumi.css – CSS Framework (github.com)
要約
Sumi.cssは、ミニマリストでクラスレスを基本とするCSSフレームワークです。プレーンでセマンティックなHTMLを記述するだけで、見た目が整います。ビルドステップ不要で、単一ファイル(6.7KB minified/gzipped)でJavaScriptや依存関係はありません。デフォルトでクラスレスですが、必要に応じてクラスを追加でき、CSSカスタムプロパティによる簡単なテーマ設定や、要素スタイルのゼロ指定性による容易な上書きが可能です。アクセシビリティにも配慮されています。
全文翻訳
Sumi.css
ミニマリストでクラスレスを基本とするCSSフレームワーク。プレーンでセマンティックなHTMLを記述するだけで、見た目が整います。特定の要素だけスタイルを適用したい場合にのみクラスを追加してください。
- 単一ファイル、ビルド不要。 6.7KB(圧縮・gzip化済み)、JavaScriptや依存関係はありません。
- デフォルトでクラスレス。 見出し、フォーム、テーブル、カード、アコーディオン、モーダル、ナビゲーションはHTML要素のみでスタイル設定されます。
- ライトモードとダークモード。 訪問者のシステム設定に自動的に従い、
data-themeでどちらかのモードを強制できます。 - テーマ設定が容易。 すべての色、フォント、サイズ、半径はCSSカスタムプロパティです。
- 上書きが容易。 要素のスタイルは指定性がゼロなので、
!importantを使わずに独自のCSSが常に優先されます。 - アクセシブル。 フォーカスリングが表示され、ARIA属性(
aria-invalid、aria-busy、aria-current)による状態管理、およびモーションリデュース(reduced motion)をサポートします。
目次
インストール
ダウンロード。 sumi.min.css をプロジェクトにコピーしてリンクします:
<link rel="stylesheet" href="sumi.min.css">
CDN。 jsDelivr経由でこのリポジトリから読み込みます。
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/vladocar/Sumi.css/sumi.min.css">
開発中は sumi.css(非圧縮版)を使用してください。コメントに各セクションの説明があります。
クイックスタート
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My page</title>
<link rel="stylesheet" href="sumi.min.css">
</head>
<body>
<header>
<nav>
<ul><li><strong>My site</strong></li></ul>
<ul>
<li><a href="/" aria-current="page">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</header>
<main>
<hgroup>
<h6>Welcome</h6>
<h1>Hello, ink.</h1>
</hgroup>
<p class="lead">This page is styled by Sumi with almost no classes.</p>
<a href="#start" role="button">Get started</a>
</main>
<footer>
<p>© 2026 My site</p>
</footer>
</body>
</html>
<header>、<main>、<footer>は、<body>の直接の子要素である場合に中央揃えになります。電話機用にviewportメタタグを保持し、ブラウザが長文を正しくハイフネーションできるようにlangを設定してください。
スタイル設定されるもの
| 要素 |
|---|
h1–h6、p、リスト、blockquote、code、kbd、pre、mark |
<nav>(2つの<ul>付き) |
<button>、[type=submit]、<a role="button"> |
<input>、<select>、<textarea>、<label>、<fieldset> |
type="checkbox"、type="radio"、type="range"、type="file"、type="color" |
<table> |
<article> |
<details> / <summary> |
<dialog> |
<progress>、<meter> |
| 結果 |
|---|
| 流動的なタイプスケールと一貫した垂直間隔 |
ナビゲーションバー、左右のグループ。<aside>内では垂直 |
| ボタン |
| フォーカスリングとヘルプテキスト付きのフル幅フィールド |
| テーマに合わせたカスタムコントロール |
| クリーンなルールと表形式の数値 |
カード。直接の<header>と<footer>はシェードバンドになります |
| アニメーションシェブロン付きアコーディオン |
| ぼかし背景付きモーダル |
| 決定済みおよび未決定のバー |
クラスと属性
SumiがプレーンHTML以外に反応するものすべて:
| クラスまたは属性 |
|---|
.container .container-fluid .narrow |
.grid |
.cols-2 .cols-3 .cols-4 .cols-6 .cols-12 |
.span-2 … .span-9、.span-full |
.row .spread .stack |
.display .lead |
.prose .serif |
.secondary .contrast .outline |
.small .large .full |
role="button" |
role="group" |
role="switch" |
aria-invalid="true" / "false" |
aria-busy="true" |
aria-current="page" |
data-tooltip="… data-placement="bottom" |
data-theme="light" / "dark" |
.dropdown .right |
.callout + .success .warning .danger |
.striped |
.muted .small .center .sr-only .overflow-auto |
| 対象要素 |
|---|
| 任意のブロック |
| ラッパー |
.grid |
| グリッドの子要素 |
| ラッパー |
| 見出し、段落 |
| テキストラッパー |
| ボタン |
| ボタン |
| チェックボックス |
| 任意の要素 |
| 任意の要素 |
| 任意の要素 |
<details> |
| ブロック |
<table> |
| 任意の要素 |
| 効果 |
|---|
| 中央揃えページ幅(72rem)、フル幅、読み取り幅(44rem) |
自動フィット列、各列は少なくとも--s-grid-min(14rem)幅 |
| 48rem以上からの固定列、それ以下は1列 |
| 数列をまたぐ |
| 折り返しフレックス行、スペースを空けた行、垂直スタック |
| ヒーロー見出し、大きな導入段落 |
| 長文読み取り列、セリフ書体 |
| ボタンの色とアウトラインスタイル |
| サイズ、フル幅 |
| ボタンとしてスタイル設定されたリンク |
| ボタン、または入力とボタンをグループ化 |
| トグルスイッチ |
| 赤または緑の検証状態 |
| ローディングスピナー |
| 現在のページをハイライト |
| ツールチップ、上または下 |
| 色モードを強制する |
| ドロップダウンメニュー、右揃え |
| メッセージボックス |
| ゼブラ行 |
| ユーティリティ |
いくつかの例
<!-- ボタン -->
<button>Save</button>
<button class="secondary outline">Cancel</button>
<button aria-busy="true">Saving</button>
<!-- ヘルプテキストと検証付きフィールド -->
<label>Email
<input type="email" name="email" aria-invalid="true" aria-describedby="email-help">
<small id="email-help">Enter a valid email address.</small>
</label>
<!-- スイッチ -->
<label><input type="checkbox" role="switch" checked> Email reminders</label>
<!-- カード -->
<article>
<header><strong>Six-week course</strong></header>
<p>From first strokes to a finished hanging scroll.</p>
<footer><a href="#book" role="button" class="full">€180</a></footer>
</article>
<!-- ドロップダウン -->
<details class="dropdown">
<summary>Export as…</summary>
<ul>
<li><a href="#">PNG</a></li>
<li><a href="#">SVG</a></li>
</ul>
</details>
<!-- モーダル: dialog.showModal(); で開き、フォームがそれを閉じます -->
<dialog id="confirm">
<article>
<header><h3>Delete this file?</h3></header>
<p>This can't be undone.</p>
<footer>
<form method="dialog" class="row">
<button class="secondary outline">Keep</button>
<button class="contrast">Delete</button>
</form>
</footer>
</article>
</dialog>
レイアウト
<!-- 電話ではスタックし、可能な限り多くの列が表示されます -->
<div class="grid">
<div>One</div>
<div>Two</div>
<div>Three</div>
</div>
<!-- タブレット幅以上から12列レイアウト -->
<div class="grid cols-12">
<div class="span-8">Main</div>
<div class="span-4">Sidebar</div>
</div>
<!-- 1つのグリッドの最小列幅を変更 -->
<div class="grid" style="--s-grid-min: 10rem">…</div>
.grid内のカードは均等な高さに引き伸ばされ、フッターが下部で揃えられます。
タイポグラフィ
見出しは流動的なスケールに従います。比率は電話では1.2からデスクトップでは1.28に成長し、ベースサイズは16pxから17pxに緩和されます。メディアクエリは不要です。見出しが大きくなるにつれて、行の高さと文字間隔はタイトになります。
<hgroup>は、見出しをアイブロウ(その前の<h6>)とサブタイトル(その後の<p>)とペアにします。.leadは導入段落を拡大します。.displayはヒーロー見出しを作成します。.proseは、約68文字の読み取り列とハイフネーションを設定します。<article class="prose">は、カードになる代わりにプレーンテキストのままになります。.serifは、要素全体、または<body>全体をシステムセリフスタックに切り替えます。
テーマ設定
すべてのデザイン決定は、--s-で始まるカスタムプロパティです。Sumiの後にロードされるスタイルシートでこれらを上書きします:
:root {
--s-primary: #0f766e;
--s-radius: .25rem;
--s-font-body: "Inter", system-ui, sans-serif;
--s-font-heading: "Fraunces", Georgia, serif;
--s-container: 64rem;
}
トークンは単一の要素でも機能します:
<div class="row" style="--s-primary: #b4235a; --s-radius: 999px">
<button>Book now</button>
<button class="outline">Gift card</button>
</div>
主要なトークン
| トークン |
|---|
--s-primary, --s-on-primary |
--s-secondary, --s-contrast |
--s-bg, --s-surface, --s-card |
--s-text, --s-muted |
--s-border, --s-border-strong |
--s-success, --s-warning, --s-danger |
--s-font-body, --s-font-heading, --s-font-mono, --s-font-serif |
--s-font-size, --s-line-height, --s-heading-weight |
--s-text-display, --s-text-h1 … --s-text-h4, --s-text-lead |
--s-flow, --s-space |
--s-container, --s-narrow, --s-measure, --s-gutter |
--s-radius, --s-shadow, --s-shadow-lg |
| コントロール |
|---|
| ボタン、リンク、フォーカスリング、チェックされたコントロール、およびそれらの上のテキスト |
| セカンダリおよびコントラストボタンの色 |
| ページ、シェードエリア、カード |
| 本文テキスト、セカンダリテキスト |
| ルール、カードエッジ、フィールドボーダー |
| 検証およびコールアウト |
| 書体 |
| ベースサイズ、リーディング、見出しの太さ |
| タイプスケールのステップ |
| テキストブロック、フォーム、コンポーネントの後のスペース |
| ページ幅、読み取り幅、行長、サイドパディング |
| 角と奥行き |
完全なリストは sumi.css の先頭にあります。
ダークモード
Sumiは追加コードなしで訪問者のシステム設定に従います。モードを強制するには、<html>でdata-themeを設定します:
<html lang="en" data-theme="dark">
data-themeは任意の要素でも機能するため、1つのセクションをライトページ内のダークにすることができます。訪問者の選択を記憶するテーマスイッチ:
const root = document.documentElement;
const saved = localStorage.getItem('theme');
if (saved) root.dataset.theme = saved;
document.querySelector('#theme-toggle').addEventListener('click', () => {
const dark = matchMedia('(prefers-color-scheme: dark)').matches;
const current = root.dataset.theme || (dark ? 'dark' : 'light');
const next = current === 'dark' ? 'light' : 'dark';
root.dataset.theme = next;
localStorage.setItem('theme', next);
});
ダークパレットは sumi.css に2回表示されます。1回はシステム設定用、もう1回は data-theme="dark" 用です。ダークカラーを変更する場合は、両方のブロックを変更してください。
スタイルの上書き
要素のスタイルは :where() でラップされており、指定性がゼロなので、プレーンなセレクタで上書きできます:
/* Sumi: :where(blockquote) { border-left: 3px solid … } */
blockquote { border-left-color: var(--s-warning); }
Sumiのトークンから独自のコンポーネントを構築すると、テーマとダークモードが自動的に適用されます:
.badge {
padding: .1em .55em;
border: 1px solid var(--s-border);
border-radius: 999px;
background: var(--s-surface);
color: var(--s-muted);
font-size: .8rem;
}
ブラウザサポート
Chrome、Edge、Firefox、Safariの現在のバージョン。Sumiは :where()、:has()、color-mix() を使用しており、これらはChromeとEdge 111、Firefox 121、Safari 16.2から利用可能です。古いブラウザでも読みやすいページが表示され、ホバーとフォーカスの色はよりプレーンになります。
ファイル
| ファイル |
|---|
sumi.css |
sumi.min.css |
docs.html |
tutorial.html |
| 目的 |
|---|
| コメント付きソース、開発用 |
| 圧縮ビルド、本番用 |
| すべてのコンポーネントとそのHTML、ライト/ダークスイッチ、ライブトークンエディタ |
| Sumiを使ったページ構築のステップバイステップガイド |
ソースを編集した後、圧縮ファイルを再構築するには:
npx lightningcss-cli --minify sumi.css -o sumi.min.css
ライセンス
MIT © 2026 Vladimir Carrer