Add a triangular point to a div that changes with the height of the content using CSS?

I have a div and I need to give it an angular point. The height will vary depending on its content, so using pseudo content and borders, as in the article below, will not work.

http://css-tricks.com/snippets/css/css-triangle/

enter image description here

Since this is a progressive improvement, I only need to support modern browsers.

+8
html css css3 css-shapes
source share
6 answers

Alternative answer using gradients and pseudo-elements

#one {height: 100px;} #two {height: 200px;} .corner { width: 100px; background-color: green; margin: 10px; position: relative; } .corner:after, .corner:before { content: ""; position: absolute; left: 100%; width: 40px; height: 50%; } .corner:before { top: 0px; background: linear-gradient(to top right, green 50%, transparent 51%); } .corner:after { bottom: 0px; background: linear-gradient(to bottom right, green 50%, transparent 51%); } 
 <div id="one" class="corner"></div> <div id="two" class="corner"></div> 
+7
source share

You can do this using svg .

svg 's (background) height completely dependent on #content ' s (text) height .

enter image description here

Demo in CodePen

 #container { position: relative; } svg { position: absolute; z-index: -1; } #content { position: relative; word-break: break-all; width: 110px; padding: 10px; box-sizing: border-box; } 
 <div id="container"> <svg id="bg" width="150" height="100%" viewBox="0 0 150 100" preserveAspectRatio="none"> <path d="M0,0 h110 l40,50 l-40,50 h-110z" fill="#6ED901" /> </svg> <div id="content">This content is dynamic and the height of the triangle will change with the height of the content. The width is fixed. Try adding some more text and see the height change. Also, notice the padding.</div> </div> 
+6
source share

CSS clip template

This uses the clip-path property, which is not supported by many modern browsers.

 #one { width: 300px; background-color:#6ED901; padding:10px; word-break: break-all; -webkit-clip-path: polygon(0% 0%, 75% 0%, 100% 50%, 75% 100%, 0% 100%); clip-path: polygon(0% 0%, 75% 0%, 100% 50%, 75% 100%, 0% 100%); } span{ width:240px; display:block; } 
 <div id="one"><span>Dynamic. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</span></div> 

CSS - Gradients

Browser support for CSS gradients is pretty good. Note that this is essentially the same as Vals , but only with dynamic height.

 .shape { width: 200px; background-color: #6ED901; position: relative; word-break:break-all; text-align: justify; padding: 10px 0 10px 10px; } .shape:after, .shape:before { content: ""; position: absolute; left: 100%; width: 80px; height: 50%; } .shape:before { top: 0px; background: linear-gradient(to top right, #6ED901 50%, transparent 51%); } .shape:after { bottom: 0px; background: linear-gradient(to bottom right, #6ED901 50%, transparent 51%); } 
 <div class="shape">Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi "Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi "Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi "Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi "Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi "Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi</div> 

CSS + JS

The following solution uses CSS and JS and runs a cross browser. JS was provided by web ticks.

 var height = document.getElementById('one').offsetHeight/2; document.getElementById('two').style.borderTopWidth = height + 'px'; document.getElementById('two').style.borderBottomWidth = height + 'px'; 
 *{ margin:0; padding:0; } #one{ width:200px; background-color:#6ED901; display:block; word-break: break-all; padding:10px; float:left; } #two{ display:block; float:left; position:absolute; left: 220px; width:0px; height: 0; border-style: solid; border-right-width:0; border-left-width:80px; border-color: transparent transparent transparent #6ED901; } 
 <div id="wrap"> <div id="one"> ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg</div> <div id="two"></div> </div> ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg <div id="wrap"> <div id="one"> ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg ghjg</div> <div id="two"></div> </div> 
+3
source share

I would try with SVG in the background:

 div { background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 100"><rect x="-5" y="-5" width="90" height="110" fill="#fff" /><polygon fill="green" points="0,0 80,50 0,100"/></svg>'); background-position:100% 50%; background-size:auto 100%; background-repeat:no-repeat; background-color:green; } 

http://jsfiddle.net/wm1am7ry/

Note. The SVG image has a white background and a green triangle. Therefore, it will not work if the background under the arrow is not a solid color.

If the width has been fixed, you can place the SVG in the generated content, located behind the green frame, which avoids the white background under the arrow:

http://jsfiddle.net/wm1am7ry/1/

 div { background-color:green; padding:20px; margin:10px 0; width:100px; position:relative; } div::after { content:""; display:block; position:absolute; top:0; bottom:0; left:100%; width:100%; background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 100"><polygon fill="green" points="0,0 80,50 0,100"/></svg>'); background-position:0 50%; background-size:auto 100%; background-repeat:no-repeat; } 
+2
source share

This can also be done using skew and rotation.

 .cont { margin: 20px 0; } .arrow { background: #6ED901; padding: 10px; position: relative; width: 100px; } .arrow:after { content: ''; position: absolute; width: 200%; height: 200%; background: #6ED901; top: 0; transform: skew(14deg, 19deg) rotate(43deg); transform-origin: right; z-index: -1; right: 0; } .cont { overflow: hidden; } 
 <div class="cont"> <div class="arrow">. Proin faucibus arcu quis ante.Proin faucibus arcu quis ante.Proin faucibus arcu quis ante.Proin faucibus arcu quis ante. Proin faucibus arcu quis ante.</div> </div> <div class="cont"> <div class="arrow">Proin faucibus arcu quis ante.Proin faucibus arcu.Proin faucibus arcu quis ante.Proin faucibus arcu.</div> </div> <div class="cont"> <div class="arrow">Proin faucibus arcu quis ante.Proin faucibus arcu.</div> </div> 
0
source share

I use the tool to trim shapes in div tags with this tool. You can easily draw shapes, as in this tool. https://bennettfeely.com/clippy/

0
source share

All Articles