How to make 3-corner-rounded triangle in CSS

前端 未结 7 2414
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-27 03:34

I\'d like to achieve a custom-colored shape like this using no Javascript: \"3

Curren

相关标签:
7条回答
  • 2020-11-27 04:04

    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

    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

        .triangle
          &.up
            triangle()
          &.down
            triangle(down)
          &.left
            triangle(left)
          &.right
            triangle(right)
    
    0 讨论(0)
  • 2020-11-27 04:05

    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>

    0 讨论(0)
  • 2020-11-27 04:07

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

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

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

    0 讨论(0)
  • 2020-11-27 04:08

    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 .triangle element (which has overflow: hidden; - you can remove that to see what happens ;) ) in order to get a rhombus.

    Then you apply the same transforms to the :before and :after pseudo-elements, plus a few more to make them rhomboidal as well.

    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 width and the height of the .triangle element.

    For Firefox, Chrome and Safari, only the orange triangle with rounded corners is sensitive to hover (thanks to pointer-events: none; on the .triangle element and pointer-events: auto; on the pseudo-elements). Otherwise, this could be achieved by wrapping .triangle in an element having the same width and height (and the same border-radius) and 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.
    0 讨论(0)
  • 2020-11-27 04:08

    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-size property):

    .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

    0 讨论(0)
  • 2020-11-27 04:17

    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.

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

    0 讨论(0)
提交回复
热议问题