#はじめに
JSを使用して要素の中央揃えを作成した時、なぜかCSSのフレックスボックスと中心がずれる場合があるので調べてみました
検証用コード
要素を3つ用意し
1.CSSのフレックスボックスを使用して中央揃えしたもの
2.JSの window.outerWidth を使用し計算を行い中央揃えしたもの
3.JSの window.innerWidth を使用し計算を行い中央揃えしたもの
を作成しどういった場合に中央揃えがずれるのかを検証してみます
<style>
.frame{
/* height: 10000px; */
}
.flex{
display: flex;
justify-content: center;
align-items: center;
}
.box{
width: 100px;
height: 100px;
color: white;
}
#box1{
background-color: rgb(255, 116, 116);
}
#box2{
background-color: rgb(126, 160, 253);
position: absolute;
top: 100px;
}
#box3{
background-color: rgb(123, 255, 128);
position: absolute;
top: 200px;
}
</style>
<div class="frame">
<div class="flex">
<div id="box1" class="box">
フレックスボックスによる中央寄せ
</div>
</div>
<div class = "inner_frame">
<div id="box2" class="box">
outerWidthによる中央寄せ
</div>
</div>
<div class = "inner_frame">
<div id="box3" class="box">
inner_widthによる中央寄せ
</div>
</div>
</div>
<script>
const outer_width = window.outerWidth
const box2 = document.getElementById('box2')
box2.style.left = `${(outer_width - box2.clientWidth) / 2}px`;
const inner_width = window.innerWidth
const box3 = document.getElementById('box3')
box3.style.left = `${(inner_width - box3.clientWidth) / 2}px`;
</script>
実際の動作
下記は赤い要素がフレックスボックス、青と緑がそれぞれJSで画面幅と要素幅から、leftの値を計算して中央に移動させています。
現時点では特に問題なくすべて中央にそろっています
ではここで親要素の縦幅を伸ばしてスクロールバーが表示されるように修正すると
CSSのフレックスボックスで中央揃えした要素が左にずれてしまいました
さらにウィンドウ幅を調整すると
window.outerWidth を使用し計算を行い中央揃えしたものが左にずれてしまいました
#原因
それぞれの計算元となる画面幅の違いが原因でした
①1枚目の画像では、全ての要素が左端から右端の画面幅をもとに中央位置の計算をしているためすべて同じ中央の位置に配置されます
②スクロールバーが表示されたことにより
赤要素は左端からスクロールバーの左側まで
window.outerWidthとwindow.innerWidthを使用している青と緑要素は左端からスクロールバー右端までを画面幅とすることにより中央揃えの計算に差が発生しています
となることでズレが発生しています
③window.outerWidth(青要素)は左端からウィンドウの一番右端、window.innerWidthは左端からスクロースバーの左側までを取得しているため画面サイズを知事メルことによってこれまたズレが発生しています
解決方法
赤要素のフレックスボックスはあくまで親要素の幅を参照しているため、JSで計算を行う場合も対象の親要素の幅を取得し計算することによってずれがなくなります