user4082764
user4082764

Reputation:

How to make a curved triangle speech bubble with pseudo-elements?

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?

enter image description here

Upvotes: 1

Views: 2838

Answers (5)

jbutler483
jbutler483

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

vals
vals

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;
}

codepen

Upvotes: 2

TylerH
TylerH

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.

CodePen Example

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

Jamie Wade
Jamie Wade

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

Semicolon
Semicolon

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

Related Questions