How to create a speech bubble in css? - css

I would like to create a speech like this,
I try to create using CSS. But I cannot align the top arrow like this. My Code is,
.bubble
{
position: relative;
width: 275px;
height: 40px;
padding: 5px;
background: #C00006;
-webkit-border-radius: 14px;
-moz-border-radius: 14px;
border-radius: 14px;
}
.bubble:after
{
content: '';
position: absolute;
border-style: solid;
border-width: 0 19px 79px;
border-color: #C00006 transparent;
display: block;
width: 0;
z-index: 1;
margin-left: -19px;
top: -79px;
left: 69%;
}
<br><br><br><br>
<div class="bubble"></div>
Online example (on JSFiddle).

You could achieve that by using skewX transform and specifying the origin of the transform as follows:
.bubble {
position: relative;
top: 4.8em;
width: 275px;
height: 40px;
padding: 5px;
background: #C00006;
-webkit-border-radius: 14px;
-moz-border-radius: 14px;
border-radius: 14px;
}
.bubble:after {
content: '';
position: absolute;
border-style: solid;
border-width: 0 19px 79px;
border-color: #C00006 transparent;
display: block;
width: 0;
z-index: 1;
/* top: -79px; */
bottom: 100%; /* better than specifying the top */
right: 38px; /* equal to width of the arrow, for instance */
-webkit-transform: skewX(-45deg);
-moz-transform: skewX(-45deg);
-ms-transform: skewX(-45deg);
-o-transform: skewX(-45deg);
transform: skewX(-45deg);
-webkit-transform-origin: 38px 100%;
-moz-transform-origin: 38px 100%;
-ms-transform-origin: 38px 100%;
-o-transform-origin: 38px 100%;
transform-origin: 38px 100%;
}
<div class="bubble"></div>
It's worth noting that CSS transforms are supported in IE 9 and newer.

You can use the CSS3 skew() method on your :after psuedo selector like this:
.bubble:after {
-ms-transform: skew(-40deg, 0deg);
-webkit-transform: skew(-40deg, 0deg);
transform: skew(-40deg, 0deg);
}
Here's a jsFiddle Demo.
.bubble {
position: relative;
width: 275px;
height: 40px;
padding: 5px;
background: #C00006;
-webkit-border-radius: 14px;
-moz-border-radius: 14px;
border-radius: 14px;
}
.bubble:after {
content: '';
position: absolute;
border-style: solid;
border-width: 0 27px 79px;
border-color: #C00006 transparent;
display: block;
width: 0;
z-index: 1;
margin-left: -19px;
top: -79px;
left: 69%;
-ms-transform: skew(-40deg, 0deg);
-webkit-transform: skew(-40deg, 0deg);
transform: skew(-40deg, 0deg);
}
<br/>
<br/>
<br/>
<br/>
<div class="bubble"></div>

try this http://jsfiddle.net/harshdand/gczu8w4e/
.bubble:after
{
content: '';
position: absolute;
border-style: solid;
border-width: 0 19px 120px;
border-color: #C00006 transparent;
display: block;
width: 0;
z-index: 1;
margin-left: -49px;
top: -79px;
left: 95%;
-ms-transform: (50deg);
-webkit-transform: rotate(50deg);
transform: rotate(50deg);
}
transform: rotate(50deg);
edit
usw skew instead of rotate . see the snippet with minimal CSS
transform: skew(-45deg);
.bubble {
position: relative;
bottom: -70px;
width: 275px;
height: 40px;
padding: 5px;
background: #C00006;
border-radius: 14px;
}
.bubble:after {
content: '';
position: absolute;
border-style: solid;
border-width: 0 19px 79px;
border-color: #C00006 transparent;
width: 1px;
z-index: 1;
bottom: 95%;
left: 79%;
transform: skew(-45deg);
}
<div class="bubble"></div>

Related

Firefox-CSS: border-radius issue for pseudo-element "before"

