2013/01/25

[css]折り返しリボンの作り方を解説するよ

カテゴリー:
タグ:

colissさんのところで、心惹かれる記事を見つけました。

[CSS]h1一つだけでこんなにかわいいレトロ風リボンが実装できるスタイルシート

レトロ風リボン

この折り返しリボン、どうなってるんだろうと思って、仕組みを調べてみました。使われている小技を2つ紹介してから、リボンの本質的な構造を説明したいと思います。

斜線の出し方

リボンを描いていく途中で、斜線が出てきます。まずはこの部分をどうやって作るかをみていきます。

使うのは、borderです。上下左右それぞれに適当に色を付けてみます。わかりやすいように、普段は使わないような色の組み合わせで塗ってみます。

20130125-2

body {
  background: #B1E3E2;
}
h1{
  border-top: 30px solid #999;
  border-right: 30px solid #990;
  border-bottom: 30px solid #909;
  border-left: 30px solid #099;
  width: 100px;
}

こうすると、borderの上下左右の境目にそれぞれ斜めの線ができているのがわかります。これをいかして、上下は同じ色、左右は背景と同じ色に塗り直してみると、次のようになります。cssは変更したところだけ書いています。

20130125-3

h1{
  border-top: 30px solid #fff;
  border-right: 30px solid transparent;
  border-bottom: 30px solid #fff;
  border-left: 30px solid transparent;
}

これだけでもちょっとリボンっぽい感じになりますね。このままだと、h1タグ内に文字を書くと大変なことになってしまいますが。

短い線の出し方

上のリボンでは、「boxよりも短い線を出す」ということをしています。完成図を見てもどこで使っているかわかりにくいですね。どう使っているかは後で解説します。

短い線を出すには、box-shadowを使います。box-shadowは、4つの数字を指定して使います。順番によって、次のように意味が定められています。

  1. 水平方向へのずらし幅
  2. 垂直方向へのずらし幅
  3. ぼかし距離(省略可能)
  4. ひろがり距離(省略可能)

ぼかし距離を0にすると、はっきりとした影ができます。ひろがり距離にマイナスの値を指定すると、影が縮小します。この性質を使って、次のように設定すると、短い線を描くことができます。

20130125-4

h1{
  height: 50px;
  width: 100px;
  background-color: #fff;
  box-shadow: 0 35px 0 -15px #999;
}

これらの技を応用して、折り返しリボンを作っていきたいと思います。

折り返しリボンの作り方

一番はじめに紹介したリボンは、大きく分けて3つの部品から成り立っています。リボンの手前の部分、折り返した時に見える裏の部分、奥の部分です。それぞれ、h1タグ、:after、:before 疑似要素が対応しています。これらの部品がどう組み合わされているかをしめしたものが、下の絵です。
20130125-5

左が完成品で、右がそれを分解したものです。右は見やすいように背景を変えてみました。h1タグの部分には、下に背景と同じ色の線が隠れていたのですね。

それでは、上で書いた小技を用いて、cssを書いていきましょう。

リボンの一番手前の部分

リボンの一番手前に見えている部分を作ります。h1タグの部分です。とりあえず、htmlは次のようにします。ほとんど何も書いてませんw。

<h1>sample ribbon</h1>

cssは、上で書いたbox-shadowの小技を使って、下のようにします。

body {
  background: #EDDACC;
  color: #8699A0;
  font-size: 12px;
}
h1{
  display: inline-block;
  position: relative;
  padding: 10px 15px;
  height: 30px;
  background-color: #fff;
  box-shadow: 0 0 30px 0 rgba(0, 0, 0, 0.4), 
  0 30px 0 -15px #B1E3E2;
}

20130125-6

このように表示されているはずです。

h1タグをinline-block表示に変えています。また、box-shadowに普通の影もつけています。下のリボンと重なった部分の境界が見えるようにするためです。これで、リボンが立体的に見えます。2つ目のbox-shadowで上で書いた小技を使っています。

bodyの背景は、box-shadowが見やすいように別の色に変えていますが、最終的にあとで別の値に設定します。positionは、後で設定する疑似要素の場所を指定するために必要になります。

リボンの裏の部分

リボンを折り返した時に見える、リボンの裏の部分を作ります。:after 疑似要素の部分です。上で書いたborderの小技を使います。

h1:after{
  content: '';
  position: absolute;
  top: 100%;
  left: 0;
  z-index: -1;
  box-sizing: border-box;
  width: 100%;
  border-top: 15px solid #99acb2;
  border-left: 15px solid transparent;
  border-right: 15px solid transparent;
}

20130125-7

topとleftの設定は、h1の真下に:after 疑似要素を追加するということをあらわしています。後半のborderの設定が、上で書いた一つ目の小技に対応しています。topにだけ色を付けて、leftとrightは透明のボーダーを設定しています。

h1のbox-shadowにかくれて、:after のボーダーは左右に少しだけ表示されるようになります。h1のbox-shadowの幅を-15pxにしたことと、ここでborderの幅を15pxにしたことによって、リボンの裏の部分がきれいな直角二等辺三角形になります。

リボンの奥の部分

最後に、折り返したときにできる、リボンの奥の部分を作ります。:before 疑似要素の部分です。ここでも、上で書いたborderの小技を使います。

h1:before{
  content: '';
  position: absolute;
  top: 15px;
  left: -15%;
  z-index: -1;
  box-sizing: border-box;
  height:100%;
  width: 130%;
  border-top: 25px solid #fff;
  border-right: 25px solid transparent;
  border-bottom: 25px solid #fff;
  border-left: 25px solid transparent;
}

20130125-8

後半のborderの設定は、上で書いたborderの小技そのままですね。h1は高さ30pxで、上下のpaddingを10pxと設定していたので、高さは50pxです。:before もheightを100%にしているので、50pxです。なので、上下左右のborder幅は25pxにすればOKですね。

topを15pxにしているのは、リボンの裏の部分を15pxで作っていたことと連動しています。widthを130%、leftを-15%に設定しているため、りぼんが左右対称になります。

box-sizingをborder-boxと設定していますが、これは、boxの幅や高さをborderを含めた値で計算するという設定です。

さて、最後に、背景を変えてみましょう。

20130125-9

body {
  background: #B1E3E2;
}

背景の色と、h1の真下にできているbox-shadowの色を合わせています。色が同化することで、折り返されたリボンがきれいに表示されます。冒頭で紹介した折り返しリボンはこうして作られていたんですね。

前の記事:
次の記事: