Awesome CSS Protips
CSS Protipsを扱う資料や関連プロジェクトをまとめたAwesomeリストです。
目次
プロ向けヒント
- Use a CSS Reset
- Inherit
box-sizing - Use
unsetInstead of Resetting All Properties - Use
:not()to Apply/Unapply Borders on Navigation - Check if Font Is Installed Locally
- Add
line-heighttobody - Set
:focusfor Form Elements - Vertically-Center Anything
- Use
aspect-ratioInstead of Height/Width - Comma-Separated Lists
- Select Items Using Negative
nth-child - Use SVG for Icons
- Use the “Lobotomized Owl” Selector
- Use
max-heightfor Pure CSS Sliders - Equal-Width Table Cells
- Get Rid of Margin Hacks With Flexbox
- Use Attribute Selectors with Empty Links
- Control Specificity Better With
:is() - Style “Default” Links
- Intrinsic Ratio Boxes
- Style Broken Images
- Use
remfor Global Sizing; Useemfor Local Sizing - Hide Autoplay Videos That Aren’t Muted
- Use
:rootfor Flexible Type - Set
font-sizeon Form Elements for a Better Mobile Experience - Use Pointer Events to Control Mouse Events
- Set
display: noneon Line Breaks Used as Spacing - Use
:emptyto Hide Empty HTML Elements - Use
margin-inlineinstead ofmargin
CSS Resetを使う
CSS resetは、要素スタイルを白紙から始め、異なるブラウザー間のスタイル一貫性を保つのに役立ちます。多くのresetパターンがありますが、より簡素なreset方法も使えます:
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}これで要素からmarginとpaddingが除去され、box-sizingによりCSSボックスモデルでレイアウトを管理できます。
デモ
ヒント: 下記の
box-sizingを継承するヒントに従う場合、CSS resetにbox-sizingプロパティを含めない選択もできます。
box-sizingを継承する
box-sizingをhtmlから継承させます:
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}これにより、別の振る舞いを活用するプラグインや他のコンポーネントでbox-sizingを変更しやすくなります。
Demo
すべてのプロパティをResetせずunsetを使う
要素のプロパティをresetする場合、個々のプロパティをすべてresetする必要はありません:
button {
background: none;
border: none;
color: inherit;
font: inherit;
outline: none;
padding: 0;
}all短縮形で要素のすべてのプロパティを指定できます。値をunsetに設定すると、要素のプロパティは初期値に変わります:
button {
all: unset;
}ナビゲーションのborder適用/解除に:not()を使う
borderを設定して…
/* add border */
.nav li {
border-right: 1px solid #666;
}…最後の要素で解除する代わりに…
/* remove border */
.nav li:last-child {
border-right: none;
}…:not()疑似クラスを使い、必要な要素だけに適用します:
.nav li:not(:last-child) {
border-right: 1px solid #666;
}このCSSセレクターは、人が説明するように読めます。
Demo
フォントがローカルにインストール済みか確認する
リモートから取得する前にフォントがローカルにインストールされているか確認できます。これはパフォーマンス上も良いヒントです。
@font-face {
font-family: "Dank Mono";
src:
/* Full name */ local("Dank Mono"), /* Postscript name */ local("Dank Mono"),
/* Otherwise, download it! */ url("//...a.server/fonts/DankMono.woff");
}
code {
font-family: "Dank Mono", system-ui-monospace;
}このヒントとデモを共有したAdam Argyleに感謝します。
line-heightをbodyへ追加する
line-heightを各<p>、<h*>、et al.へ個別に追加する必要はありません。代わりにbodyへ追加します:
body {
line-height: 1.5;
}これによりテキスト要素はbodyから簡単に継承できます。
Demo
フォーム要素に:focusを設定する
視覚を使うキーボードユーザーは、ページ内のどこへキーボードイベントが届くかをfocusで判断します。フォーム要素のfocusを、ブラウザー既定実装より目立ち一貫したものにします:
a:focus,
button:focus,
input:focus,
select:focus,
textarea:focus {
box-shadow: none;
outline: #000 dotted 2px;
outline-offset: 0.05em;
}Demo
何でも垂直中央揃えにする
いいえ、黒魔術ではありません。本当に要素を垂直中央揃えにできます。flexboxで実現できます…
html,
body {
height: 100%;
}
body {
align-items: center;
display: flex;
justify-content: center;
}…CSS Gridでも可能です:
body {
display: grid;
height: 100vh;
place-items: center;
}ヒント: 別のものを中央揃えにしたいですか。垂直、水平、何でも、いつでも、どこでも。CSS-Tricksには、そのすべてを扱う優れた解説があります。
Demo
高さ/幅の代わりにaspect-ratioを使う
aspect-ratioプロパティにより、要素のサイズ設定と一貫した幅対高さ比の維持を簡単に行えます。これはレイアウトシフトを防ぐレスポンシブウェブデザインで非常に役立ちます。画像の高さ/幅値が変わってもレイアウトが崩れないよう、object-fitとともに使います。
img {
aspect-ratio: 16 / 9; /* width / height */
object-fit: cover;
}aspect-ratioプロパティの詳細は、このweb.dev記事を参照してください。
Demo
カンマ区切りリスト
リスト項目を本物のカンマ区切りリストのように見せます:
ul > li:not(:last-child)::after {
content: ",";
}:not()疑似クラスを使うと、最後の項目にカンマは追加されません。
注記: このヒントは、特にスクリーンリーダーに関するアクセシビリティには適さない可能性があります。また、ブラウザーでのコピー&ペーストはCSS生成コンテンツでは機能しません。注意して進めてください。
負のnth-childで項目を選択する
CSSで負のnth-childを使い、1からnまでの項目を選択します。
li {
display: none;
}
/* 1から3までの項目を選択して表示する */
li:nth-child(-n + 3) {
display: block;
}また、すでに:not()の使用を少し学んだので、次を試してみてください:
/* 最初の3つを除くすべての項目を選択して表示する */
li:not(:nth-child(-n + 3)) {
display: block;
}Demo
アイコンにはSVGを使う
アイコンにSVGを使わない理由はありません:
.logo {
background: url("logo.svg");
}SVGはあらゆる解像度で適切に拡大縮小され、IE9までのすべてのブラウザーでサポートされています。.png、.jpg、.gif-jif-whatevファイルをやめましょう。
NOTE: If you have SVG icon-only buttons for sighted users and the SVG fails to load, this will help maintain accessibility:
.no-svg .icon-only::after {
content: attr(aria-label);
}「ロボトミーされたフクロウ」セレクターを使う
奇妙な名前かもしれませんが、ユニバーサルセレクター(*)を隣接兄弟セレクター(+)と使うと、強力なCSS機能を得られます:
* + * {
margin-top: 1.5em;
}この例では、文書フロー内で他の要素に続くすべての要素がmargin-top: 1.5emを受け取ります。
TIP: For more on the “lobotomized owl” selector, read Heydon Pickering’s post on A List Apart.
Demo
Pure CSSスライダーにmax-heightを使う
overflow hiddenとmax-heightを使ってCSSのみのスライダーを実装します:
.slider {
max-height: 200px;
overflow-y: hidden;
width: 300px;
}
.slider:hover {
max-height: 600px;
overflow-y: scroll;
}要素はhover時にmax-height値まで拡張され、overflowの結果としてスライダーが表示されます。
等幅のテーブルセル
テーブルの扱いは面倒になりがちです。セルを等幅に保つため、table-layout: fixedを試してください:
.calendar {
table-layout: fixed;
}苦痛のないテーブルレイアウトです。
Demo
Flexboxでmargin hackをなくす
列のgutterを扱う際、flexboxのnth-、first-、last-childのhackをspace-betweenプロパティでなくせます:
.list {
display: flex;
justify-content: space-between;
}
.list .person {
flex-basis: 23%;
}これで列のgutterは常に等間隔で表示されます。
Use Attribute Selectors with Empty Links
Display links when the <a> element has no text value but the href attribute has a link:
a[href^="http"]:empty::before {
content: attr(href);
}That’s really convenient.
Demo
NOTE: This tip may not be ideal for accessibility, specifically screen readers. And copy/paste from the browser doesn’t work with CSS-generated content. Proceed with caution.
:is()で詳細度をより良く制御する
:is()疑似クラスは、複数のセレクターを一度に対象にし、冗長性を減らしてコードの可読性を高めます。大きなセレクターをよりコンパクトな形式で書く際に非常に役立ちます。
:is(section, article, aside, nav) :is(h1, h2, h3, h4, h5, h6) {
color: green;
}上記のルールセットは、次の数多くのセレクター規則と同等です…
section h1,
section h2,
section h3,
section h4,
section h5,
section h6,
article h1,
article h2,
article h3,
article h4,
article h5,
article h6,
aside h1,
aside h2,
aside h3,
aside h4,
aside h5,
aside h6,
nav h1,
nav h2,
nav h3,
nav h4,
nav h5,
nav h6 {
color: green;
}Demo
「既定」リンクをスタイル設定する
「既定」リンク用のスタイルを追加します:
a[href]:not([class]) {
color: #008000;
text-decoration: underline;
}これで通常class属性を持たないCMS経由で挿入されたリンクに、カスケードへ全般的な影響を与えず区別を付けられます。
内在比率ボックス
内在比率を持つボックスを作るには、divへ上または下のpaddingを適用するだけです:
.container {
height: 0;
padding-bottom: 20%;
position: relative;
}
.container div {
border: 2px dashed #ddd;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}paddingに20%を使うと、ボックスの高さは幅の20%になります。ビューポートの幅にかかわらず、子divはアスペクト比を保ちます(100% / 20% = 5:1)。
Demo
壊れた画像をスタイル設定する
少しのCSSで壊れた画像をより見栄えよくします:
img {
display: block;
font-family: sans-serif;
font-weight: 300;
height: auto;
line-height: 2;
position: relative;
text-align: center;
width: 100%;
}次に、壊れた画像のユーザーメッセージとURL参照を表示するため、疑似要素規則を追加します:
img::before {
content: "We're sorry, the image below is broken :(";
display: block;
margin-bottom: 10px;
}
img::after {
content: "(url: " attr(src) ")";
display: block;
font-size: 12px;
}ヒント: このパターンのスタイル設定については、Ire Aderinokunの記事で詳しく学べます。
グローバルなサイズにはrem、ローカルなサイズにはemを使う
rootで基準font sizeを設定した後(html { font-size: 100%; })、テキスト要素のfont sizeをemへ設定します:
h2 {
font-size: 2em;
}
p {
font-size: 1em;
}次にモジュールのfont-sizeをremへ設定します:
article {
font-size: 1.25rem;
}
aside .module {
font-size: 0.9rem;
}これで各モジュールは区画化され、スタイル設定が容易になり、保守性と柔軟性が高まります。
ミュートされていない自動再生動画を隠す
これはカスタムユーザースタイルシートに最適なテクニックです。ページ読み込み時に自動再生される動画の音でユーザーを圧倒しないようにします。音声がミュートされていない場合は動画を表示しません:
video[autoplay]:not([muted]) {
display: none;
}ここでも、:not()疑似クラスを活用しています。
柔軟な文字サイズに:rootを使う
レスポンシブレイアウトの文字サイズは、各ビューポートに合わせて調整できるべきです。:rootを使い、ビューポートの高さと幅に基づいてfont-sizeを計算できます:
:root {
font-size: calc(1vw + 1vh + 0.5vmin);
}これでroot em単位を:rootが計算した値に基づいて利用できます:
body {
font: 1rem/1.6 sans-serif;
}Demo
モバイル体験を改善するためフォーム要素にfont-sizeを設定する
モバイルブラウザー(iOS Safari、et al.)が<select>ドロップダウンをタップしたときHTMLフォーム要素をズームしないよう、セレクター規則へfont-sizeを追加します:
input[type="text"],
input[type="number"],
select,
textarea {
font-size: 16px;
}Pointer Eventsでマウスイベントを制御する
Pointer eventsでは、マウスが触れている要素とどのように対話するかを指定できます。たとえばボタンの既定pointer eventを無効にするには:
button:disabled {
opacity: 0.5;
pointer-events: none;
}とても簡単です。
間隔に使う改行にdisplay: noneを設定する
Harry Robertsが指摘したように、これはCMSユーザーが間隔のために余分な改行を使うことを防ぐのに役立ちます:
br + br {
display: none;
}空のHTML要素を隠すため:emptyを使う
CMSまたは動的挿入で内容がまだ設定されていない空のHTML要素(例: <p class="error-message"></p>)があり、レイアウトに不要な空間を作っている場合、:empty疑似クラスを使ってレイアウト上から隠します。
:empty {
display: none;
}注記: 空白を含む要素は空とは見なされないことに注意してください。例:
<p class="error-message"> </p>。
サポート
Chrome、Firefox、Safari、Edgeの現行バージョン。
margin-inlineをmarginの代わりに使う
要素のインライン開始・終了marginはmargin-inlineで定義します。margin-leftとmargin-rightの代わりに、inlineプロパティで両方を定義できます。
.div {
margin-inline: auto;
}同じことは、block開始・終了margin、すなわちmargin-blockをmargin-topとmargin-bottomで定義する場合にも行えます。
.div {
margin-block: auto;
}Demo
翻訳
注記: 増え続ける翻訳済みヒントのリストを保守する時間が少なくなっています。新たなヒントの追加には十数件以上の翻訳への追加が必要です。そのため、翻訳済みREADMEにはメインREADMEにあるすべてのヒントが含まれない可能性があります。