CSSで左右/上下の両矢印を描画し、幅も自動調整する
先日、「CSSだけで両矢印と上に重ねるテキストを描いてみる」と題して左右の両矢印「↔」をCSSだけで描いてみました。
しかし、やっつけで作ったこともあり、幅の指定をしないといけない点が気になっていました。
どうせなら親要素の大きさに合わせた長さに自動調整される矢印を描きたかったんですね。
左右の両矢印を画像の幅に合わせて描画する
表示例
要するにこういうことがしたかったわけです。
写真のサイズがあらかじめわかっている場合はwidth:649px;としても良いのですが、普通レスポンシブデザインで作る場合は画像サイズが可変になるでしょうから、それに合わせて矢印の長さも自動調整してほしいところです。
今回のCSSではそれに対応しています。
HTMLとCSS
<div class="arrow_wrapper">
<div class="arrow"><div>幅は649px</div></div>
<img src="[画像ファイル]" />
</div>
<style>
div.arrow_wrapper {
position:relative;
display:inline-block;
border:1px dotted gray;
margin:12px;
font-size:0.7em;
padding:0;
}
div.arrow {
position:absolute;
left:0;
top:-10px;
width:100%;
height:2px;
background-color:red;
}
div.arrow:before {
position:absolute;
top:-4px;
left:-6px;
content:'';
display:inline-block;
border:5px solid transparent;
border-right:10px solid red;
}
div.arrow:after {
content:'';
position:absolute;
right:-6px;
top:-4px;
display:inline-block;
border:5px solid transparent;
border-left:10px solid red;
}
div.arrow > div {
position:absolute;
left:0;
right:0;
top:-16px;
text-align:center;
width:6em;
background-color:white;
margin:auto;
}
</style>
解説
前回の記事でほとんど解説済なので、あらためて語ることは少ないのですが、arrow_wrapperクラスを追加して、画像をぴっちりと隙間なく囲んでいます。
そして、そのarrow_wrapperを基準としてwidth:100%としているため、矢印のサイズがぴったり合うわけですね。
もちろん、そのまま描画してしまうと画像に被さってしまうため、div.arrowはtop:-10px;というマイナスの数値を指定して、画像にかぶらない位置へ移動させています。
すごくわずかな変更のようですが………………いや実際わずかな変更なんですけどw このCSSを作るのに半日くらいかかってしまいました。
というのも、position:absolute;を指定した場合、親要素を基準としたwidth:100%指定は効かないだろう、と思い込んでいたんですよね。そのため、divを何枚も重ねたり、floatをためしたり、無駄な努力をしてしまいました。
実際はdiv.arrow_wrapperを基準として、子要素をposition:absolute;とwidth:100%;指定するだけで良かったっていう…😭
上下左右の両矢印を画像の幅に合わせて描画する
せっかくなので上下の両矢印「↕」も追加してみます。
表示例
HTMLとCSS
<div class="arrow_wrapper">
<div class="arrow"><div>幅は649px</div></div>
<div class="arrow_updown"><div>高さは433px</div></div>
<img src="[画像ファイル]" />
</div>
<style>
div.arrow_wrapper {
position:relative;
display:inline-block;
border:1px dotted gray;
margin:12px;
font-size:0.7em;
padding:0;
}
div.arrow {
position:absolute;
left:0;
top:-10px;
width:100%;
height:2px;
background-color:red;
}
div.arrow:before {
position:absolute;
top:-4px;
left:-6px;
content:'';
display:inline-block;
border:5px solid transparent;
border-right:10px solid red;
}
div.arrow:after {
content:'';
position:absolute;
right:-6px;
top:-4px;
display:inline-block;
border:5px solid transparent;
border-left:10px solid red;
}
div.arrow > div {
position:absolute;
left:0;
right:0;
top:-12px;
text-align:center;
width:6em;
background-color:white;
margin:auto;
}
.arrow_updown {
position:absolute;
top:0;
left:-10px;
width:2px;
height:100%;
background-color:blue;
}
.arrow_updown:before {
content:'';
position:absolute;
top:-6px;
left:-4px;
border:5px solid transparent;
border-bottom:10px solid blue;
}
.arrow_updown:after {
content:'';
position:absolute;
bottom:-6px;
left:-4px;
border:5px solid transparent;
border-top:10px solid blue;
}
.arrow_updown > div {
position:absolute;
top:33%;
left:-10px;
writing-mode:vertical-rl;
background-color:white;
}
</style>
解説
左右と上下の両矢印をどちらも追加したのでCSSが長くなりましたが、やってることは変わりません。左右に三角形付けていたのを上下にしただけですね。
あー、でも、矢印の上に重ねるテキストについてはせっかくなのでwriting-mode:vertical-rl;を指定して縦書き表示にしています。
まとめ
前回の記事で左右の両矢印をCSSで作ってみましたが、汎用性がイマイチな気がしたので、画像サイズに合わせて矢印の長さも変わるバージョンを作ってみました。
ざっくりとCSSのクラス名を説明しておくと、
- .arrow_wrapperは画像をぴっちりと囲むクラス
- .arrow / .arrow:before / .arrow:after は左右の矢印を描くクラス
- .arrow_updown / .arrow_updown:before / .arrow_updown:after は上下の矢印を描くクラス
です。
あぁ、あと各arrowクラスの下にあるdivは矢印の上に重ねるテキストですね。これはあってもなくてもどちらでも良いです。
もしかしたら、CSSが長くてウッ!となる人もいるかも知れませんが、実際は上記のとおり3種類に分けて考えればシンプルなものです。
なにより、画像でこういう矢印作っちゃうと汎用性がないんですよねー。下手に動的にサイズ変更しようものなら画像が荒くなるし。
ただ、前回も書いたとおり、SVGで作るなら話は別。そちらの方法も機会があれば紹介してみたいなぁ~と思っております。
では、こちらの記事が「CSSで矢印を描きたくて描きたくてたまらない…っ!」という方の目にとまることを祈っております。