I have a card-element (bootstrap-4) with a front and back, on hover the back side is shown.
In order to create a "folded corner effect" I am using a pseudo-element(:before) on the front card, which works fine for all browsers except of firefox.
The bottom-left corner of the pseudo-element should also be rounded, so I set a border-radius. Unfortunately in Firefox the corner is not rounded, instead there is a strange box shown in the pseudo-element.
Any ideas what is causing this issue in Firefox? I already played around with positioning, z-index, overflow etc. but I cannot find the root cause.
Thanks a lot in advance!!
https://jsfiddle.net/rbv5ob20/
HTML:
.card {
color: white;
border: transparent;
border-radius: 10px;
-webkit-box-shadow: -4px 4px 5px 0px rgba(50, 50, 50, 0.2);
box-shadow: -4px 4px 5px 0px rgba(50, 50, 50, 0.2);
}
.front,
.back {
width: 100%;
height: 150px;
background: #99d0e9;
opacity: 1;
backface-visibility: hidden;
overflow: hidden;
border-radius: 10px 0px 10px 10px;
}
.front {
position: absolute;
left: 0;
z-index: 1;
opacity: 1;
text-align: left;
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
}
.front::before {
content: "";
position: absolute;
top: 0px;
right: 0px;
border-width: 0px 25px 25px 0px;
border-style: solid;
border-color: transparent #f6f6f6 #32a2d4 transparent;
border-bottom-left-radius: 10px;
}
.back {
background: #32a2d4;
opacity: 1;
-webkit-transform: rotateY(-180deg);
-ms-transform: rotateY(-180deg);
transform: rotateY(-180deg);
text-align: right;
border-top-right-radius: 10px;
display: block;
}
.card:hover .back {
-webkit-transform: rotateY(0);
-ms-transform: rotateY(0);
transform: rotateY(0);
}
.card:hover .front {
-webkit-transform: rotateY(180deg);
-ms-transform: rotateY(180deg);
transform: rotateY(180deg);
}
<section id="offering" style="background-color:#f6f6f6;">
<div class="container">
<div class="col-4 text-center">
<div class="card">
<div class="front">
this is front...
</div>
<div class="back">
this is back
</div>
</div>
</div>
</div>
</section>
In Firefox border-radius doesn't seem to get properly applied to elements with a width and height of 0. A possible workaround to this would be to make a wrapper with overflow: hidden and a border-radius on its own:
.roundArrow {
border-radius: 0 0 0 10px;
width: 50px;
height: 50px;
overflow: hidden;
}
.roundArrow:after {
content: "";
display: block;
top: 0px;
right: 0px;
border-width: 0px 50px 50px 0px;
border-style: solid;
border-color: transparent #f6f6f6 #32a2d4 transparent;
}
<div class="roundArrow"></div>
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.card {
color: white;
border: transparent;
border-radius: 10px ;
-webkit-box-shadow: -4px 4px 5px 0px rgba(50, 50, 50, 0.2);
box-shadow: -4px 4px 5px 0px rgba(50, 50, 50, 0.2);
}
.front, .back {
width: 100%;
height:150px;
background: #99d0e9;
opacity: 1;
backface-visibility: hidden;
overflow: hidden;
border-radius: 10px 0px 10px 10px;
}
.front {
position: absolute;
left: 0;
z-index: 1;
opacity:1;
text-align:left;
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
}
.front::before {
content: "";
position: absolute;
top: 0px;
right: 0px;
border-bottom-left-radius: 10px;
height: 25px;
width: 25px;
background: #32a2d4;
}
.front::after {
content: "";
position: absolute;
top: -11px;
right: -17px;
height: 28px;
width: 35px;
background: white;
transform: rotate(45deg);
}
.back {
background: #32a2d4;
opacity: 1;
-webkit-transform: rotateY(-180deg);
-ms-transform: rotateY(-180deg);
transform: rotateY(-180deg);
text-align:right;
border-top-right-radius: 10px;
display: block;
}
.card:hover .back {
-webkit-transform: rotateY(0);
-ms-transform: rotateY(0);
transform: rotateY(0);
}
.card:hover .front {
-webkit-transform: rotateY(180deg);
-ms-transform: rotateY(180deg);
transform: rotateY(180deg);
}
</style>
</head>
<body>
<section id="offering" style="background-color:#f6f6f6;">
<div class="container">
<div class="col-4 text-center">
<div class="card">
<div class="front">
this is front...
</div>
<div class="back">
this is back
</div>
</div>
</div>
</div>
</section>
</body>
</html>
Following changes of ::before pseudo-element may work for you and you also have to add ::after pseudo-element for this solution.
.front::before {
content: "";
position: absolute;
top: 0px;
right: 0px;
border-bottom-left-radius: 10px;
height: 25px;
width: 25px;
background: #32a2d4;
}
.front::after {
content: "";
position: absolute;
top: -11px;
right: -15px;
height: 25px;
width: 35px;
background: white;
transform: rotate(40deg);
}

