CSSのdisplayとposition

cssweb

display

レンダリングに使うボックスを指定する。

outer display type

pのようなブロックレベル要素やspanのようなインラインレベル要素に関わらず、指定したボックスにレンダリングする。

outer display type

<style>
.bg {
  background-color: #22ee22;
  width: 150px;
  height: 50px;
}
</style>

<div>this is <span style="display:none" class="bg">none</span> desu</div>

<div>this is <p style="display:inline" class="bg">inline</p> desu</div>

<div>this is <span style="display:block" class="bg">block</span> desu</div>

<div>this is <span style="display:inline-block" class="bg">inline-block</span> desu</div>

flexbox

displayでflexinline-flexを指定すると領域に応じてサイズやレイアウトが柔軟に決定されるflexboxになる。 IE11もいくつかのバグのため挙動が異なることがあるがサポートはしている。 レスポンシブなデザインを実現する他の方法としては後述するgridや、@media screen and (min-width: 900px) {}のような メディアクエリによる条件付きスタイルがある。 メディアクエリは<meta name="viewport" content="width=device-width, initial-scale=1.0">のようにしてビューポートのサイズを指定しないと意図通りに動かない。

flex-flowは 表示する方向のflex-directionと 折り返しのflex-wrapのショートハンドプロパティ。

子要素のflexは 伸びるときの倍率のflex-grow(default: 0)と 縮むときの倍率のflex-shrink(default: 1)、 初期サイズのflex-basis(default: auto)の ショートハンドプロパティ。

flex

<style>
.bg {
  background-color: #22ee22;
}
.bg2 {
  background-color: #ee22ee;
}
</style>

<div>
  <div>500x100</div>
  <div style="display:flex; flex-flow: row wrap; width: 500px; height: 100px; margin: 5px;" class="bg" >
    <!-- flex-basis -->
    <div style="flex: 200px; margin: 5px" class="bg2">flex-item1</div>
    <div style="flex: 200px; margin: 5px" class="bg2">flex-item2</div>
    <!-- flex-grow | flex-shrink | flex-basis -->
    <div style="flex: 0 1 200px; margin: 5px" class="bg2">flex-item3</div>
  </div>
  <div>350x100</div>
  <div style="display:flex; flex-flow: row wrap; width: 350px; height: 100px; margin: 5px;" class="bg" >
    <!-- flex-basis -->
    <div style="flex: 200px; margin: 5px" class="bg2">flex-item1</div>
    <div style="flex: 200px; margin: 5px" class="bg2">flex-item2</div>
    <!-- flex-grow | flex-shrink | flex-basis -->
    <div style="flex: 0 1 200px; margin: 5px" class="bg2">flex-item3</div>
  </div>
</div>

grid

displayでgridinline-gridを指定するとテーブルよりも柔軟なグリッドレイアウトが作れる。 grid-template-(rows/columns)で行/列のサイズを 空間の分数fr (fraction)で指定できる。例えば1fr 2fr 1frのように指定すると1:2:1のサイズになる。 あるいは、grid-auto-(rows/columns)によって画面サイズに合わせて調整したり、 repeat(auto-fit, 100px)のように書くことで敷き詰めることができる。

子要素は自動で配置されるが、grid-columngrid-rowなどで位置を指定することもできる。

grid

<style>
.bg {
  background-color: #22ee22;
}
.bg2 {
  background-color: #ee22ee;
}
</style>

<div>
  <div>150x150</div>
  <div style="display:grid; grid-template-columns: repeat(3, 1fr); width: 150px; height: 150px; margin: 5px;" class="bg" >
    <div style="grid-column: 1; grid-row: 1; width: 50px; height: 50px;" class="bg2">1x1</div>
    <div style="grid-column: 2; grid-row: 2; width: 50px; height: 50px;" class="bg2">2x2</div>
    <div style="grid-column: 3; grid-row: 3; width: 50px; height: 50px;" class="bg2">3x3</div>
    <div style="grid-column: 1; grid-row: 2; width: 50px; height: 50px;" class="bg2">1x2</div>
  </div>

  <div>300x(grid-auto-rows)</div>
  <div style="display:grid; grid-template-columns: 1fr 2fr 1fr; width: 300px; grid-auto-rows: minmax(50px, auto); margin: 5px;" class="bg" >
    <div style="width: 50px; height: 50px;" class="bg2">item1</div>
    <div style="width: 50px; height: 50px;" class="bg2">item2</div>
    <div style="width: 50px; height: 50px;" class="bg2">item3</div>
    <div style="width: 50px; height: 50px;" class="bg2">item4</div>
    <div style="width: 50px; height: 50px;" class="bg2">item5</div>
    <div style="width: 50px; height: 50px;" class="bg2">item6</div>
    <div style="width: 50px; height: 100px;" class="bg2">item7</div>
    <div style="width: 50px; height: 50px;" class="bg2">item8</div>
  </div>
