16
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CSSAdvent Calendar 2023

Day 4

「CSSの進化、知らなくて許されるのは小学生までだよねー」

Last updated at Posted at 2023-12-03

はじめに

ちゃんとCSS勉強されていますか?HTML勉強されていますか?何となくで誤魔化しでCSS使ってませんか?float:left;駆使してレスポンシブデザイン作ろうとしていませんか?

Webデザイナー、制作者のみなさん、古い情報ばかり追ってませんか?あなたが参考にしている記事はいつ書かれた記事ですか?WordPressの使い方、テーマの使い方ばかり追って、本質のコードを疎かにしていませんか?「コピペでOK!」みたいなのでとりあえずコピペで逃げてませんか?CSSでネストが使えることはちゃんと知っていますか?

フロントエンドエンジニアのみなさん、CSS疎かにして何でもJSでやろうとしていませんか?それではフロントエンジニアではなくJavaScriptエンジニアではないですか?子供の前で胸張ってフロントエンドエンジニアですって言えますか?「CSS完全に理解した」とかとりあえずネタ言って、本当はできない自分を誤魔化したりしてませんか?

バックエンド、インフラエンジニアのみなさん、こんにちは。

IEの終了した現在、ブラウザの進化はえげつないです。年始には97だったChromeのバージョンが、もう120になろうとしています。ブラウザの進化に伴って、HTML,CSS,JavaScriptも進化しています。特にCSSは、今までできなかったようなことがかなりできるようになってきました。
これを機会に年末年始、CSSの最新機能を振り返ってみませんか?

ネスト

「いやいや、ネストはSassだろ」とお思いのあなた、もう普通のCSSでネストを使えますよ。

See the Pen CSS Nest by Tomoya Masaki on CodePen.

抜粋
.container {
  margin-left:2rem;
  >.button {
    cursor:pointer;
    background:#6de7a8;
    /* 省略 */
    &:hover { 
      scale:1.1;
      opacity:0.5;
    }
  }
}

CSSだけでちゃんとネストが書けるのめちゃくちゃ便利ですね。&を利用すると親のセレクタを参照できます。この場合は.buttonのhoverを参照しています。これでもうSassの必要性がまた一段と下がったのではないのでしょうか。

新しいmargin記法、margin-inlinemargin-block

中央寄せするときに、よく使われるのが

.content {
    margin-left:auto;
    margin-right:auto;
}

です。これが一行でかけるようになりました。

.content {
    margin-inline:auto;
}

また、縦方向に関しても

.content {
    margin-block:auto;
}

と簡潔にかけるようになりました。厳密にいうと、文字の方向によります。基本的には文字が左から右方向なので、margin-inlineは左右になります。これが上から下方向の、日本語の縦書きのような文章だと上下になります。write-modeで変わるみたいです。
左右の幅を変えたかったら、

.content {
     margin-inline:40px 60px;
 }

のように書きます。

アスペクト比を設定できる、aspect-ratio

画像などで、比を簡単に保てるプロパティです。aspect-ratioを使えば、16:9の画像も変にwidthとheightを細かく設定しなくてもよくなります。

.container {
    width:100%;
    aspect-ratio: 16 / 9;
}

すりガラス表現が1行で、backdrop-filter

すりガラスのような表現が、backdrop-filter:blur(3px);のような形で書けます。

See the Pen backdrop-filter on CodePen.

抜粋
.backdrop {
    backdrop-filter:blur(3px);
}

たったこれだけで、iPhoneの通知とかでよくみかけるようなすりガラス表現ができます。非常に楽ですね。比較としてとなりに背景を透過したものを載せました。
ぼかし表現がめちゃくちゃ簡単にできました。

あらゆるコンテナの幅で条件分岐、コンテナクエリ

メディアクエリはご存知の方が多いと思います。画面サイズによって条件を変える、レスポンシブデザインでよくある手法です。
コンテナクエリはその強化版で、様々なコンテナサイズによって条件を変えられます。

See the Pen Container Query on CodePen.

抜粋
.container {
  container-type: inline-size;
  border:solid 1px;
}

@container (width < 500px) {
  .contents {
    flex-direction:column;
  }
}

container-type: inline-size;で、基準となるコンテナを指定してあげます。このコンテナの幅によってコンテナクエリが効きます。実際に動かしてもらうとわかりますが、.containerのwidthによってBoxが横並びになったり縦並びにになったりします。この場合は500px未満のときに縦並びにできます。
メディアクエリだとデバイスサイズでしか今まで判定できなかったのが、コンテナクエリだとすごく自由度が高く判定を行えます。レスポンシブデザインでなくても、可変幅なコンテナがあれば適用できます。
例えば、文字の長さによって、短かったら中央寄せ、長かったら左寄せみたいなことだってできます。また、横幅でなく縦幅だって判定に使えます。
コンテナクエリに関してはめちゃくちゃ沼が深そうなのでこちらのサイトの記事を貼っておきます。