Skew one side only of an element [duplicate]

This question already has answers here:
CSS3 Transform Skew One Side
(5 answers)
Closed 2 years ago.
I'm tying to get a result as this image :
I tried that :
#parallelogram-container {
margin: 0 50px;
}
.parallelogram {
background: #008dd0;
width: 200px;
border: none;
display: inline-block;
height: 90px;
-moz-transform: scaleX(1) scaleY(1) scaleZ(1) skewX(-20deg);
-webkit-transform: scaleX(1) scaleY(1) scaleZ(1) skewX(-20deg);
transform: scaleX(1) scaleY(1) scaleZ(1) skewX(-20deg);
transform-origin: 50% 50%;
padding: 0px;
margin: 0 1px;
}
.parallelogram:first-child {
border-bottom-left-radius: 5px;
border-top-left-radius: 5px;
}
.parallelogram-btn {
width: 60px;
background: #ffa008;
color: #FFF;
border: none;
display: inline-block;
height: 90px;
-moz-transform: scaleX(1) scaleY(1) scaleZ(1) skewX(-20deg);
-webkit-transform: scaleX(1) scaleY(1) scaleZ(1) skewX(-20deg);
transform: scaleX(1) scaleY(1) scaleZ(1) skewX(-20deg);
border-bottom-right-radius: 5px;
border-top-right-radius: 5px;
transform-origin: 50% 50%;
padding: 0px;
margin: 0px;
font-weight: 700;
cursor: pointer;
}
<div id="parallelogram-container">
<div class="parallelogram"> </div>
<div class="parallelogram"> </div>
<a class="parallelogram-btn"> </a>
</div>
I cannot achieve this like the image : first parallelogram not skrewed on his left side and last parallelogram not skrewed on his right side.
Can someone help me please ?
See Snippet
#parallelogram-container {
margin: 0 50px;
}
.parallelogram {
position: relative;
background: #008dd0;
width: 100px;
border: none;
display: inline-block;
height: 90px;
padding: 0px;
margin: 0 1px;
}
.parallelogram:nth-child(1) {}
.parallelogram:nth-child(2) {
transform-origin: bottom left;
-ms-transform: skew(-28deg, 0deg);
-webkit-transform: skew(-28deg, 0deg);
transform: skew(-28deg, 0deg);
margin-left: 1px;
}
.parallelogram:nth-child(1):after {
content: " ";
position: absolute;
display: block;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: -1;
background: #008dd0;
transform-origin: bottom left;
-ms-transform: skew(-28deg, 0deg);
-webkit-transform: skew(-28deg, 0deg);
transform: skew(-28deg, 0deg);
}
.parallelogram-btn:before {
content: " ";
position: absolute;
display: block;
width: 100%;
height: 100%;
left: -51px;
z-index: -1;
background: #ffa008;
transform-origin: bottom left;
-ms-transform: skew(-28deg, 0deg);
-webkit-transform: skew(-28deg, 0deg);
transform: skew(-28deg, 0deg);
}
.parallelogram:first-child {
border-bottom-left-radius: 5px;
border-top-left-radius: 5px;
}
.parallelogram-btn {
width: 60px;
position: relative;
background: #ffa008;
color: #FFF;
border: none;
display: inline-block;
height: 90px;
border-bottom-right-radius: 5px;
border-top-right-radius: 5px;
padding: 0px;
margin-left: 51px;
font-weight: 700;
cursor: pointer;
}
<div id="parallelogram-container">
<div class="parallelogram"> </div>
<div class="parallelogram"> </div>
<a class="parallelogram-btn"> </a>
</div>
You can also achieve this simply with the following code. In this case only one div is needed.
From this point you can of course fine tune everything but this is just to give you a rough idea.
HTML
<div class="box"></div>
CSS
.box{
width: 400px;
height: 100px;
background: #008dd0;
border-radius: 10px;
position: relative;
overflow: hidden;
}
.box:after{
content: '';
position: absolute;
top: 0;
right: 0;
width: 30%;
height: 100%;
background: #ffa008;
}
.box:before{
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%) skew(-10deg);
width: 40%;
height: 100%;
background: #008dd0;
border: 2px solid white;
border-width: 0 8px;
z-index: 100;
}
.box {
width: 400px;
height: 100px;
background: #008dd0;
border-radius: 10px;
position: relative;
overflow: hidden;
}
.box:after {
content: '';
position: absolute;
top: 0;
right: 0;
width: 30%;
height: 100%;
background: #ffa008;
}
.box:before {
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%) skew(-10deg);
width: 40%;
height: 100%;
background: #008dd0;
border: 2px solid white;
border-width: 0 8px;
z-index: 100;
}
<div class="box"></div>

