CSS Snippets #3

Tips

CSS Snippets #3

CSSで「〇〇したい」とか「これどうするんだっけ...」というときに使えるものや地味だけど覚えておくと便利だと思う簡易的なスニペットを紹介します。
以前であれば画像やJavaScriptを用いなければいけなかったものがCSSのみで表現できたり、上手く使えばよりシンプル且つ効率良く記述するのに役立つものもあるので、特にこれからCSSを学びたいという人や学び始めたばかりでもう少しレベルアップしたいという人は是非試してみてください。

※以下で紹介するものは基本的にプレフィックスを省略しています。

※デモが用意されていないものについては、自身で簡単な環境を作成して試してもらうか「CodePen」や「JSFiddle」などを利用して実際の動きを確認してください。

CSS Snippets #3 目次

  1. borderで矢印をつくる #1
  2. borderで矢印をつくる #2
  3. 要素に複数のボーダーを表示する
  4. ホバー時にレイアウトを崩さずに画像や要素にボーダーを表示する
  5. 画像を円形表示
  6. バランス良く角丸を指定する
  7. border-radiusで異なる半径を指定
  8. カーソルデザインを変更する
  9. 選択を制御する
  10. クリック・タッチイベントを制御する

1. borderで矢印をつくる #1

See the Pen CSS arrow #1 by Naoya (@nxworld) on CodePen.

※HTMLは<span class="arrow arrow-top"></span>のようなものを使用している想定です。
また、ここではspanを利用する想定にしていますが、ちょっと変更すれば疑似要素での表示も容易にできます。

borderを利用して矢印を作る方法で、基本となるスタイルに加えて例えば上向きの矢印であればborder-bottomを、右向きの矢印であればborder-leftというように表示させたい向きとは逆の方向のborderにカラーを指定すれば実装することができます。
その際にすべてのborder-widthを一緒にせずに、デモにある.arrow-up-narrow.arrow-up-wideのように少し違いをつけることで幅広や幅狭の矢印にすることができます。
また、.arrow-top-left.arrow-top-rightのように2方向指定すれば斜めの矢印にすることができます。

CSS

