CSSでグラデーション付きの矢印を描く

CSSで矢印を描くのは一般的だと思うが、それにグラデーション付けられないかと聞かれた。

試してみたらうまくいったのでメモ。

実装方法

borderで描いた矢印の上に、linear-gradientのグラデーションを重ねることで実装できた。

サンプルコード

before疑似要素で矢印、after疑似要素でグラデーションをつける。手抜き。

とりあえず、使用頻度の高そうな下矢印と右矢印のみ。

HTML

<div class="wrapper">
  <p>up</p>
  <div class="down-arrow"></div>
  <p>down</p>
</div>

<div class="wrapper">
  <p>left<span class="right-arrow"></span>right</p>
</div>

CSS

下矢印は正三角形、右矢印は底辺 = 高さの二等辺三角形にした。

何度も同じ値が出てくるため、Sassなどのプリプロセッサの変数を使ったほうがいい。

ここではCSSカスタムプロパティを使っているため、IEでは動かないが、値を展開すればIE10でも動作する。

:root {
  --down-arrow-height: 40px;
  --down-arrow-half-width: calc(var(--down-arrow-height) / 2 * 1.73205081);
  --down-arrow-margin: 10px;

  --right-arrow-width: 30px;
  --right-arrow-half-height: calc(var(--right-arrow-width) / 2);
  --right-arrow-margin: 10px;
}

.wrapper {
  background: #fff; /* 背景色をグラデーションと合わせる */
  font-size: 24px;
  text-align: center;
}

.down-arrow {
  position: relative;
  height: calc(var(--down-arrow-height) + var(--down-arrow-margin) * 2);
}

.down-arrow::before,
.down-arrow::after {
  content: '';
  position: absolute;
  top: 10px;
  left: calc(50% - var(--down-arrow-half-width)); /* 中央に配置 */
}

.down-arrow::before {
  width: 0;
  height: 0;
  border-top: var(--down-arrow-height) solid #096;
  border-right: var(--down-arrow-half-width) solid transparent;
  border-left: var(--down-arrow-half-width) solid transparent;
}

.down-arrow::after {
  width: calc(var(--down-arrow-half-width) * 2);
  height: var(--down-arrow-height);
  background: linear-gradient(
      to bottom,
      rgba(255, 255, 255, 1) 0%,
      rgba(255, 255, 255, 0) 100%);
}

.right-arrow {
  display: inline-block;
  position: relative;
  vertical-align: middle; /* こうしておくと中央に矢印の上端が揃う模様 */
  width: calc(var(--right-arrow-width) + var(--right-arrow-margin) * 2);
}

.right-arrow::before,
.right-arrow::after {
  content: '';
  position: absolute;
  top: calc(var(--right-arrow-half-height) * -1); /* 矢印の高さの半分ずらす */
  left: calc(50% - (var(--right-arrow-width) / 2)); /* 中央に配置 */
}

.right-arrow::before {
  width: 0;
  height: 0;
  border-top: var(--right-arrow-half-height) solid transparent;
  border-bottom: var(--right-arrow-half-height) solid transparent;
  border-left: var(--right-arrow-width) solid #609;
}

.right-arrow::after {
  width: var(--right-arrow-width);
  height: calc(var(--right-arrow-half-height) * 2);
  background: linear-gradient(
      to right,
      rgba(255, 255, 255, 1) 0%,
      rgba(255, 255, 255, 0) 100%);
}

実行結果

f:id:hepokon365:20190916131041p:plain

f:id:hepokon365:20190916131117p:plain

振り返り

できた後に「CSS 矢印 グラデーション」で検索してみたら、2015年にやってる人がいた。

waka.sadist.jp

先に調べとけばよかった...