0
2

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.

【技術書まとめ】作って学ぶ HTML&CSSモダンコーディング

Last updated at Posted at 2023-05-15

現在のCSSを整理するために本書を手に取った。11冊目。
CSSの全体整理のための本。とりあえずこの本でCSS実装系はいったん終わり。

まとめ

レイアウトのバリエーション

  • 両端配置
    • Flexbox justify-content: space-between, margin-right: auto
    • Grid grid-auto-flow: column; grid-template-columns: 1fr auto
  • 縦横中央配置
    • Grid justify-items: center; align-content: center
      • アイテムが1つだけなら place-items: center
    • Flexbox flex-direction: column; justify-content: center; align-items: center
  • タイル状配置
    • Grid
      • 列の数が固定
        • grid-template-columns: repeat(3, 1fr); gap: 32px 25px;
          • アイテム配置を指定する posts-container > :nth-child(5)
      • 列の数が変わる
        • grid-template-columns: repeat(auto-fit, minmax(200px, 1fr))
    • Flexbox flex-wrap: wrap, .container > * { width: 33.333% }
      • gapで余白調整 gap: 32px 25px, width: calc(33.33% - (25px * 2 / 3))
      • justify-contentで余白調整 row-gap: 32px, width: 32%
      • paddingで余白調整 width: 33.33%, padding: 0 12.5px 32px, box-sizing: border-box, .container { margin: 0 -12.5px -32px }
  • 自在に配置を変更
    • Grid
      • テンプレート grid-template-columns: auto auto, grid-column: 1 / 4
      • エリア grid-template-areas: "site" ". sns", grid-area: site
    • Flexbox position: absolute; top: 0; right: 0; height: 100%;
  • 中身に合わせたサイズで横並び配置
    • Flexbox display: flex; flex-wrap: wrap; gap: 20px;
    • Grid display: grid; grid-template-columns: repeat(auto-fit, minmax(6em, auto)); gap: 20px
  • カード型UI配置
    • Grid grid-template-columns: repeat(auto-fit, minmax(0, 1fr))
    • Flexbox flex-direction: column, .container > * { flex: 1; }
  • カードの中身を上下揃えて配置
    • Flexbox flex-direction: column, margin-top: auto
    • Grid grid-template-rows: auto 1fr auto auto
  • 画像とテキストを横並びに配置
    • Flexbox flex-direction: column, .text { flex: 1 }; .img { flex: 2 };
    • Grid grid-template-columns: 1fr 2fr
  • 画像にテキストを重ねる
    • 背景画像 .hero { height: 650px; background-image: url(img/hero.jpg); background-position: center; background-size: cover }
    • Grid grid-template-rows: 650px, .hero > * { grid-area: 1 / 1 }, .hero > img { width: 100%; height: 100%; object-fit: cover }
  • オーバーレイで表示する
    • position: fixed; inset: 0; z-index: 100;
  • ヘッダーを上部に固定する
    • position: sticky; top: 0; z-index: 10;
  • 記事本文の余白
    • margin: 1.8em 0
    • Grid display: grid; gap: 1.8em, figure { margin: 20px 0; }
  • 横幅と左右の余白
    • width width: min(92%, 1166px); margin: auto; or width: 92%; max-width: 1166px; margin: auto;
    • padding max-width: 1166px; margin: auto; padding-left: 4%; padding-right: 4%;
    • Grid grid-template-columns: 1fr min(92%, 1166px) 1fr, .grid > * { grid-column: 2; }

各種設定

  • 画面幅に合わせてフォントサイズを変える
    • font-size: clamp(48px, 5vw, 68px)
  • レスポンシブイメージ
    • srcset/sizes
  • 画像によるレイアウトシフトを防ぐ
    • <img>width/height

ヘッダー

両端に配置するレイアウト

  • ヘッダーのようなシンプルな横並びコンテンツはFlexboxで両端に配置する
    • 3つ以上の要素の場合
      • flexboxでロゴにmargin-right: autoを指定して枠を広げる
      • CSS Gridでロゴにgrid-template-columns: 1frを割り当てる

Flexboxとgapでのシンプルな横並び

.footer-sns {
    display: flex;
    gap: 24px;
}

横幅と左右の余白を調整する方法

min関数margin: autoで横幅と左右の余白を指定する

/* このクラス名を使って他のパーツでも同じ余白を指定する */
.w-container {
    width: min(92%, 1166px);
    margin: auto;
}
  • Gridで余白を調整すると
/* 2列目の横幅を指定して調整する */
.grid {
  display: grid;
  grid-template-columns: 1fr min(92%, 1166px) 1fr;
}
.grid > * {
  grid-column: 2;
}

/* 左右の列で調整する */
.grid {
  display: grid;
  grid-template-columns:
    minmax(4%, 1fr)
    minmax(auto, 1166px)
    minmax(4%, 1fr);
}
.grid > * {
  grid-column: 2
}

imgの下に余計な余白が入るのを防ぐ(imgのスタイルをリセットする)

  • imgタグは標準ではインラインブロックボックスになっているため