/* 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;
}

目次へ

2. borderで矢印をつくる #2

See the Pen CSS arrow #2 by Naoya (@nxworld) on CodePen.

※HTMLは<span class="arrow arrow-top"></span>のようなものを使用している想定です。
また、ここではspanを利用する想定にしていますが、ちょっと変更すれば疑似要素での表示も容易にできます。

同じくborderを利用して矢印を作る方法ですがこちらは先ほどとは異なるタイプのもので、上で紹介したものはborder-colorを指定する方向を変更することによって矢印の向きを変えていましたが、こちらはborderの指定は変更せずにtransform: rotate();を使って向きを変えています。
また、こちらのタイプで幅広や幅狭な矢印を作成したい場合はtransform: skew();を利用し、値をマイナスにすれば幅狭に、プラスにすれば幅広に見せることができます。

斜め指定についても新たにスタイルを追加とかではなくtransform: rotate();で調整を行っており、上のデモではさらにtransform: skew();も加えてより斜め方向に向くようにしています。
ちなみに、ここではtransform: rotate();で回転をさせる形にしていますが、単純に左上ならborder-topborder-leftを、右下ならborder-rightborder-bottomという感じで指定して表示させることももちろんできます。

CSS

/* 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);
}

目次へ

3. 要素に複数のボーダーを表示する

CSSを使ってひとつの要素に対して複数のボーダーを表示させる方法を3パターン紹介します。
いずれも初期状態としてborder: 10px solid black;が指定されている要素があると想定し、そこへさらにボーダーを追加表示させていきます。

疑似要素を利用する

疑似要素を利用する方法で、下記のように記述することで初期状態に表示されているものを含めて最大3つ分のボーダーを表示させることができます。

CSS

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を併用できないという注意点がありますが、上で紹介した疑似要素を利用するものに比べたら非常にシンプルな記述でできます。

CSS

element {
  border: 10px solid black;
  outline: 10px solid red;
}

box-shadowを利用する

box-shadowを利用する方法で、下記サンプルコードの場合は初期状態のものを含めて4つ分のボーダーが表示された状態になります。
こちらはborder-radiusも併用可能ですし、シンプルな記述で数も追記しただけ表示することが可能なので、ここで紹介している方法の中では一番使いやすい実装方法だと思います。

CSS

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;
}

目次へ

4. ホバー時にレイアウトを崩さずに画像や要素にボーダーを表示する

See the Pen XeYNbR by Naoya (@nxworld) on CodePen.

特に隙間なく並べられた画像や要素があり、それらにホバー時にボーダーを表示させたいというとき、単純にelement:hover { border: 10px solid black; }などのように指定するとレイアウトが崩れたり表示がガタガタになってしまいます。(上記デモの「default」参照)
このように隙間なく並んだ要素があってhover時にレイアウトを崩さずボーダーを表示させたいときは下記のような方法で実装することができ、それぞれ実際の動きは上にあるデモで確認してください。

ネガティブマージンを利用する

ホバー時にborderを使用してボーダーを表示させますが、その際にborder-widthの値を引く形でネガティブマージンを併せて指定する方法です。

CSS

element:hover {
  position: relative;
  margin: -10px;
  border: 10px solid black;
}

box-shadowを利用する

borderではなくbox-shadowを利用してボーダーを表現するというもので、サンプルコードで10pxと指定しているspread radiusで指定した値がボーダーの太さとなります。

CSS

element:hover {
  position: relative;
  box-shadow: 0 0 0 10px black;
}

疑似要素を利用する(内側にボーダー表示)

上2つはいずれも外側にボーダーを表示させるものでしたが、内側に表示させたいときは下記のように疑似要素を利用するという方法があります。
また、このサンプルコードの場合はborderを利用していますがbox-shadowを利用して実装することも可能で、その場合はbox-shadow: 0 0 0 10px black inset;のようにinsetを付けることで実装できます。

CSS

element:hover {
  position: relative;
}
element:hover::after {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  content: '';
  border: 10px solid black;
}

目次へ

5. 画像を円形表示

画像を円形表示

このイメージのように画像を円形に表示したい場合、画像または括っている要素のアスペクト比が1:1の正方形であれば下記を記述することで簡単に円形表示できます。

CSS

element {
  border-radius: 50%;
}

ちなみに、画像が正方形でないけどこのように円形表示したいという場合は、imgobject-fitを使った見栄え調整と組み合わせたり、positionoverflowなどを使った位置調整と組み合わせることで可能です。

目次へ

6. バランス良く角丸を指定する

バランス良く角丸を指定する

角丸が指定された要素内にさらに角丸指定された要素を配置するといったように角丸指定されたものを入れ子で使用する際に、バランス良く角丸指定を行う方法です。

例えば<div class="parent"><div class="child"></div></div>のようなHTMLがあり、どちらの要素も角丸にしたいという場合、単純にborder-radiusで同じ値を指定するだけではバランスがとれた綺麗な角丸にはなりません。

このような場合は上のイメージにあるように「親要素で指定した角丸 - 親要素と子要素の間の余白」の値を子要素のborder-radiusに指定すると綺麗な見栄えになります。
親要素と子要素の間の余白というのは、親要素に対してpaddingborderを指定している場合などにできる部分を指し、例えば親要素(.parent)にborder-radiuspaddingが指定されていた場合、その中にある子要素(.childe)のborder-radiusには下記のように「親要素のborder-radius - 親要素のpadding」の値を指定します。

CSS

.parent {
  padding: 10px;
  background: black;
  border-radius: 20px;
}
.child {
  background: white;
  border-radius: 10px; /* 20px - 10px */
}

