初めてのQiita投稿にチャレンジしてみました。
最近LPなどでよく見る斜めにカットされた背景を実装する機会があったのですが、レスポンシブで様々な画面に対応するところでいろいろ考えた結果、画面幅での条件分岐なしでシンプルに実装できたのでメモ。
急いでる人はコードとで、結局どこをいじればいいの?を見てください。
コード
HTML
<div class="outer">
<div class="inner">この中にコンテンツ</div>
</div>
CSS
.outer{
overflow: hidden;
padding: calc(100vw * 0.12) 0;
position: relative;
}
.outer:before{
background: blue;
content: '';
position: absolute;
transform-origin: center;
transform: rotate(6deg);
width: 200vw;
height: calc(100% - 0.11 * (0.11 * 50% + 50vw) * 2);
top: calc(0.11 * (0.11 * 50% + 50vw));
left: -50vw;
z-index: -1;
}
やっていること
概要
背景を付ける.outerクラスにbefore要素を付けて、そのbefore要素を回転・移動しています。その際、before要素を親要素と縦横中央にそろえてから要素の中心を軸に回転させることで画面幅が変わってもズレないようにしました。
他の記事でもやってるところの解説
CSSのみで背景を全体的に斜めにして傾斜をつける方法など、参考にさせていた記事でも使われていた手法をざっくり解説します。
overflow: hidden;
これはbefore要素の横幅を画面幅より大きくして回転させるため、画面から溢れたところを隠すためにつけています。
.outer{
position: relative;
}
.outer:before{
position: absolute;
}
position: absolute
をつけるとrelativeがついている親要素を基準に座標を指定することができます。
ここがポイント!calc()を使ってレスポンシブ対応
参考にさせていただいた記事でも.outer:before
の横幅を.outer
より広げ、縦幅を縮めて回転させることで斜めの背景を作っていました。しかし、レスポンシブで綺麗に見せるためにはどんな画面サイズでも.inner
が綺麗に.outer:before
要素の中に収まる必要があります。
イメージ的な説明
.inner
を綺麗に.outer:before
要素の中に収めるためには下図のようにbefore要素を動かして、さらに.outer
に適切なpadding
を付けてあげれば良さそうです
要素の中心を軸にして回転させる部分がこちら。
.outer:before{
transform-origin: center;
transform: rotate(6deg);
}
しかしここで大きな問題が発生します。上下方向にどれだけ縮めて移動すればよいか?ということです。
上下方向にどれだけ縮めて移動する?
左右方向は先程の図でわかるように両端がはみ出さないように十分広げておけば良いわけですが、上下方向はどうでしょうか?
上下方向に大きすぎると、:before
要素がoverflow: hidden
を付けている親要素をはみ出してしまい下図のようになってしまいます。
これを解決するために三角関数の力を借りましょう。さらに下の図を見てください。
赤く示した部分の長さが親要素のheight
より小さければ良さそうです。正確な計算はめんどくさいので、それっぽいところの長さ使ってちょっと大きい長さを計算した結果がこちらになります。
.outer:before{
height: calc(100% - tanθ * (sinθ * 50% + 50vw) * 2);
top: calc(sinθ * (0.11 * 50% + 50vw);
}
ここでθは回転させたい角度になります。各角度でのsinやtanの値はここなんかを使えば簡単に計算できるのでそれぞれ値を計算し、それよりちょっと大きい数字を代入します。
あとは.outer
のpadding
をそれっぽく調整してあげましょう。今回はこんな感じ
.outer{
padding: calc(100vw * 0.12) 0;
}
vw * パラメーター
としてあげるとどんな画面幅でもいい感じにpadding
が伸び縮してくれます。
で、結局どこをいじればいいの?
ごちゃごちゃと説明してきましたが調整すべき箇所は4箇所です。
まずは.outer:before
の
.outer:before{
transform: rotate(6deg);
height: calc(100% - tanθ * (sinθ * 50% + 50vw) * 2);
top: calc(sinθ * (0.11 * 50% + 50vw);
}
の回転角と、sinθとtanθの値。再掲になりますがsinとtanはここで計算できます。
次に.outer
のpadding
です。様子を見ながら
.outer{
padding: calc(100vw * 0.12) 0;
}
の0.12のところを増やしたり減らしたりしてみてください。
メディアクエリ書かなくても一発で綺麗な背景が作れて気持ちいい!!!