CSSの小技を紹介します!【中央揃え】【レシポンシブ対応アスペクト比固定要素】

現在のWebデザインでは HTML はページ構成を、CSS はデザインを担うこととなっています。

そんな中で地味にどうやってコーディングすれば良いのかと頭を悩ませるものがありますので、紹介したいと思います。
特に最近ではスマホのような低解像度な画面から 4K のような高解像度まで対応したレシポンシブなデザインが求められていますので、描画領域の幅が不明でも使える小技となっています。


中央揃え

意外につまずくのが中央揃えです。
CSS の “text-align : center;” でやろうとするとブロック要素には効かずに頭を悩ませます。
(インライン要素であれば “text-align” で中央揃えにできます)

こちらについては主に3通りのやり方があります。

要素の幅が分かっている場合

要素の幅が分かっている (指定する) 場合は、左右のマージンを “auto” と指定してやることで中央揃えができます。
これは、左右にそれぞれ “auto” を指定することでブラウザが左右のマージンが均等になるよう描画する為です。

ブラウザが良い感じにやってくれるので親要素の幅がいくつであれ、中央揃えになります。
具体的には以下のようにコーディングします。

<HTML>
<div class="box">
  <div class="centering">
  </div>
</div>

<CSS>
.box{
    width    : 300px;
    border   : 1px solid black;
    padding  : 5px;
}
.centering{
width : 100px;
height : 100px;
margin : 0px auto; /* margin に2値指定した場合は、"上下 左右" をそれぞれ一括で指定できる */ /* "margin-left : auto; margin-right : auto;" としても同じ */
border : 1px solid red; }

<実行結果>
1 : マージンで左右を “auto” とした場合
2 : 親要素 (class=”box”) に “text-align : center;” を指定した場合 (中央揃えされません)

1
2

また、要素の幅が分かっているので比較的新しいブラウザ (普通に現役で動く程度に新しいPC) であれば “calc関数” が利用できるので計算してその分を移動させても良いです。
上記の方法では、ブラウザの解釈方法が変わってしまうと中央揃えになりませんが、こちらなら確実に中央揃えになります。
(現在のWebデザインでは margin の方法が良く使われるのでわざわざ変更されるとは考え難いですが)

<HTML>
<div class="box">
  <div class="centering">
  </div>
</div>

<CSS>
.box{
    width    : 300px;
    border   : 1px solid black;
    padding  : 5px;
}
.centering{
width : 100px;
height : 100px; border : 1px solid red;
position : relative; left : calc((100% - 100px) / 2); /* calc関数内では減算の"-"の後ろに半角スペースが入らないと負数だと認識されて思った結果にならにのでご注意下さい */
}

<実行結果>
3 : calc関数で移動させる量を計算させた場合

3

要素の幅が分からない場合

続いては要素の幅が分からない、若しくは変わってしまう場合は上記の方法が使えません。
(中央揃えする要素の幅が不定な為)
※Javascriptなどで内容が動的に書き換わる要素など

以下の方法なら要素サイズを気にせずに使えるので、class まとめて指定する際にも重宝します。

<HTML>
<div class="box">
  <img src="vertical.png" width="80" height="120">
</div>
<div class="box">
  <img src="horizontal.png" width="180" height="120">
</div>

<CSS>
.box{
    width     : 300px;
    border    : 1px solid black;
    padding   : 5px;
}
.box > img{  /* セレクタでまとめて指定 */
position : relative; left : 50%; transform : translateX(-50%);
}

<実行結果>

こちらの方法では縦方向も同様に中央揃えにできますので、応用範囲は広いです。
(“top : 50%; transform : translateX(-50%) translateY(-50%);” を追加すれば良いです)

但し、transform プロパティは分かりにくくバグを生みやすいので使用する箇所は必要最低限に抑えておくと良いでしょう。

アスペクト比固定要素

続いてはアスペクト比を固定した要素の作成方法です。

レシポンシブデザインでWebページを設計していると、例えば「画面幅の 20% を1辺とする正方形の要素」といったものを作りたくなることがあります。
でもこれって幅はいいけど高さはどうするの?という疑問が出てきます。

そんな時は、以下の方法で対応できます。

padding プロパティに “%” を指定して高さを幅基準で作り出す

アスペクト比を固定する為に使うのは “padding プロパティ” がキモになります。

“padding プロパティ” の値に “%” を用いた比率を指定すると親要素の幅を基に計算されます。
実はこういった仕様になっているんですね~。

padding で要素ボックスの高さを決めたらその子要素をボックスいっぱいまで広げてやればアスペクト比固定の要素を作り出すことができます。
具体的には以下のようにコーディングしていきます。

<HTML>
<div class="box1">
  <div class="fix-aspect">
    <div>アスペクト比が固定された要素1</div>
  </div>
</div>
<div class="box2">
  <div class="fix-aspect">
    <div>アスペクト比が固定された要素2</div>
  </div>
</div>