目次へ

7. border-radiusで異なる半径を指定

See the Pen border-radius example by Naoya (@nxworld) on CodePen.

border-radiusを利用する場面で多いのは要素の四隅を少しだけ角丸にしたいときだとか先ほど紹介したように円形にしたいときだと思いますが、それぞれ異なる半径を指定することで上のデモにあるような少し歪んだ見栄えにするということもできます。
このデモの場合は左がaで右がdiv要素となっており、それぞれ下記のような値を指定しています。

CSS

a {
  border-radius: .4em 2em .5em 3em/3em .5em 2em .5em;
}
div {
  border-radius: 60% 40% 50% 30%/50% 70% 40% 70%;
}

目次へ

8. カーソルデザインを変更する

ボタンならばクリックできる、入力欄なら入力できるかといったように、パッと見でどのようなものなのかを認識できるようなデザインにするのがもちろん好ましいですが、ユーザーによっては見た目で判断できなかった場合に次の判断基準としてそれらをホバーなどしてカーソルデザインが変わるかどうか見ているという人もいると思います。
ボタンであればポインターのカーソルに、入力できないのであればそれを伝えるカーソルというように、そういった場合も考慮して任意のカーソルデザインを指定したい場合はCSSで下記のように記述します。

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;を指定したりしても良いかもしれません。

他にどのようなものが指定できるかや実際にどのような表示なのか確認したいときは以下のサイトが一覧化されていて便利です。

ちなみに、個人的に一番多用する機会があるcursor: pointer;をいちいち指定するのが面倒なときは、案件などにもよりますがリセットスタイルの一部として下記のような形でまとめて指定しておくこともあります。

CSS

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;
}

目次へ

9. 選択を制御する

user-selectというプロパティを利用することで選択制御が可能になります。
ただし、ブラウザによっては完全に無効化できるというわけではなく、例えば前後でuser-selectが指定されていない要素がありそれを選択する流れで該当箇所を選択した場合やcommand + Aを使った全選択をした場合などは、その箇所にuser-select: none;を指定してたとしても選択されてしまったり、テキストのコピーなどもできます。

CSS

element {
  user-select: none;
}

目次へ

10. クリック・タッチイベントを制御する

pointer-eventsというプロパティを利用することで、例えば何らかの理由で特定の要素を選択できないようにしたいとかa要素のリンク指定を無効化させたいといったことをCSSだけで実装することができます。

CSS

element {
  pointer-events: none;
}

※IEとEdgeで使用したい場合は、適用したい要素がblockまたはinline-blockになっている必要があるので注意してください。

いろいろな使い方がありますが、具体的な使用例としては下記のようなものがあります。

iPhoneやiPadなどでリンク内にある画像のみハイライトされるのを無効化する

iPhoneやiPadなどでリンク内にある画像のみハイライトされるのを無効化する

わかりづらいかもしれませんが、リンク内にある画像のみがハイライト(選択)されるのを防ぐ方法です。
例として下記のようなa要素内にイメージとテキストが含まれているHTMLがあったとします。

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を使った画像がある場合は、その画像にタップすると・リンク領域全体ではなく画像だけがハイライトされるような見栄えになってしまいます。(人によっては気にならないようなことだとは思いますが...)
以前はその回避方法として画像を背景画像にして表示させるなどして対応していたのですが、下記のようにimgpointer-eventsを指定することで、そのままimgを利用していても画像のみがハイライトされるのを防ぐことができます。

CSS

a img {
  pointer-events: none;
}

パンくずで現在地のリンクを無効化

バッドノウハウ感ある方法ではありますが、例として下記のようにすべてにhrefが指定されたa要素が使用されているパンくず用のHTMLがあったとします。

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は変更せずにリンクのみ無効にするといったことができます。

CSS

.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に関しては下記ページにまとめているので、興味ある方はこちらもご覧ください。

Close the search window,
please press close button or esc key.