CSSで「〇〇したい」とか「これどうするんだっけ...」というときに使えるものや地味だけど覚えておくと便利だと思う簡易的なスニペットを紹介する第1弾です。
以前であれば画像やJavaScriptを用いなければいけなかったものがCSSのみで表現できたり、上手く使えばよりシンプル且つ効率良く記述するのに役立つものもあるので、特にこれからCSSを学びたいという人や学び始めたばかりでもう少しレベルアップしたいという人は是非試してみてください。
- サンプルコードは基本的にプレフィックスを省略しています。
- デモが用意されていないものについては、自身で簡単な環境を作成して試してもらうか「CodePen」や「JSFiddle」などを利用して実際の動きを確認してください。
継承するbox-sizing指定
ボックスモデルのルールを変更できるbox-sizing
を使用時にその指定が継承される形にしたい場合は、リセットスタイルなどに下記のように指定しておくと便利です。
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
これが便利と感じるかは人それぞれですが、実際にこの指定を「sanitize.css」「ress」「minireset.css」のように取り入れている有名なリセットCSSも多くあります。
clearfix
clearfixとは要素のfloat
を解除するのに便利な手法のひとつで、普段からCSSを触るのであれば聞いたことないという人の方が少ないと思います。
知らない人の為にclearfixとは何なのかを簡単に説明をすると、通常float
を利用して要素を回り込ませた場合、そのままにしておくとその後のレイアウトが大きく崩れたりなどの影響が出るため、float
指定した次にくる要素などに回り込みを解除するためのclear
を指定する必要があり、人によってはわざわざそれ用の要素を作成するという人もいました。
clearfixはこういった手間を省くことができる手法で、以下で紹介するスタイルを親要素に指定することで子要素に指定されたfloat
を簡単に解除することができます。
また、親要素に指定した背景が上手く表示されないとかmargin
指定が思うようにいかないというときも、このclearfixを利用することで解決できることもあります。
clearfixが考えられたのがもう10年以上前の話で、当時はIE6などのブラウザ対応のために少し記述も長めで一部ハックを用いた記述も必要でしたが、現在は下記のようにシンプルな記述になっています。
.clearfix::after {
content: '';
display: block;
clear: both;
}
上記を共通CSSなどに記述しておき、あとはfloat
を使う子要素が出てきたときにその親要素に対して.clearfix
を指定すれば簡単にfloat
を解除させることができます。
最近だとFlexboxを使う場面も多くなってきているので、個人的にも以前に比べたら使用頻度は少なくはなりましたが、float
を多用していてclearfixの存在を初めて知ったという人がいれば是非使ってみてください。
おまけ:clearfixの代替案
上でclearfixについて紹介してきましたが、他にもこんな方法もあるよということでclearfixの代替案となる2通りの方法を紹介します。
overflow: hidden;
正確にはfloat
の解除を行っているわけではないですが、下記のようなfloat
指定された子要素とそれらを括る親要素のHTMLがあるときに、この親要素に対してoverflow: hidden;
を指定する形でもclearfixを使用したときと同じような挙動になります。
<div class="parent">
<div class="float-element"> ... </div>
<div class="float-element"> ... </div>
</div>
.parent {
overflow: hidden;
}
.float-element {
float: left;
}
こちらの方が1行で書けるのでよりシンプルで使いやすい印象はありますが、overflow: hidden;
をclearfix代わりに使う場合は注意する点もいくつかあり、よくありそうなものでは例えば子要素にbox-shadow
などで親要素からはみ出るようなシャドウをかけている場合にシャドウが途中で切れてしまったり、他にも子要素をposition: absolute;
を使うなどして親要素からはみ出ているような位置に配置した際にも同じく途中で切れてしまう見栄えになってしまいます。
overflow: hidden;
を指定しているので当たり前と言えば当たり前なのですが、このようなスタイルを子要素に指定する・指定する可能性がある場合などはoverflow: hidden;
よりもclearfixを利用した方が無難です。
display: flow-root;
「Can I use」などでも確認できるように使用できるブラウザもかなり限られているので、何も考えずに使えるようになるのは当分先だと思いますが、display: flow-root;
を使うことでclearfixを使ったときのように子要素のfloat
を簡単に解除することができます。
使用方法も下記のようなfloat
指定された子要素とそれらを括る親要素のHTMLがあるときに、この親要素に対してdisplay: flow-root;
を指定するだけと簡単です。
<div class="parent">
<div class="float-element"> ... </div>
<div class="float-element"> ... </div>
</div>
.parent {
display: flow-root;
}
.float-element {
float: left;
}
1行で書けるシンプルさはoverflow: hidden;
と同じですが、こちらの場合は先ほど注意点としてあげた子要素が途中で切れてしまうなどの問題も考えずに指定することができます。
先述したようにまだまだ非対応ブラウザが多く多用できるまでにはまだ時間がかかりそうなのですが、個人的には早く何も気にすることなく使えるようになってほしいプロパティのひとつです。
テキストの回り込みを防ぐ
例えば下記のようなHTMLがあって画像の横にテキストを表示させたいというとき、単純にimg
要素に対してfloat: left;
を指定するだけだと上のイメージのようにテキストの長さによっては画像の下に回り込む見栄えになります。
<img src="image.png" >
<p>lorem ipsum ... </p>
これを回り込まない形にしたくて且つFlexboxなどを使えない状況というときには、下記のようにテキストを表示している要素にoverflow: hidden;
を指定することで回り込みを防ぐことができます。
img {
float: left;
}
p {
overflow: hidden;
}
センタリングレイアウト(レスポンシブ向け)
一般的にセンタリングレイアウトを実装する方法として「幅指定 + 左右のmarginをauto指定」を記述し、幅指定の部分はwidth: 960px;
のように決め打ちで指定するものがありますが、例えば...
- レスポンシブ対応
- CSSを「モバイル向け → タブレット向け → ラップトップ向け」のようにモバイルファーストで記述
- モバイル・タブレット時は幅いっぱいで表示し、ラップトップなどそれ以上のサイズでは最大幅を指定
のような条件で且つセンタリングレイアウトを実装したい場合は、下記のようにwidth
に加えmax-width
を併用した形で記述すると、ウィンドウサイズが小さいときはレイアウトを幅いっぱいに表示させつつ特定のサイズ以上になったら決め打ちの幅でセンタリングされる動きになり、Media Queriesを使ってわざわざ特定のサイズでCSSを再調整する必要もなくなります。
element {
width: 100%;
max-width: 960px;
margin: 0 auto;
}
width: 100%;
は不要であれば削除可。
また、基本的に幅いっぱいにしたいけれども多少は左右に余白を設けたいという場合は下記のようにcalc()
を利用する形で実装する方法があります。
最大幅は960px
にしてあるので、例えばウィンドウサイズが1000px
以上になった場合は960px
でセンタリング配置され、それ以下のときは左右に20px
ずつ余白が設けられて残りの領域がコンテンツ領域となります。
element {
width: calc(100% - 40px);
max-width: 960px;
margin: 0 auto;
}
max-widthやmin-widthを解除する
width
で幅指定したものはauto
を指定することで解除することができますが、要素の最大幅を指定するmax-width
や逆に最小幅を指定するmin-width
を使用した際、それらを使って指定した幅を解除したいと思ってもauto
では解除することができません。
max-width
やmin-width
の幅指定を解除したい場合は、下記のようにinherit
を値に指定することで解除でき、サンプルコード内にはありませんがmax-height
とmin-height
についても同様にinherit
で解除できます。
.max-width {
max-width: inherit;
}
.min-width {
min-width: inherit;
}
ちなみに、inherit
を使用せずに初期値を指定することでももちろん解除することは可能で、その場合はmax-width
とmax-height
にはnone
を、min-width
とmin-height
には0
をそれぞれ指定します。
これといった問題が起きた印象はないのですが、inherit
を指定して何かしらの問題が起きた場合はこれらの指定を利用してみてください。
高さを100%にする
ある要素の高さを100%
(ウィンドウサイズの高さいっぱい)にしたい場合、単純にその要素にheight: 100%;
を指定するだけでは実装することができません。
これはheight
の%
指定はその親となる要素の高さに対して計算されるのが関係しており、下記のように該当の要素だけでなくhtml
とbody
に対してもheight: 100%;
を指定することで実装できます。
html, body {
height: 100%;
}
element {
height: 100%;
}
また、より簡単な方法として下記のようにvh
を使用するという方法もあり、この場合はその高さを100%
にしたい要素にのみ記述することで実装できます。
element {
height: 100vh;
}
ただし、詳しくは割愛しますがこの100vh
を指定する方法は気を付けなければいけない点もあり、例えば特定のブラウザで利用できなかったり利用できたとしてもスクロール時などに若干ズレが生じることがあったりするので、状況に応じて使い分けるのが良いと思います。
要素の中央配置
要素のサイズがわからないまたは決め打ちにすることができないけど特定の範囲で上下左右ともに中央で配置したい場合は、CSSを下記のように記述することで実装できます。
element {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
使用箇所によっては別途親要素にposition: relative;
を指定するなどの必要があります。
ここでは個人的に何かと使い勝手が良くて好んで使用しているのでこの方法を紹介しましたが中央配置の方法は他にも沢山あり、それらについては以前まとめているので興味ある方は以下をご覧ください。
calc()を活用する
calc()
はCSSで四則計算を行うことができるもので、活用することでこれまでCSSだけでは指定が難しかった値を指定できたり、複数の記述が必要だったものをシンプルにすることが可能になります。
具体的な使用例としては下記のようなものがあります。
天地中央配置
ある要素を天地中央に配置したく且つその要素のサイズがハッキリわかっている場合は、よくある方法として下記のような指定方法があります。
element {
position: absolute;
top: 50%;
left: 50%;
width: 200px;
height: 200px;
margin-top: -100px;
margin-left: -100px;
}
上のコードは、まずtop
とleft
にそれぞれ50%
を指定し、その後要素の半分のサイズをネガティブマージンとしてmargin-top
とmargin-left
で指定することで要素を天地中央配置させるというものですが、これはcalc()
を利用することで下記のように記述することでも実装でき、calc()
を利用することでmargin
の記述が不要になり、さらに要素サイズの半分がいくつになるかという計算をして記述するのも不要になります。
element {
position: absolute;
top: calc(50% - calc(200px / 2));
left: calc(50% - calc(200px / 2));
width: 200px;
height: 200px;
}
分割数をわかりやすく
例えばグリッドレイアウトのように要素を横並びで配置する際、その要素の幅指定がwidth: 20%;
とかwidth: 50%;
のようになっていると前者は5カラムで後者は2カラムと容易に把握できますが、これがwidth: 16.666666667%;
だとかwidth: 14.285714285%;
になっていると、パッと見でそれらは何カラムなのかが把握しづらいです。
これはcalc()
を使って下記のように記述することでカラム数も容易に把握できるようになり、さらに自分で計算する必要もなくなります。
/* 6カラム width: 16.666666667%; */
element {
width: calc(100% / 6);
}
/* 7カラム width: 14.285714285%; */
element {
width: calc(100% / 7);
}
%幅指定とpxマージンを組み合わせる
要素を横並びで配置するとき、要素の幅指定の単位は%
を指定するけどマージンについてはpx
指定で決め打ちにしたい場合に使える方法で、例えば下記のようなHTMLがあったとします。
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
ここに子要素(.child
)に対して4分割で幅指定をしつつ左右にそれぞれ20px
のマージンを付けたいという場合は、calc()
を利用して下記のようなCSSで実装できます。
.parent {
margin-right: calc(calc(20px / 2) * -1);
margin-left: calc(calc(20px / 2) * -1);
}
.child {
width: calc(calc(100% / 4) - 20px);
margin-right: calc(20px / 2);
margin-left: calc(20px / 2);
}
上記は幅指定とマージンに関する記述部分のみ抜粋しているので、実際にはさらに横並びにするためにdisplay: flex;
やfloat: left;
などを記述する必要があります。
コード内にあるcalc(100% / 4)
となっている箇所でカラム数を指定し、20px
と指定されている5箇所には付けたいマージンを指定していきます。
マージン部分についてはわざわざcalc()
を使用しなくてもと思うかもしれませんが、個人的にはこうしておくことで変更時に数値をわざわざ計算する必要もなくなりますし、すべて同じ数値を指定すればいいという理由から利用することが多いです。
ちなみに、CSSだとマージンを変更したくなった場合はこの5箇所すべてを変更する必要がありますが、Sassを利用しているのであればこれらをすべて変数にしておくとより指定が楽になります。
:not()を使ってスタイル指定を少しシンプルに
例えばよくあるリストにborder
を使って罫線を引くけど一番上のリストには引きたくないという場合、方法はいろいろありますが昔からよく利用されてきた方法のひとつとして下記のようなものがあります。
ul li {
border-top: 1px solid #aaa;
}
ul li:first-child {
border-top: none;
}
上記で目的の見栄えにすることはできますが、これを下記のように:not()
を用いて指定することで少しシンプルに指定することができます。
このサンプルコードの場合はli
要素の:first-child
以外の要素にスタイルを適用するというもので、先ほどのコードのようにわざわざ後からli:first-child
に対してborder-top: none;
を指定する必要がなくなります。
ul li:not(:first-child) {
border-top: 1px solid #aaa;
}
もうひとつ:not()
の使用例の紹介で、下記のように属性セレクタを使用することもでき、この場合はclassが指定されているa
要素以外にスタイルを適用するというものになります。
a:not([class]) {
/* style here... */
}
便利に感じるかどうかは組み方次第な部分もありますが、具体的にはa
要素のデフォルトスタイルとしてcolor
やtext-decoration
を指定しているけどコーディングしていく際にそれらをわざわざ打ち消すことが多い場合などに、このように:not()
を使った形でa
要素のデフォルトスタイルを指定しておくことで、class指定されたa
要素には適用されずにわざわざ不要なデフォルトスタイルを打ち消すという必要がなくなります。
ここでは擬似クラスと属性セレクタを使った例を紹介しましたが、他にもidやclassで指定したり:not()
を複数組み合わせて使うこともできます。
使いこなすことができれば上で紹介したようにわざわざ打ち消すスタイルを指定する必要がなくなったり、idやclassの付け外しが必要なくなったりと、何かと手間を省けたりシンプルにスタイル指定ができるようになると思います。
@supportsを使ったCSSの条件分岐
同じCSSを読み込んでいるけどブラウザによってスタイルを変えたいというとき、有名な方法としては「Modernizr」を使って特定のclassを付与してそれをスタイル指定に利用するとかCSSハックを利用するといったものがありますが、それらの代わり(正確には違いますけど...)のような形で使用できるのが@supports
です。
@supports
を使うことで特定のプロパティがそのブラウザでサポートしているかしていないかを判断することが可能で、これを利用することで対応ブラウザには○○のスタイルを、非対応ブラウザには△△のスタイルを指定のようなことがCSSのみで実装できます。
例えば「2. clearfix」の中で紹介したdisplay: flow-root;
を例として紹介すると、下記のような記述でdisplay: flow-root;
をサポートしているかしていないかでスタイルをそれぞれ指定することができます。
@supports (display: flow-root) {
/* ここに対応ブラウザ用のスタイル */
}
@supports not (display: flow-root) {
/* ここに非対応ブラウザ用のスタイル */
}
上記のように@supports
後の()
内にサポート判断させたいプロパティを記述し、その中にそれぞれスタイルを記述していく形で使用します。
このサンプルコードの場合は対応している場合の@supports ()
と非対応時の@supports not ()
を使用していますが、and
やor
を使った条件指定も可能です。
結局一番これを利用できたら嬉しいIEでは使えない(@supports - Can I use)ので、IEをサポートする必要がある場合には使用する機会はかなり減ると思いますが、IEは無視できる状況でちょっとした条件分岐を利用したいというときには便利です。
その他のCSS Snippetsに関しては下記ページから確認できます。