How do I add negative radius to half circle? - html

I want to do this:
So far I got this:
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: #red;
z-index: 10000;
height: 10px;
overflow: visible;
}
.header:after {
content: '';
position: relative;
top: 100%;
display: block;
margin: 0 auto;
background: red;
width: 50px;
height: 25px;
border-radius: 10px 10px 50px 50px;
}
<div class="header"></div>
Codepen.
I can't get the top radius to go outwards the half circle like in the image.
How to do this with CSS?

You cannot make a negative radius on a border.
There is the possibility to make an SVG path or radial gradient... I made a new div as circle and radial gradient on pseudo-elements. It's not perfect, but it will possibly show you the direction to solution :)
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: red;
z-index: 10000;
height: 10px;
overflow: visible;
}
.header-circ {
position: relative;
top: 100%;
display: block;
margin: 0 auto;
background: red;
width: 500px;
height: 250px;
border-radius: 10px 10px 250px 250px;
}
.header-circ::before, .header-circ::after {
content: "";
position: absolute;
width: 100px;
height: 100px;
z-index: -1;
}
.header-circ::before {
left:-94px;
background: radial-gradient(circle at bottom left, white 0%,white 75%,red 75%);
}
.header-circ::after {
right:-94px;
background: radial-gradient(circle at bottom right, white 0%,white 75%,red 75%);
}
<div class="header"></div>
<div class="header-circ"></div>

Related

Create right responsive arrow [duplicate]