ちなみに気づきましたか?今までmin-width:100pxとかやっていたのを、width < 100pxみたいに書けるようになったの。数学的に不等式を書けるようになりました。等号の入った不等式も扱えます。めちゃくちゃ直感的になりましたね。なので、500px <= width < 1000pxみたいに書けるようになりました。これはメディアクエリでも同じです。

詳しく解説されていた記事があったのでそちらを貼っておきます。

優先度も自由自在、カスケードレイヤー

CSSの悩ましい問題として詳細度の問題があります。reset cssがなぜか優先されていたり、他のcssが優先されたり、それで!importantまみれになったり。
そこであらたに、カスケードレイヤーという概念が現れました。

See the Pen Cascade Layer on CodePen.

抜粋
@layer reset,base,utility;

@layer reset {
  h1 {
    font-size:1rem;
    letter-spacing:0rem;
  }
}

@layer base {
  h1 {
    font-size:1.2rem;
    letter-spacing:.1rem;
    color:#000;
  }
}

@layer utility {
  h1 {
    color: #007bc7;
  }
}

各プロパティ@layer [名前]で囲うとそれがレイヤーになります。そして一行目の@layer reset,base,utility;で優先度を決められます。右に行くほど優先度が高いです。
実際にこのCodepen内で、@layerのreset,base,utilityの順番を変えたり消してみたりしてください。各layerとマッチしたstyleがちゃんと適用されています。
レイヤー化されているCSSはされていないCSSより詳細度が低くなります。レイヤー同士で詳細度の高さも決められます。そのため、reset cssを一番優先度の低いCSSレイヤーに、カスタマイズをしたベースのCSSをreset cssよりも優先度を高く、そしてCSS-in-JSやTailwind CSSなどでコンポーネントに直接適用させる細かいスタイルはレイヤー化しなければ一番優先度が高くなります。
これで悩ましい!important問題ともうまくおさらばしやすいのではないでしょうか?

新登場@scopeルール

これは2023年11月現在はまだ残念ながらChromeおよびEdgeのみ対応です。
CSSの適用範囲を制限できるというめちゃくちゃ画期的な機能です。@scopeをつけたクラス内はそれ以外の場所はスタイルの影響を受けないという機能です。今までクラス名に悩まされてBEMなどの記法で苦労していたのがなくなります。スーパーめちゃんこ重宝する機能です。
これに関してはここには書ききれないと思い、思いをまるまる一記事に書いたので、こちらをご覧ください。

クラス名がバッティングしてしまう、他のスタイルが適用されてしまうなどの悩みがほとんど解決されるのではないかと思っています。自分の中では、CSSライブラリ論争はすべて終了してしまうんじゃないかってレベルの強烈な衝撃を受けました。これとカスケードレイヤーを組み合わせれば詳細度などをあまり気にせず自由自在にCSSを記述できるんじゃないでしょうか?
おそらく、@scopeは今後必須間違いなしの技術だと思います。フロントエンドエンジニア、Webデザイナーに関わらず。

めちゃくちゃ便利な:has()

:before:hoverなどと同じ擬似クラスの一種です。.card:has(.hoge)と書けば、.hogeというクラスが中にある.cardにのみスタイルを設定できます。

See the Pen :has() on CodePen.

.box {
  /* 省略 */
  &:has(h3) {
    background:#999999;
  }
}

この場合はh3タグを持っているボックスのみ色が暗くなるようにしています。複数リストを並べるときに、特定の条件にマッチする要素のみスタイルを設定するみたいなときにめちゃくちゃ有効です。:not()と組み合わせればその逆も可能です。
活用方法がめちゃくちゃあるの、ものすごく便利な:has()擬似クラスです。細かいスタイル調整に困ったら:has()を使うのありです。

jsいらずのPopover API

もはやCSSだけの話でなくなってきています。純粋なHTMLです。純粋なbuttonタグだけでポップオーバーが作れます。FireFoxだけはまだ対応していないですがもうすぐ対応しそうです。

See the Pen Popover on CodePen.

抜粋
<button class="open-button" popovertarget="my-popover" popovertargetaction="show"> 開く </button>
<div id="my-popover" popover>
    <button popovertarget="my-popover" popovertargetaction="hide" class="close-button">
        <svg>
             ...
        </svg>
    </button>
