LoginSignup
3
4

More than 3 years have passed since last update.

CSSのborderで描いた三角形を配置した時に生じる隙間を消す方法

Posted at

CSSのborderを組み合わせて描いた三角形を、下図のように長方形の左辺にくっつけて配置してできた図形をレスポンシブ対応にしたい。つまり、三角形と長方形の相対的な位置関係を維持したまま、ウインドウ幅に応じて図形のサイズを変化させたい。そんなCSSを書いたところ、ブラウザに依存した現象にハマりました。その解決策のメモです。
fig01_w200.png
動作環境
macOS 10.14 (Mojave), Retinaディスプレイ(Radeon Pro 575), Firefox 75, Safari 13.1

ダメな例

まずは失敗例から。本記事では話を簡単にするため、長方形のサイズは固定とし、三角形のみサイズを可変にしたもので説明します。三角形の高さを6vwとしましょう。

html
<div class="box">
  <div class="triangle p-left"></div>
</div>
css
.box {
  width: 150px;
  height: 100px;
  background-color: #000;
  position: relative;
  margin-left: 200px;
  margin-bottom: 20px;
  color: #fff;
  padding: 16px 16px 0 20px;
}
.triangle {
  width: 0;
  height: 0;
  border-right: 6vw solid #000;
  border-top: 3vw solid transparent;
  border-bottom: 3vw solid transparent;
}
.p-left {
  position: absolute;
  top: 20px;
  left: -6vw;
}

右側borderの幅6vw、上下のborderの幅3vwという組み合わせで作った三角形div.triangleを、div.boxに対して三角形の高さ分、左側にleft: -6vwの絶対位置指定により配置しました。

これをFirefoxで表示し、ブラウザのウインドウ幅をゆっくり変えていってみましょう。すると、下図のAのように、三角形と長方形との接合部分にチラチラと隙間が空いてしまうのがわかります。
vid01_trim.gif
隙間の部分を拡大すると(下図)、そこには1デバイスピクセル分の空きが生じていました(使用したモニタはデバイスピクセル比2)。
fig02_details.png
先ほどのアニメーションに示した残りの3つの図形BDも、div.boxの左側に子要素をleftプロパティの絶対位置指定で配置したものですが、隙間が生じないものもあります。それらの違いについて見ていきましょう。

図形B: 隙間あり

子要素はwidth 0の長方形で、右側borderを幅6vwにして塗りつぶしのように見せた図形です(Aの三角形と同様の手法)。子要素はleft: -6vwで配置。Aの場合と同じく、接合部に隙間ができました。

html
<div class="box">
  <div class="rect p-left"></div>
</div>

css
.rect {
  width: 0;
  height: 50px;
  border-right: 6vw solid #000;
}

図形C: 隙間なし

子要素はwidth 6vwの塗りつぶした長方形です。子要素はleft: -6vwで配置。こちらは隙間ができません。

html
<div class="box">
  <div class="rect2 p-left"></div>
</div>
css
.rect2 {
  width: 6vw;
  height: 50px;
  background-color: #000;   
}

図形D: 隙間なし

子要素は固定幅60px, 30pxのborderを組み合わせて描いた三角形です。子要素は固定px値left: -60pxで配置。これも隙間は生じません。

html
<div class="box">
  <div class="triangle-px p-left-px"></div>
</div>
css
.triangle-px {
  width: 0;
  height: 0;
  border-right: 60px solid #000;
  border-top: 30px solid transparent;
  border-bottom: 30px solid transparent;
}
.p-left-px {
  position: absolute;
  top: 20px;
  left: -60px;
}

結果のまとめ

以上の結果をまとめると下表のとおりです。

図形 width指定 border幅指定 left指定 隙間
A 0 vw vw あり
B 0 vw vw あり
C vw (none) vw なし
D 0 px px なし

要素の形状に関係なく、border使って塗りつぶした場合はborder幅とleftの長さを両方ともvw単位で指定すると相性が悪く、ブラウザによっては半端なピクセル分の隙間ができてしまうようです。下記のブラウザで確認したところ、本記事の執筆時点(2020年5月)ではFirefoxとSafariでこの現象が発生してました。

ブラウザ Engine 現象の発生
Firefox 75 Gecko する
Safari 13.1 WebKit する
Chrome 81 Blink しない
Opera 68 Blink しない

解決策

子要素の位置をleftで指定するのは諦めて、rightを使ってみましょう。子要素の右側をdiv.boxの左辺にぴったり付けるには、たった1行right: 100%に変更するだけ。

css
.p-left {
    position: absolute;
    top: 20px;
/*  left: -6vw;*/
    right: 100%;
}

先ほどのアニメーションの図形ADで、子要素をすべてright: 100%に変更したのが下図です。これでFirefoxやSafariでも隙間が出なくなりました。
vid02_fix_trim.gif

rightプロパティは、要素の右辺と包含ブロックの右辺との間の距離を表し、値にパーセントを指定した場合は包含ブロックの幅に対するpercentageになるので1、100%を指定すれば、div.boxの幅が変動しても子要素の右側がぴったりくっつくというわけですね。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4