如何在 CSS 中制作 3 角圆角三角形

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14446677/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 21:24:20  来源:igfitidea点击:

How to make 3-corner-rounded triangle in CSS

csscss-shapes

提问by Murray Smith

I'd like to achieve a custom-colored shape like this using no Javascript: 3 corner rounded triangle

我想不使用 Javascript 来实现这样的自定义颜色形状: 3角圆角三角形

Currently I'm overlaying an image of the 'frame' over an orange rectangular div, but this is pretty hacky. I suppose I could use a dynamically generated canvas element, but that not only requires JS, but HTML5 canvas support. Any ideas?

目前,我正在将“框架”的图像覆盖在橙色矩形 div 上,但这非常棘手。我想我可以使用动态生成的画布元素,但这不仅需要 JS,还需要 HTML5 画布支持。有任何想法吗?

回答by Murray Smith

My best attempt: http://dabblet.com/gist/4592062final

我最好的尝试:http: //dabblet.com/gist/4592062最终的

Pixel perfection at any size, uses simpler math than Ana's original solution, and is more intuitive in my opinion :)

任何尺寸的像素完美,使用比 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>

回答by Ana

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>

The idea is really simple: you first apply a series of transforms to your .triangleelement (which has overflow: hidden;- you can remove that to see what happens ;) ) in order to get a rhombus.

这个想法非常简单:首先对.triangle元素应用一系列变换(它具有overflow: hidden;- 您可以删除它以查看会发生什么;))以获得菱形。

Then you apply the same transforms to the :beforeand :afterpseudo-elements, plus a few more to make them rhomboidal as well.

然后对:before:after伪元素应用相同的变换,再加上一些使它们也变成菱形。

And in the end, you have three rhombuses which intersect, the orange shape being their intersection. Hover the triangle to see the intersecting shapes ;)

最后,你有三个相交的菱形,橙色的形状是它们的交点。悬停三角形以查看相交的形状;)

It scales nicely, you just have to change the widthand the heightof the .triangleelement.

它很好地扩展,你只需要改变widthheight的的.triangle元素。

For Firefox, Chrome and Safari, only the orange triangle with rounded corners is sensitive to hover (thanks to pointer-events: none;on the .triangleelement and pointer-events: auto;on the pseudo-elements). Otherwise, this could be achieved by wrapping .trianglein an element having the same widthand height(and the same border-radius) and overflow: hidden;.

对于 Firefox、Chrome 和 Safari,只有带有圆角的橙色三角形对悬停敏感(感谢pointer-events: none;on.triangle元素和pointer-events: auto;伪元素)。否则,这可以通过包装.triangle具有相同widthheight(和相同border-radius)和的元素来实现overflow: hidden;



Notes

笔记

  • You could also do it with CSS gradients. However, unlike 2D transforms, CSS gradients won't work in IE9.
  • I'd wish I didn't have to unskew the pseudo-elemets which inherit the skew from their parent only to skew them again after a rotation, but it doesn't seem to work otherwise.
  • 您也可以使用 CSS 渐变来实现。但是,与 2D 变换不同,CSS 渐变在 IE9 中不起作用
  • 我希望我不必取消从父母那里继承偏斜的伪元素,只是在旋转后再次偏斜它们,但它似乎没有其他工作。

回答by zzzzBov

Use an image of some sort. That's what images are for. If you need it to scale, SVG is a good choice, otherwise, just use a png as a background, or an <img>element if it's part of content.

使用某种图像。这就是图像的用途。如果需要缩放,SVG 是一个不错的选择,否则,只需使用 png 作为背景,或者<img>如果它是内容的一部分,则使用元素。

If you absolutely musthave it in a CSS file, you could try data: urls(not supported in IE7 and below).

如果您绝对必须在 CSS 文件中使用它,您可以尝试data: urls(IE7 及以下不支持)。

回答by Murray Smith

Ana's answer inspired me to try another approach, one that's just as far from perfect, but is at least symmetrical. Here's a preview at real-size and blown up. It's simply a border-hack trangle wrapped in a clipping circle/border-radius:

安娜的回答激励我尝试另一种方法,一种远非完美,但至少是对称的。这是实际尺寸和放大的预览。它只是一个包裹在裁剪圆/边界半径中的边界黑客缠结:

Preview

预览

And the code (adjust the overall size via single font-sizeproperty):

和代码(通过单个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;
}

Play with it here: http://dabblet.com/gist/4590714

在这里玩:http: //dabblet.com/gist/4590714

回答by Per Lundgren

Played around with Murray Smiths most upvoted version. Wrote it as a Stylus mixin and fixed some margin issues and added a direction option. The mixin also scales the triangle to somewhat pixelperfect size. Not tested very well. Use with care

与默里史密斯最受好评的版本一起玩。将其编写为 Stylus mixin 并修复了一些保证金问题并添加了方向选项。mixin 还将三角形缩放到像素完美的大小。没有很好地测试。小心使用

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

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%)

and then just add the mixin to your class

然后只需将 mixin 添加到您的课程中

    .triangle
      &.up
        triangle()
      &.down
        triangle(down)
      &.left
        triangle(left)
      &.right
        triangle(right)

回答by Jester

I saw there was someone asking for an isosceles triangle and through some tampering with the accepted answer above I found how to manipulate it to get what I wanted considering I needed the same. This should help anyone looking for a slight change in the rounded corner triangle.

我看到有人要求等腰三角形,通过对上面已接受的答案进行一些篡改,我找到了如何操纵它以获得我想要的,因为我需要相同的三角形。这应该有助于任何寻找圆角三角形细微变化的人。

You'll notice that I separated out the width, height, and border-top-right-radius then proceeded to change the border-top-right-radius to shape the corners. The only other thing I changed was the transform property on the element directly. You can shape it how you see fit, but those seem to be the only necessary changes.

您会注意到我将宽度、高度和边框右上角半径分开,然后继续更改边框右上角半径以塑造角。我唯一改变的另一件事是直接在元素上的变换属性。你可以按照你认为合适的方式塑造它,但这些似乎是唯一必要的改变。

.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>