</div>

buttonタグのpopovertarget属性に、ポップとなる要素のidを指定してあげます。またポップとなる要素にpopoverという属性を追加してあげます。これだけでおしまいです。これなんと、jsを一行も書かずに実装しています。CSS側も、z-indexなど使用していないです。HTMLの進化もえげつないですね。
ページの上にちょこっと出す、広告などでよく使われる手段です。似たようなことをdialogタグでも実は実装できますが、こちらはjsでの操作が必要になってきます。またPopover APIで実装する場合はちゃんとaria-roleなどを付与してあげた方がいいです。
dialogはユーザーの操作をそれ以外制御する、Popover APIは制御しないとの違いなので、ユーザー削除などで何かの確認のときにはdialog、その他はPopover APIで実装と使い分けてあげるのが良さそうです。

カードレイアウトが簡潔に、subgrid

ついにsubgridが使えるようになりました。gridの中にgridを書けるようになりました。
subgridは何が違うかというと、ちゃんと親のgridと連動しているところです。

See the Pen SubGrid on CodePen.

<div class="grid">
  <article class="card">
     ...
  </article>
  <article class="card">
     ...
  </article>
  <article class="card">
     ...
  </article>
</div>
抜粋
.grid {
  display:grid;
  grid-template-columns:1fr 1fr 1fr;
}
.card {
  display:grid;
  grid-row: span 4;
  grid-template-rows: subgrid;
  gap: 0.2rem;
  /* 省略 */
}

gridの子となるクラスにgrid-template-rows:subgrid;を設定してあげるとその中もまたgridになります。
今までだと個別でカード内にまた新たにgridを設定する必要がありました。そうすると各カード内の高さがまばらだったので、カード間で高さを揃えるのが難しかったです。それが、subgridを使うと綺麗に整うようになりました。

フォームバリデーションのための、:user-valid,:user-invalid

これはWeb制作者向けです。ReactやVueなどのライブラリを使わない人向けです。またはそれらを使っていても、フォームはHTMLそのままで使う人向けです。

See the Pen :user-valid&:user-invalid on CodePen.

こちらの例ではメールアドレスを入力するフォームです。<input type="email"/>で、入力はメールアドレス形式を受け付けています。
:user-validは入力が正しいとき、:user-invalidは入力が正しくないときの擬似クラスです。これらを使えば、バリデーションの状態に対してスタイルを当てられます。
バリデーションエラーを起こすのはJavaScriptでも操作できます。ただし、エラーメッセージはHTML標準で出力されるツールチップが伴うので、それが邪魔に思う人はそもそもHTML標準のバリデーションを利用しない方が良さそうです。

CSSはプログラミング言語だ!数学関数

こちらはあまり自分では使用していないため、紹介に留めておきます。三角関数から指数関数、対数関数まで使えます。アニメーションで使う際にめちゃくちゃ有用そうですね。もはやCSSはプログラミング言語と呼べるのではってレベルですね。

終わりに

いかがでしょうか?何も他のライブラリは使ってません。通常のCSSのみしか使っていません。2023年はかなりの機能が増えました。アニメーション関連に関しては省きましたが、アニメーション関連の進化もめちゃくちゃすごいです。
アニメーション関連に関してはこちらの記事がとても詳しいのでご覧になってください。

JavaScriptで行ってきたことが大分JSレスで、CSSオンリーでできるようになりました。わずらわしい詳細度の問題もかなり解決できました。あとは@scopeが全ブラウザ対応になればもう完璧ではないでしょうか?

ところで、人によっては「いやいや、最新ブラウザばかりの対応は難しいんだよ」という方もいます。あと、「もう疲れちゃって 全然覚えられなくてェ…」みたいな方もいると思います。
しかし、無理に覚える全部覚える必要もないですし、使えない状況下であれば別に使う必要もないです。こういう機能があるってことを知っておくことが大事です。知らないで使わないのと、知っていてあえて使わないのでは、使える手数が大きく変わってきます。
「どれが優先度高いかわからなくなっちゃった。そういえばなんかカスケードレイヤーみたいな機能があったなぁ」ってときにこの記事振り返ったり、ググったりすることがとても大事です。「何かそういうのあったな」って微かに覚えてて、調べて使う、そういう積み重ねがとても大事です。
あとは進化がすごいので、「こういったことCSSで実現できないかな」っていうのを機能ごとにうまく因数分解して調べることも有効です。もしかしたらそのときにできているかもしれません。

ぜひ皆さんも最新のCSSの動向を追ってみてください。

16
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?