CSSは通常、すぐに失敗しない。 それは1年後に失敗し、システムが実際に使用され、何かを変えることはリスクを感じる。 スタイルは重く感じ始める DevTools を開いて、ルールを飛び越えて、なぜ何かが機能するのかを理解しようとします。 悪い CSS は醜いだけではなく、高価なもので、単純な UI アップデートが 3 分ではなく 3 日かかる理由です。 コードがやってる . あまりに 巣立つことが多すぎて、具体性が多すぎて、早めに決断を下すことが多すぎて、取り消しにくいことが多すぎる。 この記事は、トリックやツールを通じてではなく、プロジェクトが成長するにつれて CSS をシンプルに、読みやすい、安価に変更するためのいくつかの習慣を通してです。 これが、もっと早く学びたかったことだ。 CSSで始めることは最初の間違いです。 私はこの記事がCSSのことを知っていますが、ジュニアが犯す最も一般的な間違いの1つは、タスクにジャンプし、すべてを一度に構築することです. Styles, JavaScript, Markup, early abstractions. 通常、最も複雑な部分から始まる、または最も面白い部分から始まる。 CSSは誘惑的で、それは実感できるので、すぐに結果を見ることができます。 より良いアプローチは、CSSを置き去りにし、停止し、遅くなり、マークアップから始めることです。 あなたがアプリケーション全体を構築している場合は、ページシェルから始める。 マーク、ヘッダー、主要セクション。 最初にそれに取り組んでください。 ページを読み始めて終了します。 それは意味がありますか? スタイルに移動するときだけです。 あなたがより小さい機能で作業している場合は、同じアイデアが適用されます。最初にマークアップを置いて、アプリの残りの部分にどのように適合するかを確認します。 マークアップから始めることで、あなたは外見ではなく意図について考えるようになります。 彼らが何を HTML ファーストアプローチでは、システムを単純で予測可能にする構造、意味、制約を定義します。 は 見た目 CSS should adapt to that, not the other way around. あなたがスタイリングに急いでいるとき、あなたは視覚的なヒントの周りにマークアップを形作る傾向があります。追加の包装。間違ったタグ。 素晴らしいが、セマンティックに間違っている、あるいはスケールできない。 見る 最初にマークアップを行うことで、あなたは堅固な基盤に閉じ込められます。 アクセシビリティ、ドキュメントの概要、キーボードフロー、コンテンツの階層は主に事前に解決されます。 それはまた、あなたを良い方法で減速させます。あなたは早めにエッジケースを捕獲します。あなたは物事がどこに属していないかを見ます。 要するに、HTML-firstは、他のすべてのことを意味をもたらします。 CSSがあなたが思っている以上に働くとき コードレビューで見るもう一つの一般的な間違いは、ジュニアが行うことです。 よく見かけないのですが、簡単な例をいくつかご紹介します。 あまりに コンテンツの列を水平に中心にしたいとします: .entry-content { max-inline-size: 48rem; margin: 0 auto; /* ❌ Avoid this! */ } これは機能します. You set a max width and center the element by using auto margins. あなたは、自動マージンを用いて最大幅を設定し、要素を中心にします。 しかし、あなたが気づかないかもしれないことは、あなたも上位と下位の境界をゼロに設定しているということです。 ほとんどの場合、ショートヘッドは単に短いので使われます 代わりにあなたが望むのは、以下の通りです。 .entry-content { max-inline-size: 48rem; margin-inline: auto; /* ✅ Do this */ } 結果は同じで、副作用はなく、意図は大きい。 もう一つの共通例: .button--secondary { background: var(--color--dark-gray); } これは、背景の色を使用して、 しかし、その他のバックグラウンド関連のプロパティのバックグラウンドもリセットします。 --color--dark-gray 実は、たくさん、 背景 画像 なし バックグラウンド 0% 0% バックグラウンド 自動車 バックグラウンド / repeat オリジナルタイトル: Padding-Box バックグラウンド - Border Box Background-attachment スクリプト ほとんどの場合、それはあなたが望むものではありません。これは簡単に後で対処しなければならない不快な副作用につながる可能性があります。 代わりに望むのは、これでしょう。 .button--secondary { background-color: var(--color--dark-gray); } 以前と同じ考えですが、外科的ですが、実際に変えたいと思っているものを変えるだけです。 同じ原則は、他の短期資産、例えば、 で、 で、 で、 , and others. Be careful when using them as shorthands. または shorthands entirely を使用しないでください。 border transform transition font あまりにも多くのことをするというもっと一般的な例は、早すぎるほど具体的であることです。 a { text-decoration: none; background-image:linear-gradient(to right, currentColor, currentColor); background-position:0%100%; background-repeat: no-repeat; background-size:100%2px; transition: background-size 0.3s; &:hover, &:focus-visible { background-position:100%100%; } } このスナップは、リンクにアニメーションのサブラインを追加します。 問題は、すべての人が タグはテキストリンクです. 画像はリンクすることができます. プロフィールアバターはリンクすることができます. ボタンはしばしばアンカーとしてマークされます. <a> 突然、この「賢い」グローバルなスタイルは、あなたのロゴの下に奇妙な2pxのラインを追加したり、あなたの主なボタンのバックグレーディングを破ったりしています。 今、あなたはプロジェクトの残りの部分を、あなたが作業しているすべての非テキストリンクのための「undo」スタイルを書くことで、キャスケードと戦うことに費やします。 visual debt これをいくつかの方法で解決できます. One option is to target text links inside content. コンテンツ内のテキストリンクをターゲットにします。 .entry-content:is(h1, h2, h3, h4, h5, h6, p, li) > a { /* styles here */ } しかし、それでも、マークアップに応じて、あまりにも狭く、または広すぎる可能性があります. It relies on a specific HTML structure that may change. 私の好きなアプローチは、ユーティリティクラスです。 .has-animated-underline { /* styles here */ } これをクラスに移すことで、あなたは行動を起こします。 それは明示的で意図的であり、最も重要なことは、最初に壊れていないものを修復する必要はありません。 opt-in rather than opt-out 3. When Mobile Is A Afterthought(モバイルが後悔であるとき) モバイルウェブトラフィックは2016年にデスクトップを世界的に超えました - ほぼ10年前です。それでも私はまだデザイナーがデスクトップコンプで作業し、デスクトップの仕事を最初に提示することにほとんど時間を費やしているのを見ています。 まだ後ろ向きを感じています。 好きであろうと嫌いであろうと、私たちは最初に電話を通じてインターネットを体験します. それはまた変わるかもしれないが、それは今日の現実です。 私たちがウェブを構築する方法は、それを反映すべきです。 実際には、これが今のスタイリングのアプローチです。 マークアップを置く(それについて話しました 😉)。 ブラウザを約400pxに変更し、デスクトップが存在しないかのようにアプリや機能をスタイルします。 一旦モバイルで動作すると、ブラウザをデスクトップに変更し、スタイルに2回目のパスを行う。 この方法で働くことは、自然にあなたのプロジェクトをアクセス可能にし、小さなスクリーンに備えるという点で、80%(ランダムな数字が正しいと感じる)を得ます。 これが私たちをモバイルファーストの実装に有機的に導きます。 私がウェブ開発を始めたとき、メディアクエリはほとんど何もありませんでした. 私たちは携帯電話でウェブを閲覧していませんでした. それはデスクトップだけの宇宙でした. その後、iPhoneが登場し、メディアクエリが応答性の高いレイアウトの主なツールとなった。Web対応デバイスの数は限られていたので、断固とした断片のセットで抜け出すことができます。 /* phones */ @media (max-width: 480px) {} /* large phones and small tablets */ @media (max-width: 767px) {} /* tablets */ @media (min-width: 768px) and (max-width: 1024px) {} /* desktop */ @media (min-width: 1025px) {} モバイルファーストじゃないからね(笑) アプローチ min-width 今日、現実は異なります. 単独でブレークポイントを使用するために設計するデバイスや画面サイズが多すぎます. 自然に全体の範囲に適応するツールに頼るのはしばしば賢い。 例えば: Intrinsic Layouts with Grid or Flexbox(グリッドまたはフラックスボックス) clamp() for font sizes, spacing, and dimensions を使用する流動値 コンテナ欲求 メディアクエリはまだ有用ですが、最初にアクセスするツールではありません。 レイアウトがブレイクポイントのためだけに機能する場合、それはおそらくあまりにも硬く、それらなしで動作する場合、メディアクエリは、基盤ではなく反応構造に小さく、意図的な調整になります。 4. Cascade を使用する代わりに戦う これは、若手エンジニアが戦うことがよく見られるもう一つの分野です。 多くのCSSフレームワークとソリューションが1つの主な機能を解決するために存在します:カスケード. And I get why. If you jump into CSS without much experience, it can feel chaotic. 多くのCSSフレームワークとソリューションが存在します。 あなたはルールを書きますが、それは何もしません。あなたはそれを調整し、突然別の何かが壊れます。それに加えて、ユーザエージェントスタイルシートは背景で独自のことをしています。 それは、CSSが他のほとんどの言語と同様ではないので、失望します。JavaScriptでは、モジュールを作成できますし、何も漏れません。 あなたは同じようにCSSに近づくことはできません. あなたが試すなら、それはあなたの顔に本当に硬く噛むでしょう。 すべてのCSSの変更は、一度に2つの範囲で生存します:あなたがスタイリングしているものと、それに流入するシステムの残りの部分。 前回の例に戻ると、これだけを書くことはできません: a { text-decoration: none; background-image:linear-gradient(to right, currentColor, currentColor); background-position:0%100%; background-repeat: no-repeat; background-size:100%2px; transition: background-size 0.3s; &:hover, &:focus-visible { background-position:100%100%; } } そうすると、そのアンカーがテキストリンクではない場合でも、ページのすべてのアンカーに背景関連の属性が適用されます。 ほとんどの場合、それはあなたが望むものではありません。 いくつかのエンジニアは、これを難しい方法で学び、子供の頃の熱い炉に触れ、二度とやらないように学ぶように、完全に滝を避けることによって反応します。 それは間違いだと思うが、繰り返しを繰り返すことが多いからだ。 以下は、私が最近取り組んだプロジェクトの例です。 @define-mixin focus-state { &:focus-visible { outline: var(--outline--color) var(--outline--style) var(--outline--width); outline-offset: var(--outline--offset); } } その後、複数のコンポーネントに組み込まれました: .button { @mixin focus-state; } a { @mixin focus-state; } .pagination-link { @mixin focus-state; } ...そしてそのように。 Focus outlines should look consistent across a project, with very few exceptions. 焦点の概要は、非常に少ない例外を除いて、プロジェクト全体で一貫して見えるべきである。 この設定では、すべてのミキシン呼び出しは、同じ CSS を繰り返し生成します。 よりエレガントなアプローチは、カスケードに依存し、これをグローバルに定義することです。 :focus-visible { outline-color:var(--outline--color); outline-offset:var(--outline--offset); outline-style:var(--outline--style); outline-width:var(--outline--width); } 現在、目に見える焦点状態を受け取るすべての要素は、既定で同じスタイリングを取得します。 そして、何かが異なる必要がある稀なケースでは、それを地元に置き換えることができます: .pagination-link { --outline--offset: -2px; } シンプル、コンパクト、そして予測可能。 同じ考えは、こういうものに当てはまる。 で、 マージンリセット、 , and other styles that should behave consistently across the app. その他のスタイルは、アプリ全体で一貫して動くべきです。 box-sizing ::selection text-wrap A quick gut check helps here. If a style looks それぞれの部品で、同じように、 例外として、それはおそらくあなたのグローバルなスタイルに属します。 exactly very few カスカードを無視しないで、自分の利点に使ってください。 具体性とは、物事が引き続き分離し続けるところである。 これは通常、「CSSを書きましたが、機能しません」という理由です。 具体的に何が具体的なのか分からないのですが、MDNは ここで重要なのは、高い特定性が、第三者のライブラリや他人のコードで作業するときに苦痛の主な原因の一つであるということです。 ほんとにうまくやっている この例を挙げる: .layout > :not(.alignleft):not(.alignright):not(.alignfull):not(.alignwide) { max-width: var(--content-width); margin-left: auto; margin-right: auto; } ここでは、直接の子どもたちを中心に、 横向きで、マックス幅を適用する - 子供を除くすべての で、 で、 そして、 . .layout alignleft alignright alignfull alignwide このコードが臭い理由は2つあります。 まず、これはブラックリストのパターンです。我々はすべてをスタイリングしています。 問題は「すべて」が常に時間とともに変化するということです プロジェクトが成長するにつれて、あなたはほぼ確実により多くの例外を追加します いつかあなたはそれを追加するのを忘れ、何かが壊れます。 除く 第二に、あなたが追加する各セレクターは、特定性を増加させます。上記のスニップはすでに それを超えるためには、さらに強力な選択肢が必要であることを意味します。 で、 , or wrapping everything in 言い換えれば、あなたは複雑さをより複雑に修正します。 0.5.0 !important @layer :where() WordPress は、CSS アーキテクチャなしで始まり、カオスで終わる良い例です。 body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) { max-width: var(--wp--style--global--content-size); margin-left: auto !important; margin-right: auto !important; } I'm getting mixed signals here. We corned ourselves with the pattern, realized it was a bad idea, recovered with その後...応用 限界を超えることは不可能なのだろうか? 確かにその理由はあるが、人間...そんなに挫折するものではない。 :not() :where() !important 確かに、これらすべてをやることができる・・・。 ...あるいは、より意図的になり、自分自身に少しの平和を買うことができます。 /* 0.1.0 */ .layout > * { max-width: var(--content-width); margin-left: auto; margin-right: auto; } /* 0.2.0 */ .layout > .alignleft, .layout > .alignright { --content-width: var(--content-width--narrow); } /* 0.2.0 */ .layout > .alignwide { --content-width: var(--content-width--wide); } /* 0.2.0 */ .layout > .alignfull { --content-width: var(--content-width--full); } 読みやすく、考えやすく、基本ルールは、 例外は . 0.1.0 0.2.0 予測的・意図的。 以下は、良い理由なしで特定性が増加するもう一つの一般的な方法です。 /* ❌ combine element with a class ❌ element nested inside the block ❌ modifier nested inside the block */ a.button { &.button__label {...} &.button--secondary {...} } この例で: a と .button を組み合わせる理由がない場合は、しないでください。 .button__label を .button に埋め込む理由がない場合は、それをしないでください。 修正クラスも同じです。 新しいコンポーネントを配信している場合は、通常、代わりに望むもの: /* ✅ no element + class combination ✅ elements and modifiers stay flat */ .button {...} .button__icon {...} .button--primary {...} 以下は私が従う指のルールです。 デフォルトで単一クラス選択者を選択します。 選択肢を積み重ねる代わりにユーティリティの変数を使用してください. Source order will help you here. 具体性を 0.1.0 または 0.1.1 で保持します。 あなたが配信する機能で 0.2.0 を超えないでください。 アプリコード内の #id 選択者や inline スタイルは避けましょう. They spike specificity and are painful to override. 高レベルの特定性は、まだリファクターできない第三者コードまたは古代コードを優先する場合にのみ使用します。 ノート ON で、 そして、 :where() @layer @scope 私はこれらのツールを完全に認識しています. あなたはゼロに特定性を減らすことができます。 孤立したスタイルと , and scope selectors with . :where() @layer @scope 彼らは強力で、彼らは彼らの場所を持っていますが、彼らは悪い建築を修復しません。 同じ特異性のルールは、それぞれの層内とそれぞれの範囲内で依然として適用されます。 あなたの将来の自分は、あなたに感謝するでしょう。