🙄

【CSS】positionでleftとrightを同時指定したらどうなる?

2023/11/13に公開

先日CSSのpositionに関するクイズを出しました。

位置指定プロパティのleftrightを同時に指定するとどうなるでしょう?同時指定自体はCSSとして正しい記述になります。

答え

結論から言うと以下のようになります。

子要素の位置は左側から30px

https://codepen.io/Nishihara/pen/PoVpjeq

結果としてはleftのみを指定した時と同じような見た目になりますが、この表示になるにはいくつかの経緯があります。そして、ちょっとした条件の変化で上記のいずれかになりうる可能性があります。

挙動の詳細

まず、両方の指定があった場合、子要素はその条件[1]に合致するよう伸びようとします。ちょうど以下の画像のようになろうとします。

子要素は左右30pxの位置まで幅が伸びる

しかし、子要素に幅が指定されている場合は伸びれません。その時はleftrightのうち、書字方向のものが優先されます。通常の日本語の環境であれば書字方向は左から右(lrt)なのでleftが優先されるので左寄せになります。今回のクイズは幅が指定されているので左寄せが正解になります。

子要素の位置は左側から30px

しかし、HTMLのdir属性やCSSのdirectionプロパティで書字方向を右から左(rtl)に変更していた場合はrightが優先され、右寄せになります。右から左へ書くアラビア語だけでなく、縦書き日本語(writing-mode: vertical-rl)でも起こり得るので注意が必要です。

子要素の位置は右側から30px

上下方向でも起こる?

leftrightの同時指定で上記のような挙動が起こりますが、topbottomの同時指定はどうでしょうか?結論から言うと同様に起こり得ます。heightが未指定の場合は上下に伸びます。ただし、上下の書字方向の変化は現状Firefoxのみが対応しているwriting-mode: sideways-lr以外で変更する方法がない(はず)ので、下寄せになる場面はそうそうないです。基本はheight指定がある場合はtopが優先されると考えてよいです。

特別な事情がない限りは両方指定は避けたほうがいいかも

このように両方指定するとレイアウトの挙動が直感的でなくなります。子要素を伸ばしたいという意図ならこのような指定をするかもしれませんが、現代のCSSではflexgridを使えば同様の実装ができ、コードの意図としても明確になります。あえてこちらのテクニックを利用する意味はあまりないでしょう。

余談 子要素のマージンとの兼ね合い

余談にはなりますが、left優先で左寄せ担っている時に子要素にmargin-left:autoをつけると左側いっぱいに余白を取ろうとするとのでrightの位置になります。CSS難しい。

参考文献

https://developer.mozilla.org/ja/docs/Web/CSS/right#declaring_both_left_and_right
https://developer.mozilla.org/ja/docs/Web/CSS/writing-mode

脚注
  1. 今回の例で言えば、左から30pxと右から30pxの位置まで。 ↩︎

Discussion