こんにちは、うっちーです。
この記事はLife is Tech! Tokai Mentors Advent Calendar 2018の12日目です。
今回はCSSの記事になります。
作るもの
今回は雑誌とかでたまに見かける、枠からはみ出た部分の文字色が変わっているデザインを作っていきます。
言葉では伝わらないと思うのですが下のようなデザインです。
構想
上の画像はIllustratorで作ったのですが、まずはその手順を思い出してみます。
- 背景色を決める
- 下半分にボックスを置く
- 文字を配置し、複製する
- 文字の一つを下半分のボックスで切り抜く
これを単純にHTMLとCSSで再現すれば基本的にはできるはずです。
作ってみる
HTML + CSS (一番単純なパターン)
とりあえず何も考えずに作ってみます。
<div id="main-box">
<p>Think Better</p>
<div id="split-box">
<p>Think Better</p>
</div>
</div>
#main-box {
width: 500px;
height: 500px;
background: #E1C0B6;
position: relative;
margin: 0;
padding: 0;
}
#split-box {
width: 100%;
height: 250px;
background: #EBEBC1;
position: absolute;
top: 50%;
overflow: hidden;
}
#main-box p {
position: absolute;
width: 100%;
text-align: center;
font-size: 40px;
font-weight: 600;
line-height: 40px;
margin: 0;
}
#main-box > p {
bottom: 230px;
color: #EBEBC1;
}
#split-box > p {
top: -20px;
color: #E1C0B6;
}
これでできました。
https://codepen.io/RiField/pen/oJXxEm
解説
なんのことはありません。
ただ単に2つの文字列がボックスからはみ出す量が同じになるようにline-height
の半分だけ中心からずらした位置にそれぞれ配置しました。そのうち下側の文字列の飛び出した部分を#split-box
のoverflow: hidden
で隠しただけです。
HTML + CSS (ちょっと改善)
1つ目の例は同じ文字列が2度出てくるというとてもきれいとは言い難いものでした。
次はこれを少し改善してみます。
<div id="main-box">
<p>Think Better</p>
<div id="split-box" data-text="Think Better">
</div>
</div>
#main-box {
width: 500px;
height: 500px;
background: #E1C0B6;
position: relative;
margin: 0;
padding: 0;
}
#split-box {
width: 100%;
height: 250px;
background: #EBEBC1;
position: absolute;
top: 50%;
overflow: hidden;
}
#main-box p,
#split-box::after {
position: absolute;
width: 100%;
text-align: center;
font-size: 40px;
font-weight: 600;
line-height: 40px;
margin: 0;
}
#main-box > p {
bottom: 230px;
color: #EBEBC1;
}
#split-box::after {
content: attr(data-text);
position: absolute;
width: 100%;
text-align: center;
left: 0;
top: -20px;
color: #E1C0B6;
}
これでも同様の結果が得られます。
https://codepen.io/RiField/pen/KbpzLX
解説
今回はdata-*
属性と::after
要素を利用してHTMLから連続していたpタグを取り除いてみました。
data-*
属性はCSSから格納した情報を取得することが可能なのでここにテキストを入れて、::after
要素で取得、表示を行っています。
※::before
要素も利用すると完全にpタグをなくすことができるのですが、アクセシビリティの観点から言うとどちらかは残すべき、ということで一つは残しています。
Do not store content that should be visible and accessible in data attributes, because assistive technology may not access them. In addition, search crawlers may not index data attributes' values.
Using data attributes | MDN
HTML + CSS + JS
上の例ではデザインが機能するためには2箇所の文字列を同じにしておく必要があります。
メンテナンスの面を考えるとこれはあまり良くない(かもしれま)せん。
どうせならjavascriptを使ってテキストを編集するだけでデザインが機能するようにしておきましょう。
<div id="main-box">
<p id="text">Think Better</p>
<div id="split-box">
</div>
</div>
#main-box {
width: 500px;
height: 500px;
background: #E1C0B6;
position: relative;
margin: 0;
padding: 0;
}
#split-box {
width: 100%;
height: 250px;
background: #EBEBC1;
position: absolute;
top: 50%;
overflow: hidden;
}
#main-box p,
#split-box::after {
position: absolute;
width: 100%;
text-align: center;
font-size: 40px;
font-weight: 600;
line-height: 40px;
margin: 0;
}
#main-box > p {
bottom: 230px;
color: #EBEBC1;
}
#split-box::after {
content: attr(data-text);
position: absolute;
width: 100%;
text-align: center;
left: 0;
top: -20px;
color: #E1C0B6;
}
window.addEventListener('DOMContentLoaded', function() {
text = document.getElementById("text").innerHTML;
document.getElementById("split-box").setAttribute("data-text",text);
})
これでいいでしょうか。
https://codepen.io/RiField/pen/ebNdyJ
解説
jsを追加した以外は基本的に変わっていません。
jsもinnerHTML
でテキストの内容を取得して、setAttribute
で#split-box
のdata-text
属性にその内容を渡しているだけです。
まとめ
CSSが少しトリッキーかもしれませんが、わかってしまえばやっていることは単純です。
今回のように簡単なデザインであればIllustratorで作る際のレイヤーなどの考え方を利用してWebもデザインしていくことができるはずです。
ぜひ楽しいWebライフを!