position:fixedのコンテンツの横幅を指定する方法 結城永人 - 2023年2月20日 (月) テンプレートのImaginary themeにポップアップの表示を付けようとしてCSSのposition:fixedを使おうとしたら横幅が画面から突き抜けてしまって困った。 調べるとposition:fixedのコンテンツの位置指定の基準が普通とは異なることに起因している。 固定位置指定は絶対位置指定に似ていますが、要素の包含ブロックがビューポートによって定義される初期包含ブロックであるという点が異なり、祖先の一つに transform, perspective, filter の何れかのプロパティが none 以外 (CSS Transforms Spec を参照) に設定されている場合は例外で、その場合は祖先が包含ブロックとしてふるまいます。 position|MDN|Mozilla 通常、position:fixedのコンテンツは固定位置指定として親要素ではなくてビューポートと呼ばれる大外の画面の領域を基準として配置される。 だから位置取りをずらして表示しようとすると幅が広いほどに反対側へ突き抜けてしまう場合も出て来るし、位置取り自体も合せ辛くなってしまうことがある。 以前、位置取りに関してはボタンなどのposition:fixedのHTML要素をサイトの幅に合わせて表示する方法で、分かった。 今回、コンテンツを画面内に収めるにはどうするかで、横幅を指定する二つの方法が見付かったので、纏めておきたい。 position:fixedと一緒に使うとビューポートを基準にサイト全体の横幅を捉えてコンテンツをはみ出さずに配置することができる。 widthで横幅を指定するleftとrightで横幅を指定する 今回のマークアップは些細な日常の記事/追加ページの本文の左下に固定表示された概要ボタンから出て来る記事/追加ベージの基本情報のポップアップに使っているから押すとposition:fixedではみ出さないコンテンツの実装例を確認することができる。 widthで横幅を指定する position:fixedのコンテンツをleftかrightで横にずらすとコンテンツの横幅との関係で、はみ出してしまうことがある。 だからコンテンツの横幅と左右の余りの横幅を足して画面の横幅一杯を越えないようにコンテンツの横幅のwidthを指定すれば画面内にきっちり収めることができる。 最大幅のmax-widthを使ってもコンテンツを一定の範囲内に収められることは変わらない。 サイトと画面の幅が一致する場合のマークアップ width:calc(100% - コンテンツの余り) モバイルのスマホやタブレットならばサイトと画面の幅が一致していることが多い。その場合は計算式のcacl()を使って100%(position:fixedの基準のビューポートに対して)からleftやrightですらした分だけ引くとコンテンツが画面からはみ出すことはなくなる。 left:50pxとright:50pxでのwidthのマークアップ例 width:calc(100% - (50px + 50px)) サイトと画面の幅が一致する場合は左右から50pxずつ離れた範囲内にコンテンツが表示される。 calcl()の書き方はもっと簡略化できる。 width:calc(100% - 50px - 50px) 括弧を減らすことができるし、予め答えが分かって「50px + 50px」ならば「100px」と書いて計算式の一部を省略することもできる。 サイトよりも画面の幅が大きい場合のマークアップ width:calc(100% - 調整したコンテンツの余り) デスクトップのパソコンならばサイトと画面の幅が一致してなくて前者よりも後者の方が大きいかも知れない。その場合は計算式のcacl()を使ってposition:fixed のコンテンツの位置取りをサイトの領域に入るように調整する必要がある。ビューポートの分を差し引いてしまえばサイトの領域に絞ってコンテンツの横幅を指定できるから画面からはみ出すことはなくなる。 left:50pxとright:50pxでのwidthマークアップ例 width:calc(100% - ((50% - サイト全体の横幅 / 2 + 50px)) + (50% - (サイト全体の横幅 / 2 + 50px))) サイトよりも画面の幅が大きい場合に大外の画面の分を差し引いてサイトの左右の端から50pxずつ離れた範囲内にコンテンツが表示される。 calcl()の書き方はもっと簡略化できる。 width:calc(サイト全体の横幅 / 2 - 50px) + サイト全体の横幅 / 2 - 50px)) 括弧を減らすことができるし、もしも左右均等に配置するならば計算式を一つに纏めることもできる。 width:calc((サイト全体の横幅 / 2 - 50px) * 2)) または width:calc((サイト全体の横幅 - 100px)) サイト全体の横幅も決まって例えば「1240px」ならば全て計算して「1140px」と答えだけをwidthの値に使っても構わない。 leftとrightで横幅を指定する position:fixedのコンテンツの位置取りを指定するtopとleftとrightとbottomは同じ方向の二つの値を同時に指定するとコンテンツの幅も決めることができる。 なので横幅はleftとrightを同時に指定するとwidthで指定したのと変わらなくて、それ以上、広がることは基本的になくなる。 サイトと画面の幅が一致する場合のマークアップ left:左の位置;right:右の位置 モバイルのスマホやタブレットならばサイトと画面の幅が一致していることが多い。その場合はleftとrightを同時に指定するとその範囲にコンテンツが表示される。 left:50pxとright:50pxの同時使用のマークアップ例 left:50px;right:50px サイトと画面の幅が一致する場合は左右から50pxずつ離れた範囲内にコンテンツが表示される。 サイトよりも画面の幅が大きい場合のマークアップ left:調整した左の位置;right:調整した右の位置 デスクトップのパソコンならばサイトと画面の幅が一致してなくて前者よりも後者の方が大きいかも知れない。その場合は計算式のcacl()を使ってposition:fixed のコンテンツの位置取りをサイトの領域に入るように調整する必要がある。ビューポートの分を差し引いてしまえばサイトの領域に絞ってコンテンツの左右の位置を指定できるから画面からはみ出すことはなくなる。 left:50pxとright:50pxの同時使用のマークアップ例 left:calc(50% - サイト全体の横幅 / 2 + 50px;right:calc(50% - サイト全体の横幅 / 2 + 50px サイトよりも画面の幅が大きい場合に大外の画面の分を差し引いてサイトの左右の端から50pxずつ離れた範囲内にコンテンツが表示される。 サイト全体の横幅も決まって例えば「1240px」ならばleftもrightも一部を計算してそれぞれに「50% - 570px」 と計算式を簡略化できる。 二つの方法のデバイス毎の振り分け position:fixedのコンテンツの横幅の指定は画面の大きさによって異なるから完全に対応するには二種類のマークアップをメディアクエリ/@media screenによって振り分けて使うことになる。 マークアップをモバイルに振り分けると @media screen (max-width:サイトの最大幅) { モバイル用のposition:fixedのコンテンツの横幅のマークアップ } マークアップをデスクトップに振り分けると @media screen (min-width:サイトの最大幅に「1px」を足したもの) { デスクトップ用のposition:fixedのコンテンツの横幅のマークアップ } 画面がサイトの最大幅を越えるところからposition:fixedの横幅のマークアップが変わるので、メディアクエリのマークアップの切り替えの条件の画面幅の指定に使える。 最近ではコンテナクエリ/@containerでのマークアップの振り分けも可能になっている。親要素の幅に応じて切り替えることができる。その場合もposition:fixedのコンテンツのマークアップの切り替えの条件になるのはサイトの最大幅という画面幅を越えるかどうかであることに変わりはない。 widthの方法とleftとrightの方法はどちらも同じようなもので、モバイルでもデスクトップでも計算が少ないleftとrightの方法がwidthの方法よりも少し使い易いというくらいの違いしかないかも知れない。 コメント 新しい投稿 前の投稿
コメント