CSSのpositionプロパティで要素がズレる理由|現場で使える実践テクニック
こんにちは!
今日は「positionプロパティを使った時に、要素がズレてしまう理由と対処法」について解説します。
このテーマを選んだのは、ほんま現場でめっちゃ見かけるトラブルやからです。
「意図した位置に要素が配置されない…」という経験、初心者さんなら誰でもあると思います。
この記事の内容
positionのズレはstacking contextが原因かもしれない
僕も昔、めっちゃハマった失敗があります。position: fixedで配置した要素が、期待と違う位置に表示されるという現象です。
原因は「stacking context(積み重ねの文脈)」という概念を理解していなかったからです。
多くの人がposition: fixedは「画面に固定される」と思っていますよね。
でも実は、親要素が特定の条件を満たしていると、その親要素に対して相対的に配置されてしまうんです。
具体的には、親要素に以下のプロパティが設定されていると、新しいstacking contextが生成されます。
position: relative、absolute、fixed、stickyopacityが1未満transformがnone以外filterがnone以外will-changeで上記プロパティが指定されている
特に困るのがtransformです。
親要素にアニメーション用のtransformがついていて、その子要素でposition: fixedを使うと…もう大変やん。
固定されずに親要素の移動に巻き込まれちゃいます。
対処法としては、position: fixedの要素を親要素の外に出す、またはportalパターンでDOMの別の場所に配置することをお勧めします。
親要素のposition設定を見落としていないか
次の失敗パターンは「親要素のポジショニングの確認漏れ」です。
例えば、こんなコードを見かけます。
.child {
position: absolute;
top: 10px;
left: 10px;
}
一見問題なさそうですが、このコードの危険性は「相対値がどこになるのか不明確」だという点です。
最初のpositioned ancestorまで遡って、そこを基準に配置されるので、想定と違う場所に配置されることがめっちゃあります。
対処法は「親要素にposition: relativeを必ず明記する」です。
.parent {
position: relative;
/* 他のスタイル */
}
.child {
position: absolute;
top: 10px;
left: 10px;
}
親を明確に指定することで、意図した場所に確実に配置できます。
これは「暗黙の依存を避ける」という原則でもあって、チームメンバーが後で保守する時も助かりますよ。
transformとpositionの相互作用を知ろう
最後の重要なポイントが「transformとpositionの相互作用」です。
transform: translate()とposition: absoluteのtop、leftは、どちらも要素を移動させるプロパティです。
でも動作は全然違います。
position: absolute; top: 10px→ レイアウトフロー外での絶対配置。topの値が変わるとレンダリングコストがかかるtransform: translateY(10px)→ すでに配置された要素を変換する。GPU加速の対象になり、パフォーマンスが良い
現場ではアニメーションを作るとき、この違いを意識しないと「スマートフォンでガクガクする…」という問題になります。
例えば、ホバー時に要素を動かす場合。
/* 避けた方が良い例 */
.box:hover {
position: absolute;
top: 20px;
}
/* 推奨される例 */
.box {
transition: transform 0.3s ease;
}
.box:hover {
transform: translateY(20px);
}
transformを使う方が、ブラウザのレンダリングエンジンも「これは変換だな」と判断して最適化してくれます。
つまり、「位置を固定的に決める」ときはposition、「すでに配置された要素を動かす」ときはtransformという棲み分けが大事なんです。
まとめ
positionプロパティがズレてしまう主な原因をまとめます。
- stacking contextが生成されていないか確認する。特に
transformやopacityに注意 - 親要素に
position: relativeを明記して、相対値の基準を明確にする - アニメーションや移動にはできるだけ
transformを使う方がパフォーマンスが良い
これらのポイントを押さえておくと、ほんまにレイアウトトラブルが減ります。
最初は「なぜこんな複雑なの?」と感じるかもしれませんが、一度仕組みを理解するとスッキリしますよ。
Web制作で困ったことがあったら、またこのブログを覗いてくださいね!
― クリオ