web-dev-qa-db-ja.com

CSSで3角丸三角形を作成する方法

Javascriptを使用せずに、次のようなカスタム色のシェイプを実現したいと思います。 3 corner rounded triangle

現在、オレンジ色の長方形のdivに「フレーム」の画像をオーバーレイしていますが、これはかなりハッキーです。動的に生成されたキャンバス要素を使用できると思いますが、それにはJSだけでなく、HTML5キャンバスのサポートも必要です。何か案は?

35
Murray Smith

私の最善の試み: http://dabblet.com/Gist/4592062 final

任意のサイズのピクセル完全性、Anaの元のソリューションよりも簡単な数学を使用し、私の意見ではより直感的です:)

.triangle {
        position: relative;
        background-color: orange;
        text-align: left;
}
.triangle:before,
.triangle:after {
        content: '';
        position: absolute;
        background-color: inherit;
}
.triangle,
.triangle:before,
.triangle:after {
        width:  10em;
        height: 10em;
        border-top-right-radius: 30%;
}

.triangle {
        transform: rotate(-60deg) skewX(-30deg) scale(1,.866);
}
.triangle:before {
        transform: rotate(-135deg) skewX(-45deg) scale(1.414,.707) translate(0,-50%);
}
.triangle:after {
        transform: rotate(135deg) skewY(-45deg) scale(.707,1.414) translate(50%);
}
<div class="triangle"></div>
90
Murray Smith

dabblet demo

.triangle, .triangle:before, .triangle:after { width: 4em; height: 4em; }
.triangle {
        overflow: hidden;
        position: relative;
        margin: 7em auto 0;
        border-radius: 20%;
        transform: translateY(50%) rotate(30deg) skewY(30deg) scaleX(.866);
        cursor: pointer;
        pointer-events: none;
} 
.triangle:before, .triangle:after {
        position: absolute;
        background: orange;
        pointer-events: auto;
        content: '';
}
.triangle:before {
        border-radius: 20% 20% 20% 53%;
        transform: scaleX(1.155) skewY(-30deg) rotate(-30deg) translateY(-42.3%) 
                        skewX(30deg) scaleY(.866) translateX(-24%);
}
.triangle:after {
        border-radius: 20% 20% 53% 20%;
        transform: scaleX(1.155) skewY(-30deg) rotate(-30deg) translateY(-42.3%) 
                        skewX(-30deg) scaleY(.866) translateX(24%);
}

/** extra styles to show how it works **/

.triangle:hover { overflow: visible; }
.triangle:hover:before, .triangle:hover:after { background: none; }
.triangle:hover, .triangle:hover:before, .triangle:hover:after {
        border: dashed 1px;
}
<div class='triangle'></div>

アイデアは実に簡単です。まず、.triangle要素(overflow: hidden;があります。これを削除すると何が起こるかを確認できます)に一連の変換を適用して、ひし形を取得します。

次に、同じ変換を:beforeおよび:after疑似要素に適用し、さらにいくつかを追加して、それらを菱形にします。

そして最後に、交差する3つの菱形があり、オレンジ色の形状が交差しています。三角形にカーソルを合わせて、交差する形状を確認します;)

それはうまくスケーリングします。あなたは.triangle要素のwidthheightを変更するだけです。

Firefoxの場合、ChromeおよびSafariでは、角の丸いオレンジ色の三角形のみがホバーの影響を受けます(pointer-events: none;要素の.triangleと、擬似要素のpointer-events: auto;に感謝します)。同じwidthheight(および同じ.triangle)とborder-radiusを持つ要素にoverflow: hidden;をラップすることにより。


ノート

  • CSSグラデーションでもできます。ただし、 2D変換とは異なり 、CSSグラデーション IE9では機能しません
  • 回転後に再びスキューするために親からスキューを継承する擬似要素のスキューを解除する必要がなかったらよいのですが、そうでない場合は動作しないようです。
24
Ana

何らかの画像を使用します。それが画像の目的です。スケーリングする必要がある場合は、 SVGをお勧めします 、それ以外の場合は、背景としてpngを使用するか、<img>要素がコンテンツの一部である場合。

