CSSでリボン風の見出しを作る手順についての、超初心者向けメモ書き

ribbon-photo
photo credit: tanakawho via photopin cc
Update

すでに多くの方が解説されている内容ですが…CSS超初心者にとっては、サンプルコードをカスタマイズするだけでも一苦労なものです。なので、自分が難しく感じた点やつまづいた点を細かくおさらいしながら、手順をまとめておくことにしました。

すっごく長々と書いてしまったので、目次をつけます。リボンの作り方は後半です。

positionプロパティのおさらい

リボン風の見出しを作る前に、CSSのpositionプロパティについておさらいします。

positionプロパティを使って自由に配置

ほんとうに当たり前のことなのですが、ふつうはHTMLファイルに書いたものって、書いた順に上から下へ配置されますよね。

<img src=".../donuts.jpg">
<p class="caption">Donuts!</p>

写真<img>が上、文字<p>が下に配置されています。

SnapCrab NoName 2013 4 24 17 40 53 No 00

でも、positionプロパティを使うと、HTMLで書いた順序とは関係なく、上下左右の位置を自由に決めることができて、たとえばこんなふうに写真の上に文字を乗せたりすることもできます。

見づらいですが、写真の左上に文字を乗せました。

SnapCrab NoName 2013 4 24 17 39 14 No 00

自由に位置を決めたい要素にposition:absolute;

文字を本来の位置より上に持っていくために、<p>要素にposition:absolute;を指定します。

.caption{
position:absolute;

/*縦の位置*/
top:0;
/*横の位置*/
left:0;
}

こう書くと、文字がブラウザの左上端に移動します。

SnapCrab NoName 2013 4 24 18 2 10 No 00

ちょっとずらしてみます。

.caption{
position:absolute;

/*上から50pxずらす*/
top:50px;
/*左端から30%ずらす*/
left:30%;
}
SnapCrab NoName 2013 4 24 18 6 3 No 00

こんなふうに値を調整していけば、写真の上に文字を乗せることもできるのですが…けっこう調整が大変です。

位置の基準にしたい要素にposition:relative;

そこで、文字の位置の基準をブラウザの左上端ではなく、写真の左上端にするためにposition:relative;を使います。ですが、わたしはここで、ずっとつまづいていました…。

これはまちがいの例です。

/*写真の左上端を基準にしたい!*/
img{
position:relative;
}

/*写真の左上端から20pxのところに配置したい!*/
.caption{
position:absolute;
top:20px;
left:20px;
}

上のように書くと、こうなります。

SnapCrab NoName 2013 4 24 18 15 0 No 00

ちゃんとposition:relative;って書いたのに、やっぱり写真じゃなくてブラウザの左上端が基準になったままじゃん!としばらく悩んでいました。。。肝心な説明を読み落としていたのでした!

absolute: 絶対位置への配置となります。親ボックスにpositionプロパティのstatic以外の値が指定されている場合には、親ボックスの左上が基準位置となります。親ボックスにpositionプロパティのstatic以外の値が指定されていない場合には、ウィンドウ全体の左上が基準位置となります。

さっきposition:relative;を指定した写真(img要素)は、文字(p要素)の親ボックスじゃないですね。

そこで、このように、写真と文字をdiv要素で包みました(これが親ボックスになる)。

<div class="wrap">
    <img src="donuts.jpg">
    <p class="caption">Donuts!</p>
</div>

そして、親ボックスとなるdiv要素に、position:relative;を指定します。

/*親ボックスの左上端を基準にする!*/
.wrap{
position: relative;
}

/*親ボックスの左上端から20pxのところに配置!*/
.caption{
position:absolute;
top:20px;
left:20px;
}

これでできました!

SnapCrab NoName 2013 4 24 17 39 14 No 00

ここまでのまとめ

position:relative;position:absolute;を使って配置するときには、

  • 位置を自由に決めたい要素にposition:absolute;を指定する。topやleft(rightやbottomも使えます)で位置を調整する。
  • 位置の基準にしたい親ボックス(親要素)position:relative;を指定する。

before/after擬似要素のおさらい

リボン風の見出しを作る前に、CSSのbefore/after擬似要素についておさらいします。

CSSでリボンをつくる手順のおおまかな流れ

