position: sticky ;の5つの便利な使い方と動かないときの確認事項

position: sticky ;はヘッダーやコンテンツなど指定した要素がスクロールした際に指定した位置に固定されるプロパティです。

今回はposition: sticky ;の4つの便利な使い方と動かないときの注意点を記していきます。

また、CSSだけで全画面背景を切り替えるパララックススクロールについて記事にしているのでこちらもあわせてご覧ください。

デモ

まずはデモをご確認ください。

DEMO1

DEMO2

position: sticky ;の便利な使い方

position: sticky ;の基本

固定したい要素にposition: sticky ;とtop: 30px ;を指定してスクロールすると上端から30px下に固定されます。

.some-component {
	top: 30px ;
	position: sticky;
}

下記はスクロールした際にコンテンツ領域分タイトルを固定して、次のタイトルが来た際にまたタイトルが新たに固定される…というposition: sticky ;のベーシックなデモです。

html

<div class="sticky-1">
	<div class="title">タイトルA</div>
	<div class="contents">コンテンツ領域</div>
	<div class="title">タイトルB</div>
	<div class="contents">コンテンツ領域</div>
	<div class="title">タイトルC</div>
	<div class="contents">コンテンツ領域</div>
</div>

css

.sticky-1 .title {
	top: 0 ;
	position: sticky;
	color: #fff ;
	background: #999 ;
	padding: 1rem ;
}
.sticky-1 .contents {
	background: #f1f1f1 ;
	padding: 1rem ;
	min-height: 50vh ;
	margin-bottom: 1rem ;
}

DEMO1-1

tableタグのタイトルを固定

position: sticky ;はtableタグでも使用できます。
下記はtableのタイトルを固定した使い方です。

管理画面のtableは長くなりがちでタイトルを固定してほしい場面が多々あるので活用するとユーザビリティが上がります。

また下記ではtrにclassで指定しておりますが、thなどでも可能です。

html

<div class="sticky-2">
	<table>
		<tr class="title">
			<th>タイトルA</th>
			<th>タイトルA</th>
			<th>タイトルA</th>
		</tr>
		<tr>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
		</tr>
		<tr>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
		</tr>
		<tr>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
		</tr>
		<tr class="title">
			<th>タイトルB</th>
			<th>タイトルB</th>
			<th>タイトルB</th>
		</tr>
		<tr>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
		</tr>
		<tr>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
		</tr>
		<tr>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
		</tr>
		<tr class="title">
			<th>タイトルC</th>
			<th>タイトルC</th>
			<th>タイトルC</th>
		</tr>
		<tr>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
		</tr>
		<tr>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
		</tr>
		<tr>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
			<td>テキストが入ります</td>
		</tr>
	</table>
</div>

css

.sticky-2 table {
	width: 100% ;
}
.sticky-2 tr.title {
	color: #fff ;
	background: #555 ;
	top: 0 ;
	position: sticky;
}
.sticky-2 th, .sticky-2 td {
	padding: 0.5rem ;
}

DEMO1-2

サイドバーを固定

ブログなどでもよく見かけるサイドバーがメイン領域分固定されるデモです。

下記のデモはサイドバー全体を固定しておりますが、サイドバーのバナーや人気コンテンツのみを固定することも可能です。

html

<div class="sticky-3">
	<div class="main">
		<div class="contents">メイン領域</div>
	</div>
	<div class="side">
		<div class="side__contents">サイド領域</div>
	</div>
</div>

css

.sticky-3 {
	display: flex ;
}
.sticky-3 .main {
	width: 70% ;
	min-height: 100vh ;
	background: #f1f1f1 ;
	padding: 1rem ;
	box-sizing: border-box ;
}
.sticky-3 .side {
	width: 30% ;
	padding-left: 1rem ;
	box-sizing: border-box ;
}
.sticky-3 .side .side__contents {
	top: 30px ;
	position: sticky;
}

DEMO13

画像を固定

下からスクロールしてきた画像が上部に達すると固定され…を繰り返すデモです。

html

<div class="sticky-4">
	<div class="img"><img src="assets/img/img-1.jpg"></div>
	<div class="img"><img src="assets/img/img-2.jpg"></div>
	<div class="img"><img src="assets/img/img-3.jpg"></div>
	<div class="img"><img src="assets/img/img-4.jpg"></div>
	<div class="img"><img src="assets/img/img-5.jpg"></div>
</div>

css

.sticky-4 .img {
	top: 0 ;
	position: sticky;
}
.sticky-4 .img img {
	width: 100% ;
}

DEMO14

応用

スクロールで全画面背景画像とコンテンツをstickyで固定する記述例です。

html

<div class="img a"></div>
<div class="contents a">コンテンツ領域</div>
<div class="img b"></div>
<div class="contents b">コンテンツ領域</div>
<div class="img c"></div>
<div class="contents c">コンテンツ領域</div>

css

.img, .contents {
	width: 100% ;
	height: 100vh ;
	top: 0 ;
	position: sticky ;
}
.img {
	background: url("assets/img/img-1.jpg") no-repeat center center / cover;
	top: 0 ;
}
.img.b {
	background-image: url("assets/img/img-2.jpg");
}
.img.c {
	background-image: url("assets/img/img-3.jpg");
}
.contents {
	color: #fff ;
	background: #01579B ;
	display: flex ;
	justify-content: center ;
	align-items: center ;
}
.contents.b {
	background: #FF9100 ;
}
.contents.c {
	background: #AD1457 ;
}

DEMO2

position: sticky ;が動かないときの確認事項

親(先祖)要素にoverflow: hidden ;を使用していないか?

もっともありがちではまりやすいポイントです。

position: sticky ;を指定した要素の親(先祖)要素にoverflow: hidden ;があると機能しません。
私も何度かこちらではまっております。

もっと詳しくいうと、親(先祖)要素にoverflow, overflow-x, overflow-yのvisible以外(overlow: hidden ;やoverflow: scroll ;)が指定されているとききません。

親要素の領域が確保されていない

親要素の領域が存在していない場合stickyはききません。
上に記述した「サイドバーを固定する」はflexでメイン領域とサイド領域の高さを揃えて領域を確保した上で、サイドの中に記述した.side__contentsをstickyにしております。

単一の要素にしていないか?

<div class="sticky-1">
	<div class="title">
		タイトルA
	</div>
</div>

上記のようにコンテンツ領域がなく単一の要素にしてしまうとstickyはききません。

ブラウザの対応状況

ブラウザの対応状況は2021年11月8日時点で、Global 96.38%, Japan 95.61%となっております。
仮にブラウザ非対応だったとしても固定されないだけなので特に問題ないかと思います。

Can I use

FOLLOW US SNSで最新情報をチェック!

KEYWORD 話題のキーワード!

NEXT POST スクロールでの全画面背景の切り替えパララックスをcssだけで実現!
PAGE TOP