I am trying to create an arrow label, using css :after
.one-line {
font-size: 2em;
width: 150px;
min-height: 50px;
height: auto;
background: blue;
margin: 5px;
position: relative;
color: #fff;
}
.one-line:after {
content: '';
display: block;
position: absolute;
top: 0;
left: 100%;
width: 0;
height: 0;
border-top: 25px solid transparent;
border-bottom: 25px solid transparent;
border-left: 25px solid red;
}
<div class="one-line">text<br>text<br></div>
I want the after element to take the same height which is of parent, how can I do this by either css or js?
Note: The text inside the label is dynamically populating. [Max length of text: 2 lines]
It might not be possible, as I am thinking, to adjust it any height of parent. Currently I am trying it to adjust for both one and two lines of text.
Here is a solution using clip-path. The idea is to use % values in the polygon to only show the needed shape and it will always work whatever the height is:
.one-line {
font-size: 2em;
width: 150px;
min-height: 50px;
height: auto;
background: blue;
margin: 5px;
position: relative;
color: #fff;
}
.one-line:after {
content: '';
display: block;
position: absolute;
top: 0;
bottom: 0;
width: 25px;
right: -25px;
background: red;
-webkit-clip-path: polygon(100% 50%, 0 0, 0 100%);
clip-path: polygon(100% 50%, 0 0, 0 100%);
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>
<div class="one-line">text</div>
<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>
Here is another solution that rely on both pseudo elements and some skew transformation to create the arrow. You will notice that this one will keep ratio of the arrow.
.one-line {
font-size: 2em;
width: 150px;
min-height: 50px;
height: auto;
background: blue;
margin: 5px;
position: relative;
color: #fff;
}
.one-line:after {
content: '';
display: block;
position: absolute;
top: 0;
height: 50%;
width: 50%;
right: -25px;
background: red;
transform: skewX(20deg) translateX(-33%);
transform-origin: top;
z-index: -1;
}
.one-line:before {
content: '';
display: block;
position: absolute;
bottom: 0;
height: 50%;
width: 50%;
right: -25px;
background: red;
transform: skewX(-20deg) translateX(-33%);
transform-origin: bottom;
z-index: -1;
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>
<div class="one-line">text</div>
<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>
Another way with only one pseudo element and linear-gradient.
.one-line {
font-size: 2em;
width: 150px;
min-height: 50px;
height: auto;
background: blue;
margin: 5px;
position: relative;
color: #fff;
}
.one-line:after {
content: '';
display: block;
position: absolute;
top: 0;
height: 100%;
width: 50px;
right: -50px;
background:
linear-gradient(to bottom left, transparent 49.4%, red 50%) top,
linear-gradient(to top left, transparent 49.4%, red 50%) bottom;
background-size:100% 50.2%;
background-repeat:no-repeat;
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>
<div class="one-line">text</div>
<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>
And finally without any pseudo element and only background on the main element:
.one-line {
font-size: 2em;
width: 200px;
padding-left:50px;
min-height: 50px;
height: auto;
background:
linear-gradient(blue,blue) left/calc(100% - 50px) 100%,
linear-gradient(to bottom left, transparent 49.4%, red 50%) top right/50px 50.2%,
linear-gradient(to top left, transparent 49.4%, red 50%) bottom right/50px 50.2%;
background-repeat:no-repeat;
margin: 5px;
position: relative;
color: #fff;
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>
<div class="one-line">text</div>
<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>
Well, you could opt to keep the arrow the same size and align it in the middle by changing top to top: 50%; and adding transform: translateY(-50%);
.one-line{
width: 150px;
min-height: 50px;
height: auto;
background: blue;
margin: 5px;
position: relative;
color: #fff;
}
.one-line:after{
content: '';
display: block;
position: absolute;
left: 100%;
width: 0;
height: 0;
border-top: 25px solid transparent;
border-bottom: 25px solid transparent;
border-left: 25px solid red;
top: 50%;
transform: translateY(-50%);
}
<div class="one-line">text<br>text<br>text<br>text</div>
<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text</div>
using an svg path as a background-image, you could stretch the background-size property to 100% 100%. Just make sure the svg has preserveAspectRatio="none"
.one-line:after {
background-image: url('data:image/svg+xml;charset=UTF-8,<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" preserveAspectRatio="none" viewBox="0 0 25.1 50" style="enable-background:new 0 0 25.1 50;" xml:space="preserve"><polygon class="st0" points="0,50 0,50 25,25 0,0" fill="#ff0000"/></svg>');
position: absolute;
top: 0;
left:100%;
height: 100%;
width: 25px;
background-size: 100% 100%;
background-repeat:no-repeat;
display: block;
content:'';
}
https://jsfiddle.net/7jm54u6L/

Dynamically aligning pseudo element according to parent height

I am trying to create an arrow label, using css :after
.one-line {
font-size: 2em;
width: 150px;
min-height: 50px;
height: auto;
background: blue;
margin: 5px;
position: relative;
color: #fff;
}
.one-line:after {
content: '';
display: block;
position: absolute;
top: 0;
left: 100%;
width: 0;
height: 0;
border-top: 25px solid transparent;
border-bottom: 25px solid transparent;
border-left: 25px solid red;
}
<div class="one-line">text<br>text<br></div>
I want the after element to take the same height which is of parent, how can I do this by either css or js?
Note: The text inside the label is dynamically populating. [Max length of text: 2 lines]
It might not be possible, as I am thinking, to adjust it any height of parent. Currently I am trying it to adjust for both one and two lines of text.
Here is a solution using clip-path. The idea is to use % values in the polygon to only show the needed shape and it will always work whatever the height is:
.one-line {
font-size: 2em;
width: 150px;
min-height: 50px;
height: auto;
background: blue;
margin: 5px;
position: relative;
color: #fff;
}
.one-line:after {
content: '';
display: block;
position: absolute;
top: 0;
bottom: 0;
width: 25px;
right: -25px;
background: red;
-webkit-clip-path: polygon(100% 50%, 0 0, 0 100%);
clip-path: polygon(100% 50%, 0 0, 0 100%);
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>
<div class="one-line">text</div>
<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>
Here is another solution that rely on both pseudo elements and some skew transformation to create the arrow. You will notice that this one will keep ratio of the arrow.
.one-line {
font-size: 2em;
width: 150px;
min-height: 50px;
height: auto;
background: blue;
margin: 5px;
position: relative;
color: #fff;
}
.one-line:after {
content: '';
display: block;
position: absolute;
top: 0;
height: 50%;
width: 50%;
right: -25px;
background: red;
transform: skewX(20deg) translateX(-33%);
transform-origin: top;
z-index: -1;
}
.one-line:before {
content: '';
display: block;
position: absolute;
bottom: 0;
height: 50%;
width: 50%;
right: -25px;
background: red;
transform: skewX(-20deg) translateX(-33%);
transform-origin: bottom;
z-index: -1;
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>
<div class="one-line">text</div>
<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>
Another way with only one pseudo element and linear-gradient.
.one-line {
font-size: 2em;
width: 150px;
min-height: 50px;
height: auto;
background: blue;
margin: 5px;
position: relative;
color: #fff;
}
.one-line:after {
content: '';
display: block;
position: absolute;
top: 0;
height: 100%;
width: 50px;
right: -50px;
background:
linear-gradient(to bottom left, transparent 49.4%, red 50%) top,
linear-gradient(to top left, transparent 49.4%, red 50%) bottom;
background-size:100% 50.2%;
background-repeat:no-repeat;
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>
<div class="one-line">text</div>
<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>
And finally without any pseudo element and only background on the main element:
.one-line {
font-size: 2em;
width: 200px;
padding-left:50px;
min-height: 50px;
height: auto;
background:
linear-gradient(blue,blue) left/calc(100% - 50px) 100%,
linear-gradient(to bottom left, transparent 49.4%, red 50%) top right/50px 50.2%,
linear-gradient(to top left, transparent 49.4%, red 50%) bottom right/50px 50.2%;
background-repeat:no-repeat;
margin: 5px;
position: relative;
color: #fff;
}
<div class="one-line">text<br>text<br></div>
<div class="one-line">text<br>text<br>text<br></div>
<div class="one-line">text</div>
<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>
Well, you could opt to keep the arrow the same size and align it in the middle by changing top to top: 50%; and adding transform: translateY(-50%);
.one-line{
width: 150px;
min-height: 50px;
height: auto;
background: blue;
margin: 5px;
position: relative;
color: #fff;
}
.one-line:after{
content: '';
display: block;
position: absolute;
left: 100%;
width: 0;
height: 0;
border-top: 25px solid transparent;
border-bottom: 25px solid transparent;
border-left: 25px solid red;
top: 50%;
transform: translateY(-50%);
}
<div class="one-line">text<br>text<br>text<br>text</div>
<div class="one-line">text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text</div>
using an svg path as a background-image, you could stretch the background-size property to 100% 100%. Just make sure the svg has preserveAspectRatio="none"
.one-line:after {
background-image: url('data:image/svg+xml;charset=UTF-8,<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" preserveAspectRatio="none" viewBox="0 0 25.1 50" style="enable-background:new 0 0 25.1 50;" xml:space="preserve"><polygon class="st0" points="0,50 0,50 25,25 0,0" fill="#ff0000"/></svg>');
position: absolute;
top: 0;
left:100%;
height: 100%;
width: 25px;
background-size: 100% 100%;
background-repeat:no-repeat;
display: block;
content:'';
}
https://jsfiddle.net/7jm54u6L/

Add triangle to top of div with background image in CSS

I'm trying to add a point/triangle to my div with a background image but am struggling with how to create enough empty space.
Here's what I'm going for:
Here's what I have so far:
<div class="bg"></div>
.bg {
position: relative;
background: url('http://i.imgur.com/W27LCzB.jpg');
background-size: cover;
width: 100%;
padding-top: 50px;
height: 200px;
}
.bg:before {
content:'';
border-left: 50px solid #fff;
border-right: 50px solid #fff;
border-bottom: 50px solid transparent;
position:absolute;
top: 0;
left: 0;
right: 0;
margin: 0 auto;
width: 0;
}
I tried following this Stack Overflow question, but the approach in the top answer creates borders that come from the ends of the rectangular div.
Could achieve your design using another div. Hope you'll like it :)
.bg {
position: relative;
background: url('http://i.imgur.com/W27LCzB.jpg');
background-size: cover;
width: 100%;
padding-top: 50px;
height: 200px;
}
.bg:before {
content:'';
border-left: 50px solid #fff;
border-right: 50px solid #fff;
border-bottom: 50px solid transparent;
position:absolute;
top: 0;
left: 0;
right: 0;
margin: 0 auto;
width: 0;
}
.helper {
position: absolute;
height: 50px;
top: 0;
left: 0;
right: 0;
}
.helper:before, .helper:after {
content: "";
background: white;
position: absolute;
top: 0;
bottom: 0;
width: calc(50% - 50px);
}
.helper:before {left: 0;}
.helper:after {right: 0;}
<div class="bg">
<div class="helper"></div>
</div>
You can achieve what you want by using pseudo element and skew them to get the shape border
.bg {
position: relative;
background: url('http://i.imgur.com/W27LCzB.jpg');
background-size: cover;
width: 100%;
padding-top: 50px;
height: 200px;
overflow: hidden;
}
.bg:before {
content: '';
background: #fff;
position: absolute;
top: 0;
right: calc(50% + 20px);
width: 150%;
height: 50px;
transform: skewX(-40deg);
}
.bg:after {
content: '';
background: #fff;
position: absolute;
top: 0%;
left: calc(50% + 20px);
width: 150%;
height: 50px;
transform: skewX(40deg);
}
<div class="bg"></div>

Making rounded triangle shape using CSS

I have been trying to create this shape in the bottom left and top right corners of the page. Unfortunately, I have not been able to create the desired look the closest that I have been able to achieve is a pie shape with the following code:
<style>
/* css code that will create, color, and shape
the first accent color area */
#colorAreaOne{
width: 700px;
height: 700px;
background: #3333ff;
opacity: 0.8;
border-radius: 0 700px 0 0;
-moz-border-radius: 0 700px 0 0;
-webkit-border-radius: 0 700px 0 0;
position: fixed;
bottom: 0px;
left: 0px;
}
/* css code that will create, color, and shape
the second accent color area */
#colorAreaTwo{
width: 700px;
height: 700px;
background: #3333ff;
opacity: 0.8;
border-radius: 0 0 700px; 0;
-moz-border-radius: 0 0 700px 0;
-webkit-border-radius: 0 0 700px 0;
position: fixed;
top: 0px;
right: 0px;
}
</style>
If anyone has any information it would be much appreciated. Thank you!
A radial-gradient
div {
width: 700px;
height: 700px;
margin: 1em auto;
background-image: radial-gradient(circle at 100% 0, transparent 0%, transparent 700px, black 700px);
}
<div></div>
You may use a square and use a round pseudo to fill parts of it with a shadow
div {
height:50vw;
width:50vw;
bottom:0;
position:fixed;
overflow:hidden;
}
div:before {
content:'';
display:block;
height:100%;
border-radius:0 0 0 50% ;
box-shadow:0 0 0 50vw turquoise;
<div></div>
border-radius: 50%; overflow: hidden;
.shape{
width: 400px;
height: 400px;
overflow: hidden;
position: relative;
}
.shape:after{
content: "";
position: absolute;
left: -100%;
bottom: -100%;
width: 200%;
height: 200%;
-webkit-border-radius: 50%;
border-radius: 50%;
border: 400px solid;
<div class="shape"></div>
Here is one quick solution that will work if pseudo element is same color as background.
.el {
width: 200px;
height: 200px;
background: black;
position: relative;
overflow: hidden;
margin: 50px;
}
.el:before {
content: '';
position: absolute;
left: 0;
bottom: 0;
width: 200%;
height: 200%;
background: white;
border-radius: 50%;
}
<div class="el"></div>

CSS shape with inset curve and transparent background

I need to create a CSS shape like this image..
Please check this fiddle of my work
I have created something like that, but I cannot give a curve to it.
#shape {
border-left: 70px solid transparent;
border-top: 100px solid red;
height: 0;
width: 200px;
}
Can anyone help me?
You can use a pseudo element with border-radius and background-shadows to create the curve and enable a transparent background for the curve.
Output :
#shape {
width: 300px; height: 100px;
position: relative;
overflow: hidden;
}
#shape:before {
content: '';
position: absolute;
top: 10%; right: 0;
width: 300%;
padding-bottom: 300%;
border-radius: 100%;
background: none;
box-shadow: 10px -10px 5px 300px #F15723;
z-index: -1;
}
body{background:url(https://farm9.staticflickr.com/8461/8048823381_0fbc2d8efb.jpg);background-size:cover;}
<div id="shape"></div>
demo
Variant #01:
CSS3 linear-gradient() can draw this background as well:
CSS:
div {
background: linear-gradient(45deg, transparent 50px, tomato 50px);
}
Output Image:
body {
background: linear-gradient(lightgreen, green);
min-height: 100vh;
margin: 0;
}
div {
background: linear-gradient(45deg, transparent 50px, tomato 50px);
height: 150px;
margin: 20px;
width: 400px;
}
<div>
</div>
Variant #02:
We can use :before and :after pseudo elements and use css3 transformation to make this shape with round corners.
body {
background: linear-gradient(lightgreen, green);
min-height: 100vh;
margin: 0;
}
div {
border-radius: 10px;
position: relative;
overflow: hidden;
height: 150px;
margin: 20px;
width: 400px;
}
div:before {
border-radius: 0 0 10px 10px;
transform-origin: 100% 0;
transform: skewY(45deg);
background: tomato;
position: absolute;
width: 45px;
z-index: -1;
content: '';
bottom: -5px;
left: 0;
top: 0;
}
div:after {
border-radius: 0 10px 10px 10px;
background: tomato;
position: absolute;
content: '';
left: 35px;
bottom: 0;
right: 0;
top: 0;
}
<div>
</div>