<CSS>
.box1{ /* 親要素 -> ".fix-aspect"のpaddingの基準となる幅になる要素 */
    width    : 300px;
}
.box2{ /* 親要素 -> ".fix-aspect"のpaddingの基準となる幅になる要素 */
    width    : 200px;
}
.fix-aspect{
    position : relative;  /* 子要素にabsoluteを指定するので基準をこの要素にする為にstatic(初期値)以外が必要 */
    width    : 100%;
    padding-top : 66.7%;  /* 親要素の幅の2/3を比率で指定して2:3のボックスを作る(padding-bottomでもOK) */
}
.fix-aspect > div{
position : absolute; /* top~rightでボックスいっぱいまで引き延ばす為にpositionはabsoluteに設定する必要がある */ top : 0; /* 上下左右からの位置を0にすると要素いっぱいまで広がる */ bottom : 0; /* "height:100%;" では要素いっぱいまで広がらないので注意が必要です */ left : 0; right : 0;
background-color : #FFDDDD; }

<実行結果>

アスペクト比が固定された要素1
アスペクト比が固定された要素2

このように padding プロパティで要素幅に依存した高さの設定ができます。

CSSを使わない場合は、希望のアスペクト比となる透明画像 (若しくは CSS の “visibility” プロパティを “hidden” にするか、”opacity” で透過する) をインライン要素に貼り付けて大きさを確定させる方法も考えられます。
もちろんこの方法は現在の HTML 文書の構造上は推奨できませんし、アスペクト比を変えるたびに画像を用意しなければならず不便ですので “padding” による指定が良いでしょう。

要素間に線や疑似要素を表示する

要素と要素の間に境界線を表示したり、疑似要素で矢印などを表示したいことは良くありますよね。

一番簡単な方法は、全ての要素に対して一旦設定して最後の要素だけは疑似クラスの “:last-child” で打ち消す、という方法が良くとられます。
でもこれって打ち消すべきプロパティが増えると面倒ですし、変更も大変です。

そんな時は隣接セレクタというものを使うことで簡略化できます。
(もちろん隣接セレクタでは対応できない場合もあります)

隣接セレクタでは、ある要素のすぐ後ろに来る要素を選択することができます。
これを使って、例えば <div> タグで作ったボックスの間に疑似要素を表示するなら以下の指定方法で div と div が連続している2個目の要素にだけスタイルを選択できます。
div + div::before { /* 疑似要素で表示する要素を作る */ }

<HTML>
<div class="ele_between">
  <div></div>
  <div></div>
</div>
<div class="ele_between">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

<CSS>
.ele_between div{
    height        : 50px;
    border        : 1px solid black;
    border-radius : 10px;
    box-sizing    : border-box;
}
.ele_between div + div{   /* class="ele_between" の下層にあるdivのすぐ後ろにあるdivに対する要素が選択される */
    border-color  : red;  /* 分かりやすいように色を付けておく */
    position      : relative;  /* 疑似要素の位置をabsoluteで指定するので基準をこの要素にする為 */
    margin-top    : 20px; /* 疑似要素を置く場所を開けておく */
}
.ele_between div + div::before{   /* class="ele_between" の下層にあるdivのすぐ後ろにあるdivに対する要素が選択される */
    position      : absolute;
    content       : ' ';
    top           : -11px;
    left          : 50%;
    transform     : translate(-50%);
    width         : 20%;
    height        : 2px;
    background    : #A1A1A1;
}

<実行結果>
要素の数が変わっても問題なし。

また応用として、パンくずリストの間に矢印を表示させることも可能です。

<HTML>
<ul class="header-breadcrumb2" itemscope itemtype="http://schema.org/BreadcrumbList">
  <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
    <a href="https://analogstd.com" itemid="https://analogstd.com" itemscope itemtype="http://schema.org/Thing" itemprop="item">
      <span itemprop="name">Analog Studio</span>
    </a>
    <meta itemprop="position" content="1">
  </li>
  <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
    <a href="https://analogstd.com/category/pc/" itemid="https://analogstd.com/category/pc/" itemscope itemtype="http://schema.org/Thing" itemprop="item">
      <span itemprop="name">PC</span>
    </a>
    <meta itemprop="position" content="2">
  </li>
  <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
    <a href="https://analogstd.com/category/pc/css/" itemid="https://analogstd.com/category/pc/css/" itemscope itemtype="http://schema.org/Thing" itemprop="item">
      <span itemprop="name">CSS</span>
    </a>
    <meta itemprop="position" content="3">
  </li>
</ul>

<CSS>
ul.header-breadcrumb{
 	list-style-type : none;
 	padding         : 0px;
 	margin          : 5px;
	line-height     : 1em;
	font-size       : 0;
}
ul.header-breadcrumb li{
	position        : relative;
	display         : inline-block;
	margin          : 0px;
	margin-right    : 20px;
	padding         : 10px;
	font-size       : 12px;
	background-color: #EFEFEF;
	border-radius   : 5px;
	box-shadow      : 1px 1px 2px rgba(0,0,0,0.2);
}
ul.header-breadcrumb li + li::before{
	position        : absolute;
	content         : '>';
	left            : 14px;
	top             : 10px;
}

<実行結果>

まとめ

以上、CSS を使った小技でした。

レシポンシブなデザインに不可欠な技術ですので是非このブログに方法が載っていることを覚えておいて下さい。
コーディングの細かいところまで覚えておく必要はないと思いますので、考え方を覚えておくと良いでしょう。

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください