見出し - CSS三角形はどのように機能しますか?
css 直角三角形 (12)
CSS三角:5つの行為の悲劇
アレックスが言ったように 、等しい幅の境界線は、45度の角度でお互いに突き合わせています。
上の境界線がないときは、次のようになります。
それからあなたはそれに0の幅を与える...
...そして高さ0 ...
最後に、2つの側面の境界を透明にします。
その結果三角形になります。
CSS Tricks - CSSのシェイプには、さまざまなCSSシェイプがたくさんあります。特に私は三角形に困惑しています。
#triangle-up {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
<div id="triangle-up"></div>
どのように、なぜそれは機能するのですか?
SASS(SCSS)三角ミックスイン
私はこれを書いて、CSSの三角形を自動的に生成することを容易にしました(そしてDRY):
// Triangle helper mixin (by Yair Even-Or)
// @param {Direction} $direction - either `top`, `right`, `bottom` or `left`
// @param {Color} $color [currentcolor] - Triangle color
// @param {Length} $size [1em] - Triangle size
@mixin triangle($direction, $color: currentcolor, $size: 1em) {
$size: $size/2;
$transparent: rgba($color, 0);
$opposite: (top:bottom, right:left, left:right, bottom:top);
content: '';
display: inline-block;
width: 0;
height: 0;
border: $size solid $transparent;
border-#{map-get($opposite, $direction)}-color: $color;
margin-#{$direction}: -$size;
}
ユースケースの例:
span {
@include triangle(bottom, red, 10px);
}
プレイグラウンドページ
重要な注意点:
三角形が一部のブラウザでピクセル化されているように見える場合は、 here説明さhereいる方法のいずれかを試してみてください。
OK、この三角形は、要素の境界がHTMLとCSSで一緒に動作するために作成されます...
私たちは通常1〜2pxのボーダーを使用しているので、同じ幅でボーダー同士が45度の角度をなしていることに気付くことはなく、また幅が変わると角度の度合いも変わります。
.triangle {
width: 100px;
height: 100px;
border-left: 50px solid black;
border-right: 50px solid black;
border-bottom: 100px solid red;
}
<div class="triangle">
</div>
次に、次のステップでは、幅や高さなどはありません。
.triangle {
width: 0;
height: 0;
border-left: 50px solid black;
border-right: 50px solid black;
border-bottom: 100px solid red;
}
<div class="triangle">
</div>
そして、我々は以下のように望ましい三角形を作るために左と右の境界を見えないようにする:
.triangle {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
<div class="triangle"></div>
ステップを見るためにスニペットを実行したくない場合は、イメージシーケンスを作成して、1つのイメージ内のすべてのステップを表示します。
ここで私はデモンストレーションのために作成したJSFiddleのアニメーションを示します。
下記のスニペットもご覧ください。
これはスクリーンキャストから作られたアニメーションGIFです
transforms = [
{'border-left-width' :'30', 'margin-left': '70'},
{'border-bottom-width' :'80'},
{'border-right-width' :'30'},
{'border-top-width' :'0', 'margin-top': '70'},
{'width' :'0'},
{'height' :'0', 'margin-top': '120'},
{'borderLeftColor' :'transparent'},
{'borderRightColor' :'transparent'}
];
$('#a').click(function() {$('.border').trigger("click");});
(function($) {
var duration = 1000
$('.border').click(function() {
for ( var i=0; i < transforms.length; i++ ) {
$(this)
.animate(transforms[i], duration)
}
}).end()
}(jQuery))
.border {
margin: 20px 50px;
width: 50px;
height: 50px;
border-width: 50px;
border-style: solid;
border-top-color: green;
border-right-color: yellow;
border-bottom-color: red;
border-left-color: blue;
cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>
Click it!<br>
<div class="border"></div>
ランダムバージョン
/**
* Randomize array element order in-place.
* Using Durstenfeld shuffle algorithm.
*/
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
transforms = [
{'border-left-width' :'30', 'margin-left': '70'},
{'border-bottom-width' :'80'},
{'border-right-width' :'30'},
{'border-top-width' :'0', 'margin-top': '70'},
{'width' :'0'},
{'height' :'0'},
{'borderLeftColor' :'transparent'},
{'borderRightColor' :'transparent'}
];
transforms = shuffleArray(transforms)
$('#a').click(function() {$('.border').trigger("click");});
(function($) {
var duration = 1000
$('.border').click(function() {
for ( var i=0; i < transforms.length; i++ ) {
$(this)
.animate(transforms[i], duration)
}
}).end()
}(jQuery))
.border {
margin: 50px;
width: 50px;
height: 50px;
border-width: 50px;
border-style: solid;
border-top-color: green;
border-right-color: yellow;
border-bottom-color: red;
border-left-color: blue;
cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>
Click it!<br>
<div class="border"></div>
オールインワンバージョン
$('#a').click(function() {$('.border').trigger("click");});
(function($) {
var duration = 1000
$('.border').click(function() {
$(this)
.animate({'border-top-width': 0 ,
'border-left-width': 30 ,
'border-right-width': 30 ,
'border-bottom-width': 80 ,
'width': 0 ,
'height': 0 ,
'margin-left': 100,
'margin-top': 150,
'borderTopColor': 'transparent',
'borderRightColor': 'transparent',
'borderLeftColor': 'transparent'}, duration)
}).end()
}(jQuery))
.border {
margin: 50px;
width: 50px;
height: 50px;
border-width: 50px;
border-style: solid;
border-top-color: green;
border-right-color: yellow;
border-bottom-color: red;
border-left-color: blue;
cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>
Click it!<br>
<div class="border"></div>
これは古い質問ですが、この三角技法を使って矢印を作成する方法を共有する価値があると思います。
ステップ1:
2つの三角形を作成し、2つ目は:after
擬似クラスを使用して、それをもう一方の下に配置します。
.arrow{
width: 0;
height: 0;
border-radius: 50px;
display: inline-block;
position: relative;
}
.arrow:after{
content: "";
width: 0;
height: 0;
position: absolute;
}
.arrow-up{
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid #333;
}
.arrow-up:after{
top: 5px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid #ccc;
right: -50px;
}
<div class="arrow arrow-up"> </div>
ステップ2
今度は、2番目の三角形の主要な境界線の色を同じ背景色に設定するだけです。
.arrow{
width: 0;
height: 0;
border-radius: 50px;
display: inline-block;
position: relative;
}
.arrow:after{
content: "";
width: 0;
height: 0;
position: absolute;
}
.arrow-up{
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid #333;
}
.arrow-up:after{
top: 5px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid #fff;
right: -50px;
}
<div class="arrow arrow-up"> </div>
すべての矢でフィドル:
http://jsfiddle.net/tomsarduy/r0zksgeu/
これを元にしてCSSを使用して、私は後ろのボタンと次のボタンに矢印を追加しました(はい、100%クロスブラウザではなく、滑らかなものではありません)。
.triangle {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
margin:20px auto;
}
.triangle-down {
border-bottom:none;
border-top: 100px solid red;
}
.triangle-left {
border-left:none;
border-right: 100px solid red;
border-bottom: 50px solid transparent;
border-top: 50px solid transparent;
}
.triangle-right {
border-right:none;
border-left: 100px solid red;
border-bottom: 50px solid transparent;
border-top: 50px solid transparent;
}
.triangle-after:after {
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 5px solid red;
margin:0 5px;
content:"";
display:inline-block;
}
.triangle-after-right:after {
border-right:none;
border-left: 5px solid blue;
border-bottom: 5px solid transparent;
border-top: 5px solid transparent;
}
.triangle-before:before {
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 5px solid blue;
margin:0 5px;
content:"";
display:inline-block;
}
.triangle-before-left:before {
border-left:none;
border-right: 5px solid blue;
border-bottom: 5px solid transparent;
border-top: 5px solid transparent;
}
<div class="triangle"></div>
<div class="triangle triangle-down"></div>
<div class="triangle triangle-left"></div>
<div class="triangle triangle-right"></div>
<a class="triangle-before triangle-before-left" href="#">Back</a>
<a class="triangle-after triangle-after-right" href="#">Next</a>
ほとんどすべての答えは境界を使って構築された三角形に焦点を当てていますので、( @lima_filの回答から@lima_fil ) linear-gradient
法を@lima_filます。
45°
ような度数を使うと、私たちが望む三角形を得るためにheight/width
特定の比率を尊重しなければならなくなり、これは反応しません。
.tri {
width:100px;
height:100px;
background:linear-gradient(45deg, transparent 50%,red 0);
/*To illustrate*/
border:1px solid;
}
Good one
<div class="tri"></div>
bad one
<div class="tri" style="width:150px"></div>
bad one
<div class="tri" style="height:30px"></div>
これを行うのではなく、 to bottom
to top
to bottom
の方向の定義済みの値を考慮する必要があります。この場合、どのような種類の三角形も応答性を保ちながら取得できます。
1)長方形の三角形
このような三角形を得るためにto top left
、 to bottom right
、 to top left
、 to bottom right
などのような線形勾配と斜め方向が必要です
.tri-1,.tri-2 {
display:inline-block;
width:100px;
height:100px;
background:linear-gradient(to bottom left, transparent 49.8%,red 50%);
border:1px solid;
animation:change 2s linear infinite alternate;
}
.tri-2 {
background:linear-gradient(to top right, transparent 49.8%,red 50%);
border:none;
}
@keyframes change {
from {
width:100px;
height:100px;
}
to {
height:50px;
width:180px;
}
}
<div class="tri-1"></div>
<div class="tri-2"></div>
2)二等辺三角形
この場合、上記のような2つの線形勾配が必要であり、それぞれが幅の半分(または高さ)を取ることになります。 それは、最初の三角形の鏡像を作成するようなものです。
.tri {
display:inline-block;
width:100px;
height:100px;
background-image:
linear-gradient(to bottom right, transparent 49.8%,red 50%),
linear-gradient(to bottom left, transparent 49.8%,red 50%);
background-size:50.5% 100%; /* I use a value slightly bigger than 50% to avoid having a small gap between both gradient*/
background-position:left,right;
background-repeat:no-repeat;
animation:change 2s linear infinite alternate;
}
@keyframes change {
from {
width:100px;
height:100px;
}
to {
height:50px;
width:180px;
}
}
<div class="tri"></div>
3)正三角形
これは、グラデーションの高さと幅の関係を維持する必要があるため、扱いにくいです。 上記と同じ三角形を使用しますが、二等辺三角形を正三角形に変換するために計算を複雑にします。
簡単にするために、divの幅がわかっていて、高さが三角形を内側に描くのに十分な大きさ( height >= width
)と考えます。
我々は2つの勾配g1
とg2
を持ち、青い線はdiv
w
幅であり、各勾配はその50%( w/2
)を持ち、三角形の各辺はw
と等しくなければならない。 緑色の線は、両方の勾配hg
高さであり、以下の式を簡単に得ることができます。
(w/2)² + hg² = w²
---> hg = (sqrt(3)/2) * w
---> hg = 0.866 * w
計算を行い、必要な結果を得るためにcalc()
を使用することができます:
.tri {
--w:100px;
width:var(--w);
height:100px;
display:inline-block;
background-image:
linear-gradient(to bottom right, transparent 49.8%,red 50%),
linear-gradient(to bottom left, transparent 49.8%,red 50%);
background-size:calc(var(--w)/2 + 0.5%) calc(0.866 * var(--w));
background-position:
left bottom,right bottom;
background-repeat:no-repeat;
}
<div class="tri"></div>
<div class="tri" style="--w:80px"></div>
<div class="tri" style="--w:50px"></div>
別の方法は、divの高さを制御し、グラデーションの構文を簡単に保つことです:
.tri {
--w:100px;
width:var(--w);
height:calc(0.866 * var(--w));
display:inline-block;
background:
linear-gradient(to bottom right, transparent 49.8%,red 50%) left,
linear-gradient(to bottom left, transparent 49.8%,red 50%) right;
background-size:50.2% 100%;
background-repeat:no-repeat;
}
<div class="tri"></div>
<div class="tri" style="--w:80px"></div>
<div class="tri" style="--w:50px"></div>
4)ランダムな三角形
ランダムな三角形を取得するには、それぞれの50%の条件を削除するだけで済みますが、2つの条件(両方とも同じ高さで、両方の幅の合計が100%である必要があります)を保つ必要があるため、簡単です。
.tri-1 {
width:100px;
height:100px;
display:inline-block;
background-image:
linear-gradient(to bottom right, transparent 50%,red 0),
linear-gradient(to bottom left, transparent 50%,red 0);
background-size:20% 60%,80% 60%;
background-position:
left bottom,right bottom;
background-repeat:no-repeat;
}
<div class="tri-1"></div>
しかし、もし我々が各側の値を定義したいのであれば? 我々は単に計算をやり直す必要があります!
グラデーションの高さとしてhg1
とhg2
を定義してみましょう(両方とも赤い線に等しい)。次に、グラジエントの幅( wg1 + wg2 = a
)としてwg1
とwg2
します。 私は計算を詳述するつもりはありませんが、最終的には次のようになります:
wg2 = (a²+c²-b²)/(2a)
wg1 = a - wg2
hg1 = hg2 = sqrt(b² - wg1²) = sqrt(c² - wg2²)
今度はcalc()
を使ってもCSSの限界に達しました。これを実装することはできません。最終結果を手動で集めて固定サイズとして使うだけです。
.tri {
--wg1: 20px;
--wg2: 60px;
--hg:30px;
width:calc(var(--wg1) + var(--wg2));
height:100px;
display:inline-block;
background-image:
linear-gradient(to bottom right, transparent 50%,red 0),
linear-gradient(to bottom left, transparent 50%,red 0);
background-size:var(--wg1) var(--hg),var(--wg2) var(--hg);
background-position:
left bottom,right bottom;
background-repeat:no-repeat;
}
<div class="tri" ></div>
<div class="tri" style="--wg1:80px;--wg2:60px;--hg:100px;" ></div>
ボーナス
ローテーションやスキューを適用できることを忘れてはならず、より多くの三角形を取得するオプションがあります。
.tri {
--wg1: 20px;
--wg2: 60px;
--hg:30px;
width:calc(var(--wg1) + var(--wg2));
height:100px;
display:inline-block;
background-image:
linear-gradient(to bottom right, transparent 50%,red 0),
linear-gradient(to bottom left, transparent 50%,red 0);
background-size:var(--wg1) var(--hg),var(--wg2) var(--hg);
background-position:
left bottom,right bottom;
background-repeat:no-repeat;
}
<div class="tri" ></div>
<div class="tri" style="transform:skewY(25deg)"></div>
<div class="tri" style="--wg1:80px;--wg2:60px;--hg:100px;" ></div>
<div class="tri" style="--wg1:80px;--wg2:60px;--hg:100px;transform:rotate(20deg)" ></div>
もちろん、状況によってはより適切なSVGソリューションを念頭に置いておく必要があります。
svg {
width:100px;
height:100px;
}
polygon {
fill:red;
}
<svg viewBox="0 0 100 100"><polygon points="0,100 0,0 100,100" /></svg>
<svg viewBox="0 0 100 100"><polygon points="0,100 50,0 100,100" /></svg>
<svg viewBox="0 0 100 100"><polygon points="0,100 50,23 100,100" /></svg>
<svg viewBox="0 0 100 100"><polygon points="20,60 50,43 80,100" /></svg>
下の三角形を考えてみましょう
.triangle {
border-bottom:15px solid #000;
border-left:10px solid transparent;
border-right:10px solid transparent;
width:0;
height:0;
}
これが私たちに与えられたものです:
なぜそれがこの形で出てきたのですか? 下の図は寸法を説明しています。下端に15px、左右に10pxを使用しています。
右の境界線を削除することによって直角三角形を作ることもかなり簡単です。
基本的な正方形と境界から始めます。 各国境には異なる色が与えられますので、それらを区別することができます:
.triangle {
border-color: yellow blue red green;
border-style: solid;
border-width: 200px 200px 200px 200px;
height: 0px;
width: 0px;
}
それはあなたにthisを与える:
しかし、上の境界線は必要ありません。したがって、幅を0px
設定します。 200px
ボーダー - ボトムは、 200px
トライアングルを200pxにします。
.triangle {
border-color: yellow blue red green;
border-style: solid;
border-width: 0px 200px 200px 200px;
height: 0px;
width: 0px;
}
私たちはthisを得るでしょう:
次に、2つのサイドの三角形を非表示にするには、border-colorを透明に設定します。 上ボーダーは効果的に削除されているので、ボーダートップカラーも透明に設定できます。
.triangle {
border-color: transparent transparent red transparent;
border-style: solid;
border-width: 0px 200px 200px 200px;
height: 0px;
width: 0px;
}
ついにこれを得this :
境界線は交差する角度のついたエッジを使用します(幅の等しい境界線では45°の角度ですが、境界線の幅を変更すると角度が歪むことがあります)。
jsFiddle 。
特定の罫線を隠すことで、三角形の効果を得ることができます(上で分かるように、異なる部分の色を変えることによって)。 三角形の形状を実現するために、エッジカラーとしてtransparent
がよく使用されます。
異なるアプローチ:
変換回転を伴うCSS3三角形
三角形は、このテクニックを使って作るのがとても簡単です。 このテクニックがここでどのように機能するかを説明するアニメーションを見ることを好む人にとって、
- アニメーションへのリンク: CSS3の三角形を作る方法 。
- デモ: CSS3の三角形は、変換が回転して作成されます。
さもなければ、ここに1つの要素で二等辺三角形の直角三角形を作る方法の4つの行為(これは悲劇ではない)の詳細な説明です。
- 注1:二等辺三角形の三角形や派手なものについては、手順4を参照してください 。
- 注2:次のスニペットでは、ベンダー接頭辞は含まれていません。 彼らはcodepenのデモに含まれています 。
- 注3:以下の説明のHTMLは常にです:
<div class="tr"></div>
ステップ1: divを作成する
簡単です。 width = 1.41 x height
を確認してください。 あなたはアスペクト比を維持して、 反応する三角形を作るためにパーセンテージとパッディングボトムの使用を含むテクニクク( ここを参照 )を使用することができます。 次の画像では、divは黄色い黄色の境界線を持っています。
そのdivでは、 擬似要素を挿入し、100%の幅と親の高さを与えます。 擬似要素は、次の画像に青色の背景があります。
この時点で、私たちはこのCSSを持っています:
.tr {
width: 30%;
padding-bottom: 21.27%; /* = width / 1.41 */
position: relative;
}
.tr: before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #0079C6;
}
ステップ2:回転させましょう
まず、最も重要な点は、変換元を定義することです 。 デフォルトの原点は擬似要素の中心にあり、左下にそれが必要です。 このCSSを擬似要素に追加することによって:
transform-origin:0 100%;
またはtransform-origin: left bottom;
今度は、擬似要素をtransform : rotate(45deg);
時計回りに45度回転させることができますtransform : rotate(45deg);
この時点で、私たちはこのCSSを持っています:
.tr {
width: 30%;
padding-bottom: 21.27%; /* = width / 1.41 */
position: relative;
}
.tr:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #0079C6;
transform-origin: 0 100%;
transform: rotate(45deg);
}
ステップ3:それを隠す
擬似要素の不要な部分(divを黄色の枠線でオーバーフローするもの)を隠すには、単にoverflow:hidden;
を設定するだけですoverflow:hidden;
容器の上に置く。 黄色のボーダーを取り除いた後、あなたは... 三角形を取得します! :
CSS:
.tr {
width: 30%;
padding-bottom: 21.27%; /* = width / 1.41 */
position: relative;
overflow: hidden;
}
.tr:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #0079C6;
transform-origin: 0 100%;
transform: rotate(45deg);
}
ステップ4:さらに進んでください...
デモに示すように、三角形をカスタマイズすることができます:
-
skewX()
再生することで、より薄くするか、よりフラットにします。 - トランスフォームの回転と回転の方向を変えて、左、右、または他の方向を指すようにします。
- 3Dトランスフォームプロパティを使っていくつかのリフレクションを行います。
- 三角形の境界線を与える
- 三角の内側に画像を置く
- もっともっと... CSS3の力を発揮してください!
なぜこのテクニックを使うのですか?
- トライアングルは簡単に反応することができます。
- 境界線を持つ三角形を作ることができます 。
- 三角形の境界を維持することができます。 つまり、カーソルが三角形の内側にある場合にのみホバー状態またはクリックイベントをトリガーすることができます。 これは、各三角形がそれ自身のホバー状態を持つように、各三角形がそれを隣人にオーバーレイすることができないこのようないくつかの状況では非常に便利になることがあります。
- 反射のような派手なエフェクトを作ることができます。
- 2dと3dの変換プロパティを理解するのに役立ちます。
なぜこのテクニックを使わないのですか?
私たちは次のdivを持っていると言うことができます:
<div id="triangle" />
CSSを段階的に編集して、何が起きているのかを明確にします
ステップ1: JSの手引きリンク:
#triangle {
background: purple;
width :150px;
height:150PX;
border-left: 50px solid black ;
border-right: 50px solid black;
border-bottom: 50px solid black;
border-top: 50px solid black;
}
これは簡単なdivです。 非常にシンプルなCSSを使用します。 そこで素人が理解できる。 Divは150 x 150ピクセル、境界は50ピクセルです。 画像が添付されています:
ステップ2: JSの手軽なリンク:
#triangle {
background: purple;
width :150px;
height:150PX;
border-left: 50px solid yellow ;
border-right: 50px solid green;
border-bottom: 50px solid red;
border-top: 50px solid blue;
}
今私は4面すべての境界線の色を変更しました。 画像が添付されています。
STEP:3 JS簡単リンク:
#triangle {
background: purple;
width :0;
height:0;
border-left: 50px solid yellow ;
border-right: 50px solid green;
border-bottom: 50px solid red;
border-top: 50px solid blue;
}
今度はdivの高さと幅を150ピクセルからゼロに変更しました。 画像が添付されています
ステップ4: JSfiddle:
#triangle {
background: purple;
width :0px;
height:0px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid red;
border-top: 50px solid transparent;
}
今、私はすべての境界線を下の境界線から離れて透明にしました。 画像は下に添付されています。
ステップ5: JSの手軽なリンク:
#triangle {
background: white;
width :0px;
height:0px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid red;
border-top: 50px solid transparent;
}
今私は背景色を白に変更しました。 画像が添付されています。
それで、私たちは必要な三角形を得ました。