img {
    display: block;
     /* オリジナルサイズ以上に拡大されるのを防ぎながら、親要素の横幅に合わせる */
    max-width: 100%;
    /* 横幅に対してオリジナルの縦横比を維持した高さにする */
    height: auto;
}

ヘッダーを画面上部に固定するレイアウト

position: stickyでヘッダーを固定する

.header {
  position: sticky;
  top: 0;
  z-index: 10;
}

ヒーロー

縦横中央に配置するレイアウト

  • FlexboxとCSS Gridどちらでも対応できる
    • 今後複雑なデザインになっても対応しやすいのはCSS Grid

画面幅に合わせてfont-sizeを48pxから68pxに変化させる

.hero h1 {
  font-size: clamp(48px, 5vw, 68px); /* 画面幅960pxで48px、1360pxで68px */
  min-height: 0vw; /* Safariで機能させるため */
}

シンプルなボタンのサンプル

a {
  color: inherit;
  text-decoration: none;
}

a:hover {
  filter: brightness(90%) contrast(120%);
}

a.btn {
  display: block;
  width: 260px;
  padding: 10px;
  box-sizing: border-box;
  border-radius: 4px;
  background-color: #e8b368;
  color: #fff;
  font-size: 18px;
  text-align: center;
  text-shadow: 0 0 6px #00000052;
}

縦横中央に配置するレイアウト

CSS Gridで設定する

.hero-container {
  display: grid;
  justify-items: center;
  align-content: center;
  height: 100%;
}

/* 縦横中央に配置するアイテムが1つだけの場合 */
.hero-container {
  display: grid;
  place-items: center; /* justify-items, align-itemsの値をまとめて指定する */
  height: 100%;
}

Flexboxで設定する

.hero-container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100%;
}

画像にテキストを重ねるレイアウト

背景画像で表示する

.hero {
  height: 650px;
  background-image: url(img/hero.jpg);
  background-position: center;
  background-size: cover;
}

<img>で表示する

.hero {
  display: grid;
  grid-template-rows: 650px;
}

.hero > * {
  /* 「grid-row1; grid-column: 1;」をまとめて指定する */
  grid-area: 1 / 1;
}

.hero > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

画像とテキスト

横並びにするレイアウト

  • 配置を逆転させるときはFlexboxの方がわかりやすくなる

Flexboxのrow-reverseを使用する

/* 連続して並べた場合に上要素のpaddingで間隔を調整する */
.imgtext + .imgtext {
  padding-top: 0;
}

.imgtext-container {
  display: flex;
  flex-direction: column;
}

@media (min-width: 768px) {
  .imgtext-container {
    flex-direction: row;
    align-items: center;
    gap: clamp(45px, 6vw, 80px); /* 余白を可変にする */
  }

  /* imagetext-containerに、reverseが指定されたときだけ配置を逆にする */
  .imgtext-container.reverse {
    flex-direction: row-reverse;
  }

  .imgtext-container > .text {
    flex: 1;
    min-width: 17em; /* テキスト折り返しで崩れるので最小幅を指定する */
  }
  .imgtext-container > .img {
    flex: 2;
  }
}

CSS Gridを使用する

.imgtext-container {
  display: grid;
  gap: clamp(45px, 6vw, 80px);
}

.imgtext-container.reverse > .text {
  order: 2;
}

.imgtext-container.reverse > .img {
  order: 1;
}

@media (min-width: 768px) {
  .imgtext-container {
    grid-template-columns: 1fr 2fr;
    align-items: center;
  }

  .imgtext-container.reverse {
    grid-template-columns: 2fr 1fr;
  }
}

可変サイズフォントの下線の余白をemで指定して対応する

.heading-decoration {
  font-size: clamp(30px, 3vw, 40px);
  min-height: 0vw; /* Safari用 */
}

.heading-decoration::after {
  display: block;
  content: "";
  width: 160px;
  height: 9px;
  border-top: solid 1px #b72661;
  margin-top: 0.6em;
}

見出しフォントをパーツ外側に配置する

.heading {
  position: absolute;
  /* パーツの上の余白から外側に出すサイズ(0.6em)をマイナス指定する */
  top: calc((var(--v-space) + 0.6em) * -1);
}

Chrome, Safariで:hoverを反映させるため、<a>にdisplay: blockを指定する

.post a {
  display: block;
}

article画像を3:2の縦横比に揃える

.post img {
    aspect-ratio: 3 / 2;
    object-fit: cover;
    width: 100%; /* aspect-ratioの設定を反映させるために必要 */
}

タイル状に並べるレイアウト

CSS Gridでタイル状にする

.posts-container {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 32px 25px;
}

@media (min-width: 768px) {
  .posts-container {
    grid-template-columns: repeat(3, 1fr);
  }
}

特定のアイテムの配置をグリッドで指定する(5つめだけ大きく配置する)

.posts-container > :nth-child(5) {
    grid-column: 1 / span 2;
    grid-row: 1 / span 2;
}

.posts-container > :nth-child(5) img {
  aspect-ratio: 3 / 2.5;
}

@mediaを使用せず、コンテナの横幅に合わせてタイル状に並べるレイアウト

