Reputation:
Hi everyone I am trying to make a curved triangle speech bubble with the CSS ::after
pseudo-element.
I have created like this DEMO:
.test
{
position: relative;
width: 430px;
height: 175px;
padding: 0px;
background: #FFFFFF;
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius: 6px;
}
.test:after
{
content: '';
position: absolute;
border-style: solid;
border-width: 14px 14px 0;
border-color: #FFFFFF transparent;
display: block;
width: 0;
z-index: 1;
bottom: -14px;
left: 8px;
}
How do I do like the picture?
Upvotes: 1
Views: 2838
Reputation: 24559
you could use pseudo elements (and their trickery) to generate something similar to this:
div {
height: 200px;
width: 350px;
background: tomato;
margin: 50px;
position: relative;
display: inline-block;
}
div:before {
content: "";
position: absolute;
height: 40px;
width: 40px;
background: tomato;
bottom: 2%;
left: -15px;
border-radius: 0 0 100% 0;
-webkit-transform: rotate(35deg);
transform: rotate(35deg);
}
div:after {
content: "";
position: absolute;
height: 40px;
width: 10px;
background: white;
bottom: 7%;
left: -18px;
border-radius: 50%;
-webkit-transform: rotate(35deg);
transform: rotate(35deg);
}
<div>Hello world</div>
.test {
height: 200px;
width: 350px;
background: tomato;
border-radius: 5px;
position: relative;
margin: 20px;
}
.test:before {
content: "";
position: absolute;
height: 20px;
width: 20px;
background: tomato;
bottom: 20px;
left: -6px;
transform-origin: center center;
transform: rotate(30deg);
border-radius: 0 0 100% 0;
}
.test:after {
content: "";
position: absolute;
height: 20px;
width: 10px;
background: white;
bottom: 24px;
left: -11px;
border-radius: 50%;
transform-origin: center center;
transform: rotate(30deg);
}
.zoom {
margin: 0 auto;
height: 200px;
width: 200px;
background: red;
position: relative;
border-radius: 0 0 100% 0;
transform-origin:center center;
transform: rotate(45deg);
margin-top:50px;
}
.zoom:before {
content: "";
position: absolute;
height: 100%;
width: 50%;
background: white;
border-radius: 50%;
left: -25%; top: 0;
}
<div class="test">hello world</div>
<hr/>
<div class="zoom"></div>
tested in Chrome, IE and Firefox (latest versions)
Upvotes: 5
Reputation: 64174
Just another posibility, so that you can choose
.test:after {
content: '';
position: absolute;
border: 0px solid;
display: block;
width: 0;
z-index: -1;
bottom: 30px;
left: -13px;
width: 40px;
height: 40px;
background-color: transparent;
border-bottom-left-radius: 50%;
border-bottom-right-radius: 50%;
box-shadow: 14px 10px 0px 10px white;
}
Upvotes: 2
Reputation: 21086
To move the arrow to the left side, simply change the position of the pseudo element and the borders. At this time, however, I don't think it is possible to create a concave curve without introducing way more complexity, like clipping masks. It would be easier to create a .png image of the curved triangle in Photoshop or Illustrator and then position it next to the speech bubble as desired.
HTML:
<div class="container">
<div class="test"></div>
</div>
CSS:
body{
background-color:#000;
}
.container {
margin:0px auto;
width:500px;
margin-top:50px;
}
.test
{
position: relative;
width: 430px;
height: 175px;
padding: 0px;
background: #FFFFFF;
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius: 6px;
}
.test:after
{
content: '';
position: absolute;
border-style: solid;
border-width: 0px 0px 15px 16px;
border-color: #FFFFFF transparent;
display: block;
width: 0;
z-index: 1;
bottom: 4px;
left: -15px;
}
Upvotes: 0
Reputation: 277
Trying to achieve that curved triangle shape with pure CSS might be very tricky, so I'd suggest instead you create that shape in vector format, save it off as an SVG and use that in your :after
element.
Of course save off a PNG fallback for browsers that don't support SVG as well.
As others have already mentioned, a simple CSS potitioning change would get your :after
element in the bottom left-hand corner, but an SVG might be your only option to get the curved triangle shape.
Upvotes: 0
Reputation: 7423
It seems you're just positioning it at the bottom instead of the left...
.test:after {
content: '';
position: absolute;
border-style: solid;
border-width: 0 0 14px 14px;
border-color: #FFFFFF transparent;
display: block;
width: 0;
z-index: 1;
bottom: 4px;
left: -14px;
}
However this won't replicate the image exactly, which instead shows a curve. While you could probably replicate that curve with nothing but a bunch of clever border tricks, it would make a lot more sense to use an image.
Upvotes: 0