</div>

中央寄せ

横方向の中寄せはblockにwidthを設定してmargin autoしたり、親要素でtext-align: centerしてinline(-block)にすることでできる。

横方向の中央寄せ

<style>
.bg {
  background-color: #22ee22;
  height: 80px;
}
</style>

<div style="margin: 5 auto" class="bg">block margin</div>

<div style="margin: 5 auto; width: 100px" class="bg">block margin width</div>

<div style="margin: 5 auto; display: inline-block" class="bg">inline-block margin</div>

<div style="text-align: center">
  
  <div style="display: inline-block" class="bg">inline-block align-center</div>
  
  <div style="width: 100px" class="bg">block align-center width</div>
</div>

一方、縦方向の中央寄せはblockにheightを設定してmargin autoしても0となり、親要素でvertical-align: middleしてinline(-block)にしてもボックス内で少し下に動くだけなので、次のようにtopで50%動かして、transformで調整などする。

縦方向の中央寄せ

<style>
.bg {
  position: relative;
  background-color: #22ee22;
  width: 300px;
  height: 100px;
}
.bg2 {
  position: absolute;
  background-color: #ee22ee;
  top: 50%;
  left: 50%;
  transform: translateY(-50%) translateX(-50%);
  -webkit-transform: translateY(-50%) translateX(-50%);
}
</style>


<div class="bg">
  <span class="bg2">center</span>
</div>

あるいはflexboxならjustify-content: centerで横方向の、align-items: centerで縦方向の中央寄せができ、 子要素でalign-selfを指定することで個別に設定を上書きすることもできる。 top/leftで動かす方法は他の要素によってずれることがあるが、こちらは大抵うまくいき、複数要素を揃えるのも簡単。

Flexboxの中央寄せ

<style>
.bg {
  background-color: #22ee22;
}
.bg2 {
  background-color: #ee22ee;
}
</style>
<div style="display:flex; flex-flow: row wrap; width: 500px; height: 100px; justify-content: center; align-items: center;" class="bg" >
  <!-- flex-basis -->
  <div style="flex: 200px; margin: 5px" class="bg2">flex-item1</div>
  <div style="flex: 200px; height: 50px; margin: 5px" class="bg2">flex-item2</div>
  <!-- flex-grow | flex-shrink | flex-basis -->
  <div style="flex: 0 1 200px; margin: 5px" class="bg2">flex-item3</div>
</div>

position

relative

この設定を考慮せずにすべての要素を配置した後に設定を適用する。 そのため、この例の3つ目のdivのleft: 30pxは2つ目のdivの元々の位置から30px右になっている。

relative

<style>
.bg {
  display: inline-block;
  background-color: #22ee22;
  width: 150px;
  height: 50px;
}
</style>

<div>
  <div class="bg">aaa</div>
  <div style="position: relative; top: 30px; left: 30px" class="bg">bbb</div>
  <div style="position: relative; left: 30px" class="bg">ccc</div>
</div>

absolute

絶対位置で指定する。位置指定された祖先要素の相対的な位置になる。

absolute

<style>
.bg {
  display: inline-block;
  background-color: #22ee22;
  width: 150px;
  height: 50px;
}
</style>

<div>
  <div class="bg">aaa</div>
  <div style="position: relative; top: 50px">
    <div style="background-color: #eeeeee">relative top 50px</div>
    <div style="position: absolute; top: 50px; left: 300px" class="bg">top 50px; left: 300px</div>
    <div style="position: absolute; left: 100px" class="bg">left 100px</div>
  </div>
</div>

fixed

ビューポートに対して絶対的な位置を指定する。この例では2つ目のfixedなdivはスクロールしてもビューポートに対して位置が固定される。

fixed

<style>
.bg {
  display: inline-block;
  background-color: #22ee22;
  width: 150px;
  height: 50px;
}
</style>

<div style="height: 3000px" class="bg">aaa</div>
<div style="position: fixed; top: 50px; left: 300px" class="bg">top 50px; left: 300px</div>