full width responsive arrow on bottom of div

Hee!
Currently I'm trying to make the following nav
but ending up getting the following
How can I lower the height of the arrow I'm adding at the bottom but keeping the full width?
nav {
position: relative;
display: inline-block;
height: 50px;
width: 100%;
text-align: center;
color: white;
background: gray;
line-height: 50px;
text-decoration: none;
padding-bottom: 15%;
background-clip: content-box;
overflow: hidden;
}
nav:after {
content: "";
position: absolute;
top: 50px;
left: 0;
background-color: inherit;
padding-bottom: 50%;
width: 57.7%;
z-index: -1;
-webkit-transform-origin: 0 0;
-ms-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: rotate(-30deg) skewX(30deg);
-ms-transform: rotate(-30deg) skewX(30deg);
transform: rotate(-30deg) skewX(30deg);
}
<nav>nav</nav>
http://jsfiddle.net/v50wwuw6/
Using the border triangle technique with vw unit: http://jsfiddle.net/hamop5ca/
30px is the arrow height.
nav {
position: relative;
height: 50px;
width:100%;
background: gray;
}
nav:before {
content: "";
position: absolute;
top: 100%;
left: 0;
border-top: 30px solid red;
border-left: 50vw solid transparent;
border-right: 50vw solid transparent;
}
<nav>nav</nav>

:before / :after tag in inline css (workaround?)