CSS Gridで並べる

  • 「特定のブレークポイントで2列と3列を切り替える」ような制御は難しくなる
.posts-container {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 32px 25px;
}

Flexboxで並べる

.posts-container {
    display: flex;
    flex-wrap: wrap;
    gap: 32px 25px;
}

.posts-container > * {
    flex-grow: 1;
    width: 200px;
}

Flexboxで設定する

  • gapで調整する
    • gapを入れた分だけ横幅を短くする
  • justify-contentで調整する(アイテム数を5件などに変えると崩れる)
  • アイテムの横幅値余白を含めて調整する
    • paddingを入れて、border-boxを指定する
gapで調整する
.posts-container {
  display: flex;
  flex-wrap: wrap;
  gap: 32px 25px;
}

.posts-container > * {
  /* 横幅50%から、25pxのギャップを1つ分を2分割したサイズを引く */
  width: calc(50% - (25px * 1 / 2)); 
}

@media (min-width: 768px) {
  .posts-container > * {
    width: calc(33.33% - (25px * 2 / 3));
  }
}

フッター

Gridでアイコンを正方形の中に表示する

.footer-sns a {
    display: grid;
    place-items: center; /* 縦横中央に配置する(要素が1つだけの場合) */
    width: 36px;
    aspect-ratio: 1 / 1;
    background-color: #cccccc;
    color: #ffffff;
    clip-path: circle(50%);
}

記事

本文の構成要素の感覚をブラウザ標準の設定に戻す(特定クラスの特定要素を:whereで指定する)

.entry-container :where(h1, h2, h3, h4, h5, h6, p, figure, ul) {
  margin-top: revert;
  margin-bottom: revert;
  padding: revert;
  list-style: revert;
}

記事本文のレイアウト

marginの重ね合わせと、:first-child, :last-childで指定する

.entry-container p {
  margin: 1.8em 0;
}

.entry-container > :first-child {
  margin-top: 0;
}

.entry-container > :last-child {
  margin-bottom: 0;
}

CSS Grid/Flexboxで設定する

/* Grid */
.entry-container {
    display: grid;
    gap: 1.8em;
}

/* Flexbox */
.entry-container {
    display: flex;
    flex-direction: column;
    gap: 1.8em;
}

複数の適用先をまとめて指定する

  • 詳細度の違い
    • :is()
    • :where()

プラン

ボタンをwidth: autoにして左右いっぱいに広げる

.plan .btn {
    width: auto;
}

カード内のCTAボタンを下に揃えて表示を統一する

Flexboxで設定する

.plan .price {
  margin-top: auto; /* 余剰スペースが割り当てられる */
  ...
}

CSS Gridで設定する

.plan {
  display: grid;
  grid-template-rows: auto 1fr auto auto; /* 2列目に余剰スペースを割り当てる */
}

カード型UIのレイアウト

CSS Gridで設定する

.plans-container {
  display: grid;
  gap: 27px;
}

@media (min-width: 768px) {
  .plans-container {
    /* 並べるカードの数を固定する */
    grid-template-columns: repeat(3, 1fr);

    /* カードの数を変えても対応できるようにする */
    grid-template-columns: repeat(auto-fit, minmax(0, 1fr));

    /* 複数行でレイアウトする場合 */
    grid-template-columns: repeat(2, 1fr);
  }
}

Flexboxで設定する

.plans-container {
    display: flex;
    flex-direction: column;
    gap: 27px;
}

@media (min-width: 768px){
    .plans-container {
        flex-direction: row;
    }
    
    .plans-container > * {
        flex: 1;

        /* 複数行でレイアウトする場合 */
        width: calc(50% - (27px * 1 / 2));
        box-sizing: border-box;
    }
}

ナビゲーション

position: fixedでオーバーレイ表示する

@media (max-width: 767px) {
  .nav {
    position: fixed;
    inset: 0; /* 上下左右から内側に0の距離に揃える */
    z-index: 100;
    background-color: #4e483ae6;
  }

  .nav ul {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 100%;
    gap: 40px;
    color: #ffffff;
  }
}

ボタンクリックでメニューを表示する

position: fixed, inset: 0で設定する

<button
  class="navbtn"
  onclick="document.querySelector('html').classList.toggle('open')"
>
  <i class="fas fa-bars"></i>
  <span class="sr-only">MENU</span>
</button>
@media (max-width: 767px) {
  .nav {
    position: fixed;
    inset: 0 -100% 0 100%; /* 右画面外に配置する */
    z-index: 100;
    background-color: #4e483ae6;

    /* top, left, width, heightで設定する場合 */
    top: 0;
    left: 100%;
    width: 100%;
    height: 100%;
    z-index: 100

    transition: transform 0.3s;
  }

  .open .nav {
    transform: translate(-100%, 0); /* navの横幅分だけ左移動させる */
  }

  /* 不要なスクロール発生を防ぐ */
  .open body {
    position: fixed;
    overflow: hidden;
  }

  .nav ul {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 100%;
    gap: 40px;
    color: #ffffff;
  }
}
0
2
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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?