CSSで「〇〇したい」とか「これどうするんだっけ...」というときに使えるものや地味だけど覚えておくと便利だと思う簡易的なスニペットを紹介する第3弾です。
以前であれば画像やJavaScriptを用いなければいけなかったものがCSSのみで表現できたり、上手く使えばよりシンプル且つ効率良く記述するのに役立つものもあるので、特にこれからCSSを学びたいという人や学び始めたばかりでもう少しレベルアップしたいという人は是非試してみてください。
- サンプルコードは基本的にプレフィックスを省略しています。
- デモが用意されていないものについては、自身で簡単な環境を作成して試してもらうか「CodePen」や「JSFiddle」などを利用して実際の動きを確認してください。
borderで矢印をつくる #1
border
を利用して矢印を作る方法で、基本となるスタイルに加えて例えば上向きの矢印であればborder-bottom
を、右向きの矢印であればborder-left
というように表示させたい向きとは逆の方向のborder
にカラーを指定すれば実装することができます。
その際にすべてのborder-width
を一緒にせずに、デモにある.arrow-up-narrow
や.arrow-up-wide
のように少し違いをつけることで幅広や幅狭の矢印にすることができ、.arrow-top-left
や.arrow-top-right
のように2方向指定すれば斜めの矢印にすることができます。
HTMLは<span class="arrow arrow-top"></span>
のようなものを使用している想定で、ここではspan
を利用する想定にしていますが少し内容を変更することで疑似要素での表示も容易にできます。
/* arrow common style */
.arrow {
display: inline-block;
width: 0;
height: 0;
border: 15px solid transparent;
}
.arrow-top {
border-bottom-color: #000;
}
.arrow-right {
border-left-color: #000;
}
.arrow-bottom {
border-top-color: #000;
}
.arrow-left {
border-right-color: #000;
}
.arrow-top-narrow {
border-bottom: 30px solid #000;
}
.arrow-top-wide {
border-top: 15px solid transparent;
border-right: 30px solid transparent;
border-bottom: 15px solid #000;
border-left: 30px solid transparent;
}
.arrow-top-left {
border-top: 15px solid #000;
border-left: 15px solid #000;
}
.arrow-top-right {
border-top: 15px solid #000;
border-right: 15px solid #000;
}
.arrow-bottom-left {
border-bottom: 15px solid #000;
border-left: 15px solid #000;
}
.arrow-bottom-right {
border-bottom: 15px solid #000;
border-right: 15px solid #000;
}
borderで矢印をつくる #2
同じくborder
を利用して矢印を作る方法ですがこちらは先ほどとは異なるタイプのもので、上で紹介したものはborder-color
を指定する方向を変更することによって矢印の向きを変えていましたが、こちらはborderの指定は変更せずにtransform: rotate();
を使って向きを変えています。
また、こちらのタイプで幅広や幅狭な矢印を作成したい場合はtransform: skew();
を利用し、値をマイナスにすれば幅狭に、プラスにすれば幅広に見せることができます。
斜め指定についても新たにスタイルを追加とかではなくtransform: rotate();
で調整を行っており、上のデモではさらにtransform: skew();
も加えてより斜め方向に向くようにしています。
ちなみに、ここではtransform: rotate();
で回転をさせる形にしていますが、単純に左上ならborder-top
とborder-left
を、右下ならborder-right
とborder-bottom
という感じで指定して表示させることももちろんできます。
HTMLは<span class="arrow arrow-top"></span>
のようなものを使用している想定で、ここではspan
を利用する想定にしていますが少し内容を変更することで疑似要素での表示も容易にできます。
/* arrow common style */
.arrow {
display: inline-block;
width: 15px;
height: 15px;
border-top: 2px solid #000;
border-right: 2px solid #000;
}
.arrow-top {
transform: rotate(-45deg);
}
.arrow-right {
transform: rotate(45deg);
}
.arrow-bottom {
transform: rotate(135deg);
}
.arrow-left {
transform: rotate(-135deg);
}
.arrow-top-narrow {
transform: rotate(-45deg) skew(-15deg, -15deg);
}
.arrow-top-wide {
transform: rotate(-45deg) skew(7deg, 7deg);
}
.arrow-top-left {
transform: rotate(-90deg) skew(-10deg, -10deg);
}
.arrow-top-right {
transform: rotate(0) skew(-10deg, -10deg);
}
.arrow-bottom-left {
transform: rotate(180deg) skew(-10deg, -10deg);
}
.arrow-bottom-right {
transform: rotate(90deg) skew(-10deg, -10deg);
}
要素に複数のボーダーを表示する
CSSを使ってひとつの要素に対して複数のボーダーを表示させる方法を3パターン紹介します。
いずれも初期状態としてborder: 10px solid black;
が指定されている要素があると想定し、そこへさらにボーダーを追加表示させていきます。
疑似要素を利用する
疑似要素を利用する方法で、下記のように記述することで初期状態に表示されているものを含めて最大3つ分のボーダーを表示させることができます。
element {
position: relative;
border: 10px solid black;
}
element::before {
position: absolute;
top: -20px;
right: -20px;
bottom: -20px;
left: -20px;
z-index: -1;
content: '';
border: 10px solid red;
}
element::after {
position: absolute;
top: -30px;
right: -30px;
bottom: -30px;
left: -30px;
z-index: -1;
content: '';
border: 10px solid blue;
}
outlineを利用する
outline
プロパティを利用する方法で、初期状態に表示されているものを含めて最大2つ分のボーダーしか表示させることはできず、さらにborder-radius
を併用できないという注意点がありますが、上で紹介した疑似要素を利用するものに比べたら非常にシンプルな記述でできます。
element {
border: 10px solid black;
outline: 10px solid red;
}
box-shadowを利用する
box-shadow
を利用する方法で、下記サンプルコードの場合は初期状態のものを含めて4つ分のボーダーが表示された状態になります。
こちらはborder-radius
も併用可能ですし、シンプルな記述で数も追記しただけ表示することが可能なので、ここで紹介している方法の中では一番使いやすい実装方法だと思います。
element {
border: 10px solid black;
box-shadow: 0 0 0 10px red, 0 0 0 20px blue, 0 0 0 30px yellow, 0 0 0 40px green;
}
ホバー時にレイアウトを崩さずに画像や要素にボーダーを表示する
特に隙間なく並べられた画像や要素があり、それらにホバー時にボーダーを表示させたいというとき、単純にelement:hover { border: 10px solid black; }
などのように指定するとレイアウトが崩れたり表示がガタガタになってしまいます。(上記デモの「default」参照)
このように隙間なく並んだ要素があってhover
時にレイアウトを崩さずボーダーを表示させたいときは下記のような方法で実装することができ、それぞれ実際の動きは上にあるデモで確認してください。
ネガティブマージンを利用する
ホバー時にborder
を使用してボーダーを表示させますが、その際にborder-width
の値を引く形でネガティブマージンを併せて指定する方法です。
element:hover {
position: relative;
margin: -10px;
border: 10px solid black;
}
box-shadowを利用する
border
ではなくbox-shadow
を利用してボーダーを表現するというもので、サンプルコードで10px
と指定しているspread radius
で指定した値がボーダーの太さとなります。
element:hover {
position: relative;
box-shadow: 0 0 0 10px black;
}
疑似要素を利用する(内側にボーダー表示)
上2つはいずれも外側にボーダーを表示させるものでしたが、内側に表示させたいときは下記のように疑似要素を利用するという方法があります。
また、このサンプルコードの場合はborder
を利用していますがbox-shadow
を利用して実装することも可能で、その場合はbox-shadow: 0 0 0 10px black inset;
のようにinset
を付けることで実装できます。
element:hover {
position: relative;
}
element:hover::after {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
content: '';
border: 10px solid black;
}
画像を円形表示
イメージのように画像を円形に表示したい場合、画像または括っている要素のアスペクト比が1:1の正方形であれば下記を記述することで簡単に円形表示できます。
element {
border-radius: 50%;
}
ちなみに、画像が正方形でないけどこのように円形表示したいという場合は、img
にobject-fit
を使った見栄え調整と組み合わせたり、position
やoverflow
などを使った位置調整と組み合わせることで可能です。
バランス良く角丸を指定する
角丸が指定された要素内にさらに角丸指定された要素を配置するといったように角丸指定されたものを入れ子で使用する際に、バランス良く角丸指定を行う方法です。
例えば<div class="parent"><div class="child"></div></div>
のようなHTMLがあり、どちらの要素も角丸にしたいという場合、単純にborder-radius
で同じ値を指定するだけではバランスがとれた綺麗な角丸にはなりません。
このような場合は上のイメージにあるように**「親要素で指定した角丸 - 親要素と子要素の間の余白」の値を子要素のborder-radius
に指定すると綺麗な見栄えになります。
親要素と子要素の間の余白というのは、親要素に対してpadding
やborder
を指定している場合などにできる部分を指し、例えば親要素(.parent
)にborder-radius
とpadding
が指定されていた場合、その中にある子要素(.childe
)のborder-radius
には下記のように「親要素のborder-radius - 親要素のpadding」**の値を指定します。
.parent {
padding: 10px;
background: black;
border-radius: 20px;
}
.child {
background: white;
border-radius: 10px; /* 20px - 10px */
}
border-radiusで異なる半径を指定
border-radius
を利用する場面で多いのは要素の四隅を少しだけ角丸にしたいときだとか先ほど紹介したように円形にしたいときだと思いますが、それぞれ異なる半径を指定することで上のデモにあるような少し歪んだ見栄えにするということもできます。
このデモの場合は左がa
要素で右がdiv
要素となっており、それぞれ下記のような値を指定しています。
a {
border-radius: .4em 2em .5em 3em/3em .5em 2em .5em;
}
div {
border-radius: 60% 40% 50% 30%/50% 70% 40% 70%;
}
カーソルデザインを変更する
ボタンならばクリックできる、入力欄なら入力できるかといったように、パッと見でどのようなものなのかを認識できるようなデザインにするのがもちろん好ましいですが、ユーザーによっては見た目で判断できなかった場合に次の判断基準としてそれらをホバーなどしてカーソルデザインが変わるかどうか見ているという人もいると思います。
ボタンであればポインターのカーソルに、入力できないのであればそれを伝えるカーソルというように、そういった場合も考慮して任意のカーソルデザインを指定したい場合はCSSで下記のように記述します。
button {
cursor: pointer;
}
input[type="text"]:disabled {
cursor: not-allowed;
}
上記記述後にブラウザで表示を確認すると、ボタン要素はカーソルがポインターに変更されてクリックできることがわかりやすくなり、disabled
が指定されて入力することができないinput type="text"
要素はカーソルが許可されていない旨を表すものに変更されます。
ここでは2種類の指定方法を紹介しましたがcursor
プロパティは他にも多数あり、その他の利用例としてはクリックして画像が拡大されるようなものであればcursor : zoom-in;
を、ドラッグで切り替えるのに対応したカルーセル要素などにcursor: ew-resize;
とかcursor: grab;
を指定したりしても良いかもしれません。
他にどのようなものが指定できるかや実際にどのような表示なのか確認したいときは「CSS Cursor」というサイトが一覧化されていて便利です。
ちなみに、個人的に一番多用する機会があるcursor: pointer;
をいちいち指定するのが面倒なときは、案件などにもよりますがリセットスタイルの一部として下記のような形でまとめて指定しておくこともあります。
a[href],
label[for],
button,
input[type="button"],
input[type="submit"],
input[type="reset"],
input[type="image"],
input[type="radio"],
input[type="checkbox"],
select {
cursor: pointer;
}
選択を制御する
user-select
というプロパティを利用することで選択制御が可能になります。
ただし、ブラウザによっては完全に無効化できるというわけではなく、例えば前後でuser-select
が指定されていない要素がありそれを選択する流れで該当箇所を選択した場合やcommand + Aを使った全選択をした場合などは、その箇所にuser-select: none;
を指定してたとしても選択されてしまったりテキストのコピーなどもできます。
element {
user-select: none;
}
クリック・タッチイベントを制御する
pointer-events
というプロパティを利用することで、例えば何らかの理由で特定の要素を選択できないようにしたいとかa要素のリンク指定を無効化させたいといったことをCSSだけで実装することができます。
ただし、IEとEdgeの場合は適用したい要素がblock
またはinline-block
になっている必要があるので注意してください。
element {
pointer-events: none;
}
いろいろな使い方がありますが、具体的な使用例としては下記のようなものがあります。
iPhoneやiPadなどでリンク内にある画像のみハイライトされるのを無効化する
わかりづらいかもしれませんが、リンク内にある画像のみがハイライト(選択)されるのを防ぐ方法で、例として下記のようなa
要素内にイメージとテキストが含まれているHTMLがあったとします。
<a href="#">
<img src="img.png">
<p>Lorem ipsum dolor sit amet ...</p>
</a>
上記のようなHTMLで特にスマートフォンやタブレット向けのサイトを作成する際は、リンクをタップしやすくするなどの理由でa
要素にCSSでdisplay: block;
やdisplay: inline-block;
を指定することが多いと思います。
その際にa
要素の中身がテキストのみであれば、例えばiPhoneやiPadではデフォルトだと薄いグレーもしくは-webkit-tap-highlight-color
で指定したカラーがそのリンク領域全体をタップされたということがわかりやすいようにハイライト表示されると思うのですが、上記HTMLのようにa
要素の中にimg
を使った画像がある場合は、その画像にタップすると・リンク領域全体ではなく画像だけがハイライトされるような見栄えになってしまいます。(人によっては気にならないようなことだとは思いますが...)
以前はその回避方法として画像を背景画像にして表示させるなどして対応していたのですが、下記のようにimg
にpointer-events
を指定することで、そのままimg
を利用していても画像のみがハイライトされるのを防ぐことができます。
a img {
pointer-events: none;
}
パンくずで現在地のリンクを無効化
バッドノウハウ感ある方法ではありますが、例として下記のようにすべてにhref
が指定されたa
要素が使用されているパンくず用のHTMLがあったとします。
<div class="breadcrumb">
<span><a href="http://example.com/">Home</a></span>
<span><a href="http://example.com/category/">Category</a></span>
<span><a href="http://example.com/page.html">Page Title</a></span>
</div>
上記のようなHTMLを使用している際、例えば現在見ているページ(サンプルコードの場合は3つ目のspan
要素)はリンク不要というときは普通にa要素を取っ払ってしまえばいいのですが、a
要素に対してデフォルトスタイルとしていろいろと指定していてそれらはそのまま利用したいときや何らかの理由でHTMLを変更できないといったようなときは、下記のようにpointer-events
を利用することでHTMLは変更せずにリンクのみ無効にするといったことができます。
.breadcrumb span,
.breadcrumb a {
display: inline-block;
}
.breadcrumb span:not(:first-child)::before {
content: '>';
margin: 0 .5em;
}
.breadcrumb span:last-child a {
pointer-events: none;
color: #000;
text-decoration: none;
cursor: default;
}
現在地はほとんどの場合パンくず表示の最後にあると思うのでその指定には:last-child
を利用しており、そこへpointer-events: none;
を指定しています。
また、このような使い方をする場合は、サンプルコードにもあるようにリンクが無効化されているのをわかりやすくなるようtext-decoration: none;
やcursor: default;
といったスタイルも併せて指定しておくと良いかと思います。
その他のCSS Snippetsに関しては下記ページから確認できます。