絶対にmustCSSファイルに含める必要がある場合は、 data:urls (IE7以下ではサポートされていません)を試すことができます。

9
zzzzBov

マレー・スミスの最も投票されたバージョンで遊んだ。スタイラスミックスインとして書き、マージンの問題を修正し、方向オプションを追加しました。ミックスインは、三角形をややピクセルパーフェクトなサイズにスケーリングします。非常によくテストされていません。注意して使用する

http://codepen.io/perlundgren/pen/VYGdwX

    triangle(direction = up, color = #333, size = 32px)
        position: relative
        background-color: color
        width:  2*(round(size/3.25))
        height: 2*(round(size/3.25))
        border-top-right-radius: 30%
        &:before,
        &:after
          content: ''
          position: absolute
          background-color: inherit
          width:  2*(round(size/3.25))
          height: 2*(round(size/3.25))
          border-top-right-radius: 30%

        if direction is up
          transform: rotate(-60deg) skewX(-30deg) scale(1,.866)
          margin: (@width/4) (@width/2.5) (@width/1.2) (@width/2.5)

        if direction is down
          transform: rotate(-120deg) skewX(-30deg) scale(1,.866)
          margin: 0 (@width/1.5) (@width/1.5) (@width/6)

        if direction is left
          transform: rotate(-30deg) skewX(-30deg) scale(1,.866)
          margin: (@width/5) 0 (@width) (@width/1.4)

        if direction is right
          transform: rotate(-90deg) skewX(-30deg) scale(1,.866)
          margin: (@width/5) (@width/1.4) (@width) 0

        &:before
          transform: rotate(-135deg) skewX(-45deg) scale(1.414,.707) translate(0,-50%)
        &:after
          transform: rotate(135deg) skewY(-45deg) scale(.707,1.414) translate(50%)

そして、クラスにミックスインを追加します

    .triangle
      &.up
        triangle()
      &.down
        triangle(down)
      &.left
        triangle(left)
      &.right
        triangle(right)
5
Per Lundgren

アナの答えは、完璧とは程遠いが、少なくとも対称的である別のアプローチを試してみようと思いました。これが実物大で拡大されたプレビューです。これは、クリッピングサークル/境界線の半径に囲まれた単なる境界ハックの三角形です。

Preview

そして、コード(単一のfont-sizeプロパティ):

.triangle {
    font-size: .8em;
    position: relative;
    width: 3.8em;
    height: 3.8em;
    text-align: center;
    margin: 10% auto 0;
    overflow: hidden;
    border-radius: 100%;
} 
.triangle:before {
    content: '';
    position: absolute;
    width:0;
    height: 0;
    border: solid 2em transparent;
    border-bottom-color: orange;
    border-bottom-width: 3.2em;
    border-top-width: 0;
    margin: -.3em -2em;
}

ここで遊んでください: http://dabblet.com/Gist/4590714

5
Murray Smith

私は二等辺三角形を求めている人がいて、上記の受け入れられた答えを改ざんすることで、同じものが必要だと思って欲しいものを得るためにそれを操作する方法を見つけました。これは、丸い角の三角形のわずかな変化を探している人の助けになるはずです。

幅、高さ、および境界線の右上の半径を分離した後、境界線の右上の半径を変更して角を形作ったことがわかります。私が変更した他の唯一のことは、要素のtransformプロパティでした。どのようにフィットするかは形作ることができますが、必要な変更はそれだけのようです。

.diff-arrow {
  margin-left:30px;
  position: relative;
  background-color: #20C0F1;
  text-align: left;
  width: 10em;
  height: 10em;
  border-top-right-radius: 20%;
}

.diff-arrow:before,
.diff-arrow:after {
  content: '';
  position: absolute;
  background-color: inherit;
  width: 10em;
  height: 10em;
  border-top-right-radius: 15%;
}

.diff-arrow {
  transform: rotate(-45deg) skewX(0deg) scale(0.5);
}

.diff-arrow:before {
  transform: rotate(-135deg) skewX(-45deg) scale(1.414, .707) translate(0, -50%);
}

.diff-arrow:after {
  transform: rotate(135deg) skewY(-45deg) scale(.707, 1.414) translate(50%);
}
<div class="diff-arrow"></div>
1
Jester