さて、CSSでリボンをつくるときには、positionプロパティと、before/after擬似要素を使います。手順をざっくりとまとめてみますね。

  1. 背景色などを指定して、リボンの土台をつくる

    div要素ではなく見出し(h2など)でももちろん大丈夫です

    <div class="ex-1">Ribbon Sample</div>
    
    .ex-1{
    background-color: lightcoral;
    color: indianred;
    /*その他、widthやmarginなどいろいろ*/
    }
    
    SnapCrab NoName 2013 4 25 11 44 55 No 00
  2. リボンの土台にposition:relative;を指定する
    .ex-1{
    background-color: lightcoral;
    color: indianred;
    /*その他、widthやmarginなどいろいろ*/
    
    /*位置の基準にする!*/
    position: relative;
    }
    
  3. before/after擬似要素で三角形をつくり、position:absolute;を指定する
    /*----左側の三角形----*/
    .ex-1:before{
    /*リボンを基準に動かす*/
    position: absolute;
    top: 0;
    left:0;
    
    /*三角形をつくるための記述いろいろ(後述!)*/
    }
    
    /*----右側の三角形----*/
    .ex-1:after{
    /*リボンを基準に動かす*/
    position: absolute;
    top: 0;
    right:0;
    
    /*三角形をつくるための記述いろいろ(後述!)*/
    }
    
    SnapCrab NoName 2013 4 25 11 55 44 No 00
  4. 位置を調整する!
    /*----左側の三角形----*/
    .ex-1:before{
    /*リボンを基準に動かす*/
    position: absolute;
    top: 50%;
    left:-25px;
    
    /*三角形をつくるための記述いろいろ*/
    
    /*三角形がはみ出さないように*/
    z-index:-1;
    }
    
    /*----右側の三角形----*/
    .ex-1:after{
    /*リボンを基準に動かす*/
    position: absolute;
    top: 50%;
    right:-25px;
    
    /*三角形をつくるための記述いろいろ*/
    
    /*三角形がはみ出さないように*/
    z-index:-1;
    }
    
    SnapCrab NoName 2013 4 25 11 45 35 No 00

before/after擬似要素って完全に前後じゃなかった

ところで、どうして三角形がブラウザの左上端にとんでいかずに、ちゃんとリボンの土台付近に配置されるのでしょう?先ほどのように親ボックス(親要素)position:relative;と書いていないのに…。って思ったのですが、これはちょっと試してみたらすぐにわかりました。

div要素と、それに対するbefore/after擬似要素に背景色をつけてみます。

<div class="sample">Sample</div>
.sample{
background-color: lightcoral;
}

.sample:before{
background-color: orange;
content: "Before";
}

.sample:after{
background-color: purple;
content: "After";
}
SnapCrab NoName 2013 4 25 12 25 19 No 00

このように、before/after擬似要素って、元の要素に包まれている感じなのですね。

こういう位置関係なのかと思っていました

SnapCrab NoName 2013 4 25 12 32 35 No 00

元の要素をbefore/after擬似要素の親ボックス(親要素)のようなものだと考えていいのかな、と理解しました。

CSSで見出し(h2)をリボン風にする!

見出し(h2)をこんなふうにリボン風にしてみます!

SnapCrab NoName 2013 4 25 13 3 30 No 00

リボンの大元をつくります

HTMLはこれだけです。

<div class="content">
    <h2 class="ex-1">Ribbon Sample</h2>
</div>

リボンを乗せている白いところは、幅300pxということにします。

/*----リボンを乗せている白いところ----*/
.content{
background-color: white;
width:300px;
height: 300px;
padding-top: 50px;
}

それではまず、リボンの大元をつくります。

/*----リボン----*/
.ex-1{
/*リボンの色と文字の色*/
background-color: lightcoral;
color: indianred;

/*横に15pxずつはみ出すようにする*/
margin-left: -15px;
margin-right: -15px;

/*リボンの幅。
リボンを乗せる部分(300px)に、左右15pxずつのmarginを足したもの*/
width: 330px;

/*リボンの高さ*/
line-height:  50px;

/*あとでつくる三角形の位置の基準になるので*/
position: relative;
}
content and ribbon base

リボンの巻き込み部分の三角形をつくります!まずは左側。

before/after擬似要素を、左右の巻き込み部分の三角形にします。borderプロパティを使って三角形を描きます。

/*----リボンの左側の巻き込み部分----*/
.ex-1:before{
/*あとで位置を調整するのでこの3つを書いておく*/
position: absolute;
top:0;
left: 0;

/*ここには文字を入れないので、" "の中は無し*/
content: "";

/*これが三角形*/
border: 25px solid transparent;
border-right-color: indianred ;
}

こうなります。

css ribbon before

三角形が描かれる仕組み!

ここでちょっと、borderで三角形が描かれるまでの仕組みをメモしておきます。

borderプロパティというと、いつもはこんなふうに使いますよね。先ほどの三角形の記述、後半を書き換えてみます。

/*----リボンの左側の巻き込み部分----*/
.ex-1:before{
/*あとで位置を調整するのでこの3つを書いておく*/
position: absolute;
top:0;
left: 0;

/*----ここから変更----*/
/*★わかりやすいように、文字を入れてみます。*/
content: "Border-Sample";

/*★いつものborderの使い方の例*/
border: 1px solid indianred;
}

文字を1pxのボーダーで囲んでいるだけです。見づらいので下のリボンはいったん消します。

