简体   繁体   中英

How to achieve a responsive ribbon shape in CSS?

在此处输入图片说明

Trying to achieve this with css. I've achieved in doing this but this breaks if my label (CAREER) is longer the size of the div . If its longer then the content wraps and the height of the div increases. But the left ribbon cut does not do that responsively. Can someone suggest a better approach?

 .custom-tag-container { border: 1px solid; margin: auto; display: flex; align-items: stretch; border-color: green green green transparent; padding: 4px !important; } .custom-tag-container>p { color: green; font-weight: bold; flex: 1; margin: auto; } #triangle-left { height: 25px; width: 25px; background: transparent; transform: rotateZ(45deg) translateX(-12.5px) translateY(12.5px); border: 1px solid; border-color: green green transparent transparent; }
 <div class="custom-tag-container"> <div id="triangle-left" /> <p>Hello Worldsm</p> </div>

JS Fiddle

Here is an idea that rely on skew transformation where it will be responsive and you will have transparency:

 .box { height: 50px; border: 2px solid green; border-left: 0; border-radius:0 5px 5px 0; position:relative; margin:5px; } .box:before, .box:after{ content:""; position:absolute; left:0; height:50%; width:3px; background:green; } .box:before { top:0; transform:skew(45deg); transform-origin:top; } .box:after { bottom:0; transform:skew(-45deg); transform-origin:bottom; }
 <div class="box"></div> <div class="box" style="height:80px"></div>

功能区边缘 CSS

If you want to keep the same width for the arrow, you can consider a different idea using background:

 .box { height: 50px; border: 2px solid green; border-left: 0; border-radius:0 5px 5px 0; position:relative; margin:5px; overflow:hidden; } .box:before, .box:after{ content:""; position:absolute; left:0; top:0; height:50%; width:30px; background: linear-gradient(to top right, transparent calc(50% - 4px),green,transparent 50%) bottom/100% calc(100% + 4px); } .box:after { transform:scaleY(-1); transform-origin:bottom; }
 <div class="box"></div> <div class="box" style="height:80px"></div>

and with SVG too

 .box { height: 50px; border: 2px solid green; border-left: 0; border-radius:0 5px 5px 0; position:relative; margin:5px; } .box:before, .box:after{ content:""; position:absolute; left:0; top:0; height:50%; width:30px; background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 15 15" preserveAspectRatio="none"><line x1="0" y1="-1" x2="15" y2="16" stroke="green" /></svg>') 0 0/100% 100%; } .box:after { transform:scaleY(-1); transform-origin:bottom; }
 <div class="box"></div> <div class="box" style="height:80px"></div>

在此处输入图片说明

You can also optimize the code and do it without pseudo element:

 .box { height: 50px; border: 2px solid green; border-left: 0; border-radius:0 5px 5px 0; margin:5px; background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 15 15" preserveAspectRatio="none"><line x1="0" y1="-1" x2="15" y2="16" stroke="green" /></svg>') top left/30px 50%, url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 15 15" preserveAspectRatio="none"><line x1="0" y1="16" x2="15" y2="-1" stroke="green" /></svg>') bottom left/30px 50%; background-repeat:no-repeat; }
 <div class="box"></div> <div class="box" style="height:80px"></div>

The same SVG can be used to obtain the first result where the arrow width is also dynamic. The trick is to only define the height and preserve the ratio:

 .box { height: 50px; border: 2px solid green; border-left: 0; border-radius:0 5px 5px 0; margin:5px; background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 15 15"><line x1="0" y1="-1" x2="15" y2="16" stroke="green" /></svg>') top left/auto 50%, url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 15 15"><line x1="0" y1="16" x2="15" y2="-1" stroke="green" /></svg>') bottom left/auto 50%; background-repeat:no-repeat; }
 <div class="box"></div> <div class="box" style="height:80px"></div>


You can easily add a coloration inside too.

With skew transformation:

 .box { height: 50px; border: 2px solid green; border-left: 0; border-radius:0 5px 5px 0; position:relative; overflow:hidden; z-index:0; margin:5px; } .box:before, .box:after{ content:""; position:absolute; z-index:-1; left:0; right:0; height:50%; border-left:3px solid green; background:yellow; } .box:before { top:0; transform:skew(45deg); transform-origin:top; } .box:after { bottom:0; transform:skew(-45deg); transform-origin:bottom; }
 <div class="box"></div> <div class="box" style="height:80px"></div>

With the SVG background

 .box { height: 50px; padding-left:30px; border: 2px solid green; border-left: 0; border-radius:0 5px 5px 0; margin:5px; background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 15 15" preserveAspectRatio="none"><polygon points="16,17 16,-2 0,-1 " fill="yellow" stroke="green" /></svg>') top left/30px 50%, url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 15 15" preserveAspectRatio="none"><polygon points="16,16 16,-2 0,16 " fill="yellow" stroke="green" /></svg>') bottom left/30px 50%, yellow content-box; background-repeat:no-repeat; }
 <div class="box"></div> <div class="box" style="height:80px"></div>

If you have white-on-white background, then you can use two css-triangles that one covers other and creates edge for ribbon. If you need some transparency, then you should rely on clip-path (check if support is proper for your users) OR some SVG elements.

 * { box-sizing: border-box; } .ribbon { width: 100%; height: 100px; border: 2px solid blue; position: relative; padding: 0 120px; line-height: 100px; text-align: center; font-size: 30px; } .ribbon:before, .ribbon:after { content: ''; width: 0; height: 0; border-top: 50px solid transparent; border-left: 100px solid green; border-bottom: 50px solid transparent; position: absolute; top: 0; left: 0; } .ribbon:after { border-left-color: white; left: -3px; }
 <div class="ribbon">CARRIER</div>


For less-hacky approach use simple background image.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM