≪ Today I learned. RSS購読
公開日
タグ
CSS
著者
ダーシノ(@bc_rikko)

position: fixedの基準を親要素にあわせる

position: fixed;を指定すると、ドキュメントフローから除外され、Initial Containing Block(最初の包含ブロック ≒ viewport ≒ ブラウザの表示領域)を基準に配置される。

TL;DR

(通常は)親要素を基準にposition: fixed;ができない

「overflowが発生するある要素に対し固定位置に配置したい」ということが、通常はできない。

以下の場合、.fixed要素を.container要素を基準に配置したくても、viewportの左上の表示されてしまう。

<div class="container">
  <div class="fixed">Fixed</div>]
  ...
</div>
.container {
  position: relative;
  overflow: auto;
}

.fixed {
  position: fixed;
  top: 0;
  left: 0;
}

CSS Container Queries や CSS Anchor Positioning があるのでできそうな気もするが、実装するにはCSSハックが必要になる。

transformを使ったCSSハック(古い)

transformプロパティにnone以外の値が設定されると、Stacking Context(重ね合わせコンテキスト)が生成される。そのため、Containing Block(包含ブロック)として扱われるようになる。

<div class="containing-block">
  <div class="content">
    <!-- Fixed要素は.containing-block要素を基準にレイアウトされる -->
    <div class="fixed">Fixed</div>
    ...
  </div>
</div>
.containing-block {
  transform: translate(0);
}

.container {
  overflow: auto;
}

.fixed {
  /* #containing-blockを基準に配置 */
  position: fixed;
  top: 0;
  left: 0;
}

transformを使ったCSSハックのデモ

Fixed

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

containプロパティを使った制御

先述のtransformプロパティを使った制御は、「CSSハック」というだけあって意図が読み取りづらい。

containプロパティlayoutを使うことで、要素外のレイアウトに影響を与えることなくposition: fixed;を使うことができる。

<div class="layout">
  <div class="content">
    <!-- Fixed要素はdiv.layout要素を基準にレイアウトされる -->
    <div class="fixed">Fixed</div>
    ...
  </div>
</div>
.layout {
  contain: layout;
}

.container {
  overflow: auto;
}

.fixed {
  /* contain: layoutを指定した要素を基準に配置 */
  position: fixed;
  top: 0;
  left: 0;
}

containプロパティを使ったデモ

Fixed

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.