css border sample

このボーダーをおもいきり太くして、色を変えてみます。

border-left: 50px solid lightgray;
border-top: 50px solid orange;
border-bottom: 50px solid deepskyblue;
border-right:50px solid indianred;
}

こうなります。

css border 50px sample

borderって、太くすると台形みたくなるのですね。

次に、先ほど入れたcontent内の文字をなくします。

content: "";

contentの幅がなくなって、ボーダーが4つの三角形のようになりました。

css border triangle sample

リボンの左側に使う三角形だけ残して、他の3つのborderの色を透明にします。

border-left: 50px solid transparent;
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-right:50px solid indianred;
}

三角形ができました!

css border right triangle sample

リボンを戻して見てみます。

css border right triangle sample and ribbon

三角形の大きさはお好みでよいのですが、わたしは調整がしやすいよう、リボンの高さとぴったりになるようにしました。

さっき、リボンの高さを50pxにしたので、

.ex-1{
/*いろいろ省略*/

/*リボンの高さ*/
line-height:  50px;
}

borderは半分の25pxにすればぴったりになります。

border: 25px solid transparent;
border-right-color: indianred;

これで左側の巻き込み部分の三角形ができあがりです!

css ribbon before

右側の三角形もつくります

左側とほとんど同じです。

/*----リボンの右側の巻き込み部分----*/
.ex-1:after{
/*あとで位置を調整するのでこの3つを書いておく*/
position: absolute;
top:0;
right: 0; /*ここがちがう*/

content: "";

border: 25px solid transparent;
border-left-color: indianred ; /*ここがちがう*/
}

両側の三角形が完成です。

css ribbon before after

位置の調整

これから三角形の位置を調整してリボンの巻き込み部分を仕上げます。

/*----リボンの左側の巻き込み部分----*/
.ex-1:before{
position: absolute;

/*三角形の上半分がリボンに隠れるように*/
top:50%;

/*ちょうどいい位置に調整*/
left:-25px; 

content: "";
border: 25px solid transparent;
border-right-color: indianred ; 
}

/*----リボンの右側の巻き込み部分----*/
.ex-1:after{
position: absolute;

/*三角形の上半分がリボンに隠れるように*/
top:50%;

/*ちょうどいい位置に調整*/
right: -25px;

content: "";
border: 25px solid transparent;
border-left-color: indianred ;
}

あとちょっと!

css ribbon before after 2

最後に、リボンの上に三角形が表示されてしまっていますので、before/afterの両方にz-index:-1;を指定します。

css ribbon before after 3

あとはお好みで角を丸くしたり、背景色を工夫したりして、完成です!

SnapCrab NoName 2013 4 25 13 3 30 No 00

完成形のサンプルコード

最後に、上の画像のコードを載せておきます(ベンダープレフィックス全部はかいていません)。不適切なところがあったら教えていただけるととっても嬉しいです。

HTML

<div class="content">
    <h2 class="ex-1">Ribbon Sample</h2>
</div>

CSS

/*----リボンを乗せている白いところ----*/
.content{
background-color: white;
height: 300px;
width:300px;
padding-top: 50px;
}

/*----リボン----*/
.ex-1{
position: relative;

/*リボンの色*/
background-color: lightcoral;/*グラデーションが表示されないブラウザ用*/
background: -webkit-gradient(linear,left top, left bottom,from(#f29c96), to(#f08080));/*古いSafariなど用*/
background: -webkit-linear-gradient(#f29c96, #f08080);/*Safari、Chrome用*/
background: -moz-linear-gradient(#f29c96, #f08080);/*Firefox用*/
background: -o-linear-gradient(#f29c96, #f08080);/*Opera用*/
background: linear-gradient(#f29c96, #f08080); /*標準*/

/*文字*/
color: indianred;
text-align: center;
text-shadow:0 1px 0 rgba(255,255,255,0.3);
-webkit-text-shadow:0 1px 0 rgba(255,255,255,0.3);

/*リボンの幅と高さ*/
width: 330px;
line-height:  50px;

/*はみ出る部分*/
margin-left: -15px;
margin-right: -15px;

/*上側だけちょこっと角丸*/
border-radius:2px 2px 0 0;
-webkit-border-radius:2px 2px 0 0;

/*リボンが少し浮いて見えるようにうっすらとシャドウ*/
box-shadow:0 10px 30px -8px rgba(0,0,0,0.2); 
-webkit-box-shadow:0 10px 30px -8px rgba(0,0,0,0.2); 
}

.ex-1:before{
position: absolute;
top:50%;
left:-25px;
content: "";
border: 25px solid transparent;
border-right-color: indianred ;
z-index: -1;
}

.ex-1:after{
position: absolute;
top:50%;
right:-25px;
content: "";
border: 25px solid transparent;
border-left-color: indianred ;
z-index: -1;
}