So I'm trying to put animated css into an email signature. I got it to work in iOS / Mac email-clients, but Gmail and Outlook seem to block part of the code. Does anyone maybe know of a workaround?
The code that I use now in my email:
<!doctype HTML>
<html style="margin: 0; padding: 0;">
<head style="margin: 0; padding: 0;">
<style rel="stylesheet" style="margin: 0; padding: 0;" type="text/css">
* { margin: 0; padding: 0; }
.container {
background: #64B1EE;
width: 100%;
height: 100%;
position: absolute;
overflow: hidden;
}
.airplane {
position: absolute;
left: 40%;
top: 10%;
z-index: 3;
-webkit-animation: plainfly 10s linear infinite;
-o-animation: plainfly 10s linear infinite;
animation: plainfly 10s linear infinite;
}
.airplane div {
background: #F9FBFC;
border-radius: 100%;
width: 60px;
height: 60px;
position: absolute;
z-index: 1;
}
div.head {
top: 21px;
left: 83px;
width: 60px;
height: 25px;
border-radius: 100%;
}
div.body {
top: 20px;
left: 0;
width: 130px;
height: 26px;
border-radius: 40% 30% 20% 50%;
z-index: 1
}
div.lwing {
top: 7px;
left: 60px;
height: 21px;
width: 30px;
border-radius: 5px;
z-index: 0 ;
-webkit-transform: skew(51deg, 0deg);
-ms-transform: skew(51deg, 0deg);
-o-transform: skew(51deg, 0deg);
transform: skew(51deg, 0deg);
}
div.rwing {
top: 34px;
left: 57px;
height: 27px;
width: 35px;
border-radius: 5px;
z-index: 1;
box-shadow: 0px 6px 4px rgba(0, 0, 0, 0.16);
-webkit-transform: skew(-49deg, 0deg);
-ms-transform: skew(-49deg, 0deg);
-o-transform: skew(-49deg, 0deg);
transform: skew(-49deg, 0deg);
}
div.tale {
top: 15px;
left: 10px;
width: 16px;
height: 16px;
border-radius: 2px;
-webkit-transform: skew(35deg, -9deg);
-ms-transform: skew(35deg, -9deg);
-o-transform: skew(35deg, -9deg);
transform: skew(35deg, -9deg);
background: linear-gradient(0deg,#FFF, #BBDEFF);
}
div.window,
div.window:before,
div.window:after {
content: "";
top: 6px;
left: 48px;
width: 4px;
height: 4px;
border-radius: 30%;
background: #9AD0F5;
border: 1px solid #5093D1;
position: absolute;
}
div.window:before {
left: -12px;
top: -1px;
}
div.window:after {
left: 10px;
top: -1px;
}
div.window:nth-child(1){
left:81px
}
div.window:nth-child(2){
left:115px
}
div.window:nth-child(2):after {
border-top-right-radius: 8px;
width: 6px;
}
#-webkit-keyframes plainfly {
0% {
left: -10%;
-webkit-transform: scale(.4);
-ms-transform: scale(.4);
-o-transform: scale(.4);
transform: scale(.4);
}
50% {
left: 110%;
-webkit-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
51% {
-webkit-transform: rotateY(180deg);
-webkit-transform: rotateY(180deg);
-ms-transform: rotateY(180deg);
-o-transform: rotateY(180deg);
transform: rotateY(180deg);
}
100% {
left: -10%;
-webkit-transform: scale(1.4) rotateY(180deg);
-ms-transform: scale(1.4) rotateY(180deg);
-o-transform: scale(1.4) rotateY(180deg);
transform: scale(1.4) rotateY(180deg);
}
}
#-webkit-keyframes cloud {
0% { left: 15%; }
50% { left: 63%; }
100% { left: 15%; }
}
#-webkit-keyframes cloud_a {
0% { left: 62%; }
50% { left: 90%; }
100% { left: 62%; }
}
#-webkit-keyframes cloud_b {
0% { left: 50%; }
50% { left: 23%; }
100% { left: 50%; }
}
#-webkit-keyframes cloud_c {
0% { left: 37%; }
50% { left: 47%; }
100% { left: 37%; }
}
#-webkit-keyframes cloud_d {
0% { left: 25%; }
50% { left: 65%; }
100% { left: 25%; }
}
</style>
</head>
<body style="margin: 0; padding: 0;">
<div class="container" style="background: #64B1EE; height: 100%; margin: 0; overflow: hidden; padding: 0; position: absolute; width: 100%;"><airplane class="airplane" style="animation: plainfly 10s linear infinite; left: 40%; margin: 0; padding: 0; position: absolute; top: 10%; z-index: 3;"><div class="head" style="background: #F9FBFC; border-radius: 100%; height: 25px; left: 83px; margin: 0; padding: 0; position: absolute; top: 21px; width: 60px; z-index: 1;">
</div>
<div class="body" style="background: #F9FBFC; border-radius: 40% 30% 20% 50%; height: 26px; left: 0; margin: 0; padding: 0; position: absolute; top: 20px; width: 130px; z-index: 1;">
<div class="window" style="background: #9AD0F5; border: 1px solid #5093D1; border-radius: 30%; content: ""; height: 4px; left: 48px; margin: 0; padding: 0; position: absolute; top: 6px; width: 4px; z-index: 1;">
</div>
<div class="window" style="background: #9AD0F5; border: 1px solid #5093D1; border-radius: 30%; content: ""; height: 4px; left: 48px; margin: 0; padding: 0; position: absolute; top: 6px; width: 4px; z-index: 1;">
</div>
<div class="window" style="background: #9AD0F5; border: 1px solid #5093D1; border-radius: 30%; content: ""; height: 4px; left: 48px; margin: 0; padding: 0; position: absolute; top: 6px; width: 4px; z-index: 1;">
</div>
</div>
<div class="lwing" style="background: #F9FBFC; border-radius: 5px; height: 21px; left: 60px; margin: 0; padding: 0; position: absolute; top: 7px; transform: skew(51deg, 0deg); width: 30px; z-index: 0;">
</div>
<div class="rwing" style="background: #F9FBFC; border-radius: 5px; box-shadow: 0px 6px 4px rgba(0, 0, 0, 0.16); height: 27px; left: 57px; margin: 0; padding: 0; position: absolute; top: 34px; transform: skew(-49deg, 0deg); width: 35px; z-index: 1;">
</div>
<div class="tale" style="background: linear-gradient(0deg,#FFF, #BBDEFF); border-radius: 2px; height: 16px; left: 10px; margin: 0; padding: 0; position: absolute; top: 15px; transform: skew(35deg, -9deg); width: 16px; z-index: 1;">
</div></airplane></div>
</body>
</html>
Jsfiddle to make it easier: https://jsfiddle.net/rvrvbtL9/
Any help would be greatly appreciated! Thanks in advance.
The problem you are having is created by the email clients removing everything within a <style> tag. Email clients all process HTML emails different and most of the time you will have to use limited inline styles with a table based layout for best compatiblity.
This is a great resource.
MattSizzle has already written everything I was planning to say about CSS in emails and email clients (along with the same reference link).
In your case, using an animated GIF instead of a CSS animation might be a good practice. It has better browser compatibility as seen here. Nevertheless, animated GIF in email has its own drawbacks, such as "some Outlook versions not showing the animation but the first frame only". Take a look at the article. It may help.
The issue is that Gmail will allow styles but they must NOT be in the body, the previous poster is correct that they require inline css and nothing global. They also strip the HEAD. They strip out class, id and styles from the body. Also no positioning may NOT be used even if its inline. Images need to be on a publicly accessible server, Outlook for instance will not handle base64 encoded images.
Your solution: Remove your classes, all positioning code, HEAD, and convert everything inline. You can use this tool to help you do that: MailChimp Inline converter Instead of positioning, tables are your friend.
Litmus is a fantastic tool to view your html in several clients.

Angled, wrapping CSS ribbon over image

It is possible to achieve this ribbon using only CSS?
.box {
width: 300px;
height: 300px;
background-color: #a0a0a0;
position: relative;
}
.ribbon {
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
border: 25px solid transparent;
border-top: 25px solid #757575;
position: absolute;
bottom: 20px;
right: -50px;
padding: 0 10px;
width: 120px;
color: white;
font-family: sans-serif;
size: 11px;
}
.ribbon .txt {
position: absolute;
top: -20px;
left: 20px;
}​
<div class="box">
<div class="ribbon">
<div class="txt">
Example Text
</div>
</div>
<div>​

Resources