Angled CSS Separator - css

Please see the below image...
I would like to make this via CSS.
I'm using this separator now as an image ( jpg ) that is responsive inside my container. The problem is that I can't seem to match colors exactly or get the white crystal clear and sharp.
I think CSS would be best way to solve this problem.
The dimensions are 1170px x 100px
Using Bootstrap 3.2
<div class="container">
<div class="row">
<img class="img-responsive" src="img/separator.gif">
</div>
</div>

Solution 1 : with borders with vw units :
DEMO (credits to Harry for the demo)
.separator{
width:95vw;
margin:0 auto;
}
.separator:before, .separator:after{
content:'';
display:block;
}
.separator:before{
border-left: 95vw solid #DA7317;
border-bottom: 60px solid transparent;
border-right:0;
border-top:0;
}
.separator:after{
border-right: 95vw solid #000;
border-top: 50px solid transparent;
border-left:0;
border-bottom:0;
margin-top:-45px;
}
<div class="separator">
</div>
Solution 2: with transform rotate :
DEMO
.separator{
position:relative;
padding-bottom:5.5%;
overflow:hidden;
}
.separator:before, .separator:after{
content:'';
position:absolute;
-webkit-backface-visibility:hidden;
}
.separator:before{
background: #DA7317;
bottom:100%; left:-1%;
width:101%; height:200%;
-webkit-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
transform-origin: 100% 100%;
-webkit-transform: rotate(-3deg);
-ms-transform: rotate(-3deg);
transform: rotate(-3deg);
}
.separator:after{
background: #000;
top:100%;
width:100%; height:100%;
-webkit-transform-origin: 0 0;
-ms-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: rotate(-2.5deg);
-ms-transform: rotate(-2.5deg);
transform: rotate(-2.5deg);
}
<div class="separator"></div>

Using SVG: Recommended
You could make use of SVG to create the shape. Since it is a separator (which implies, it is not going to contain any text within the shape), it is more like an image and SVG fits the case perfectly. SVG can auto-scale without having any impact to the actual shape and since it is vector based, it doesn't get pixelated on scaling either.
We can use either SVG path or polygons to create this shape. Below are the sample snippets.
/* Using SVG Path */
svg {
height: 100px;
width: 1170px;
}
path#top {
fill: rgb(218, 115, 23);
}
path#bottom {
fill: rgb(42, 42, 42);
}
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<path d='m 0,0 h 100 l -100,95z' id='top' />
<path d='m 0,100 h 100 l 0,-90z' id='bottom' />
</svg>
/* Using SVG Polygons */
svg {
height: 100px;
width: 1170px;
}
polygon#top {
fill: rgb(218, 115, 23);
}
polygon#bottom {
fill: rgb(42, 42, 42);
}
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<polygon points='0,0 100,0 0,95' id='top' />
<polygon points='0,100 100,100 100,10' id='bottom' />
</svg>
Using Gradients:
You could achieve the shape by using two linear-gradient for background and position them appropriately like in the below snippet. Linear gradients can scale without affecting the shape.
.separator {
height: 100px;
width: 1170px;
background-image: linear-gradient(to top left, rgba(0, 0, 0, 0) 49%, rgb(218, 115, 23) 50%),
linear-gradient(to top left, rgb(42, 42, 42) 49%, rgba(0, 0, 0, 0) 50%);
background-size: 100% 95%, 100% 90%;
background-position: 0% 0%, 0% 90%;
background-repeat: no-repeat;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="separator"></div>
None of the approaches produce a perfectly smooth output for the white colored area in the middle. While SVG produces more smoother edges, gradients produce a very rough/coarse output.

Related

Rounding corners of parallelogram made from clip-path CSS [duplicate]

I want to be able to round out the 3 leftmost corners on this shape that I have created, any idea how that can be done?
div {
position: absolute;
z-index: 1;
width: 423px;
height: 90px;
background-color: #b0102d;
color: white;
right: 0;
margin-top: 10vw;
-webkit-clip-path: polygon(100% 0%, 100% 50%, 100% 100%, 25% 100%, 0% 50%, 25% 0%);
clip-path: polygon(100% 0%, 100% 50%, 100% 100%, 25% 100%, 0% 50%, 25% 0%);
}
<div></div>
use inset with round property :
inset(0% 45% 0% 45% round 10px)
An SVG filter can round any kind of clip-path. You simply need to apply it to a parent element. Adjust the stdDeviation to control the radius:
.box {
width: 423px;
height: 90px;
background-color: #b0102d;
color: white;
clip-path: polygon(100% 0%, 100% 50%, 100% 100%, 25% 100%, 0% 50%, 25% 0%);
}
.parent {
filter: url('#goo');
overflow:hidden;
position: fixed;
right:-50px;
z-index: 1;
margin-top: 10vw;
}
<div class="parent">
<div class="box"></div>
</div>
<svg style="visibility: hidden; position: absolute;" width="0" height="0" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="goo"><feGaussianBlur in="SourceGraphic" stdDeviation="8" result="blur" />
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" />
<feComposite in="SourceGraphic" in2="goo" operator="atop"/>
</filter>
</defs>
</svg>
Related: https://stackoverflow.com/a/65485455/8620333
I've recently found success experimenting with approaches like this...
SVG
<svg width="0" height="0">
<defs>
<clipPath id="clipped">
<circle cx="var(--myRad)" cy="var(--myRad)" r="var(--myRad)"></circle>
<circle cx="var(--myRad)" cy="calc(var(--myHeight) - var(--myRad))" r="var(--myRad)"></circle>
<circle cx="calc(var(--myWidth) - var(--myRad))" cy="calc(var(--myHeight) - var(--myRad))" r="var(--myRad)"></circle>
<circle cx="calc(var(--myWidth) - var(--myRad))" cy="var(--myRad)" r="var(--myRad)"></circle>
<rect y="var(--myRad)" width="var(--myWidth)" height="calc(var(--myHeight) - (2 * var(--myRad)))"></rect>
<rect x="var(--myRad)" width="calc(var(--myWidth) - (2 * var(--myRad)))" height="var(--myHeight)"></rect>
</clipPath>
</defs>
</svg>
CSS
.clipped {
--myWidth: 100vw;
--myHeight: 10rem;
--myRad: 2rem;
clip-path: url(#clipped);
}
I found this useful as compared to using border-radius with overflow set to hidden, because this approach doesn't create a BFC or break things like sticky position and css perspective effects. Also, this allows you to "inset" the position of the svg paths to clip inside the element with a "corner-radius" if you want.
You can also mess around with the circle to get some different effects.
-webkit-clip-path: circle(60.0% at 50% 10%);
clip-path: circle(50.0% at 50% 50%);
Codepen
Too bad you can't combine the polygon and circle... or maybe you can and I haven't played around with it enough to figure it out. HTH
clip-path: inset(45% 0% 33% 10% round 10px)
I don't have a comment option yes, so I'm writing it as an answer..
you need to write as many points as possible to round the corner. Nothig else...
for, example a few more points to make lower part bit rounder:
-webkit-clip-path: polygon(100% 0%, 100% 100%, 100% 100%, 25% 100%, 5% 70%,1% 60%, 0% 50%, 25% 0%);
oh, yes, or SVG as comment people here.. :)
You could use a child element and do a nested clip-path on that and the child's pseudo element. The parent will do a polygon clip on the shape first, then the pseudo will have an ellipse to round the borders. The clips will have a combined effect.
.parent, .parent div, .parent div:before {
width: 423px;
height: 90px;
position: absolute;
}
.parent {
right: 0;
background-image: linear-gradient(to right, transparent 210px, #b0102d 210px);
margin-top: 15vh;
}
.parent div {
clip-path: polygon(100% 0%, 100% 100%, 25% 100%, 0 50%, 25% 0);
}
.parent div:before {
content: "";
background-color: #b0102d;
clip-path: ellipse(200px 45px at 210px);
}
<div class="parent">
<div></div>
</div>
Here is the demo with some adaptations to illustrate what's going on:
.parent, .parent div, .parent div:before {
width: 423px;
height: 90px;
position: absolute;
}
.parent {
right: 0;
background-image: linear-gradient(to right, transparent 210px, yellow 210px);
margin-top: 15vh;
}
.parent div {
background-color: blue;
clip-path: polygon(90% 0%, 90% 100%, 25% 100%, 0 50%, 25% 0);
}
.parent div:before {
content: "";
background-color: #b0102d;
clip-path: ellipse(200px 45px at 210px);
}
<div class="parent">
<div></div>
</div>
The horizontal size and position of the ellipse can be used to get a different effect on the edges. Note that the background starting postion of the parent needs to be adjusted to the same value as the placement of the ellipse (last value in the clip-path) because it fills up whatever gets clipped off on the right side. This can be visualised by removing background-color: blue from .parent div in the second demo.
Here is an additional Codepen to to try it out.

How to get rounded edges with clip path code? [duplicate]

I want to be able to round out the 3 leftmost corners on this shape that I have created, any idea how that can be done?
div {
position: absolute;
z-index: 1;
width: 423px;
height: 90px;
background-color: #b0102d;
color: white;
right: 0;
margin-top: 10vw;
-webkit-clip-path: polygon(100% 0%, 100% 50%, 100% 100%, 25% 100%, 0% 50%, 25% 0%);
clip-path: polygon(100% 0%, 100% 50%, 100% 100%, 25% 100%, 0% 50%, 25% 0%);
}
<div></div>
use inset with round property :
inset(0% 45% 0% 45% round 10px)
An SVG filter can round any kind of clip-path. You simply need to apply it to a parent element. Adjust the stdDeviation to control the radius:
.box {
width: 423px;
height: 90px;
background-color: #b0102d;
color: white;
clip-path: polygon(100% 0%, 100% 50%, 100% 100%, 25% 100%, 0% 50%, 25% 0%);
}
.parent {
filter: url('#goo');
overflow:hidden;
position: fixed;
right:-50px;
z-index: 1;
margin-top: 10vw;
}
<div class="parent">
<div class="box"></div>
</div>
<svg style="visibility: hidden; position: absolute;" width="0" height="0" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="goo"><feGaussianBlur in="SourceGraphic" stdDeviation="8" result="blur" />
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" />
<feComposite in="SourceGraphic" in2="goo" operator="atop"/>
</filter>
</defs>
</svg>
Related: https://stackoverflow.com/a/65485455/8620333
I've recently found success experimenting with approaches like this...
SVG
<svg width="0" height="0">
<defs>
<clipPath id="clipped">
<circle cx="var(--myRad)" cy="var(--myRad)" r="var(--myRad)"></circle>
<circle cx="var(--myRad)" cy="calc(var(--myHeight) - var(--myRad))" r="var(--myRad)"></circle>
<circle cx="calc(var(--myWidth) - var(--myRad))" cy="calc(var(--myHeight) - var(--myRad))" r="var(--myRad)"></circle>
<circle cx="calc(var(--myWidth) - var(--myRad))" cy="var(--myRad)" r="var(--myRad)"></circle>
<rect y="var(--myRad)" width="var(--myWidth)" height="calc(var(--myHeight) - (2 * var(--myRad)))"></rect>
<rect x="var(--myRad)" width="calc(var(--myWidth) - (2 * var(--myRad)))" height="var(--myHeight)"></rect>
</clipPath>
</defs>
</svg>
CSS
.clipped {
--myWidth: 100vw;
--myHeight: 10rem;
--myRad: 2rem;
clip-path: url(#clipped);
}
I found this useful as compared to using border-radius with overflow set to hidden, because this approach doesn't create a BFC or break things like sticky position and css perspective effects. Also, this allows you to "inset" the position of the svg paths to clip inside the element with a "corner-radius" if you want.
You can also mess around with the circle to get some different effects.
-webkit-clip-path: circle(60.0% at 50% 10%);
clip-path: circle(50.0% at 50% 50%);
Codepen
Too bad you can't combine the polygon and circle... or maybe you can and I haven't played around with it enough to figure it out. HTH
clip-path: inset(45% 0% 33% 10% round 10px)
I don't have a comment option yes, so I'm writing it as an answer..
you need to write as many points as possible to round the corner. Nothig else...
for, example a few more points to make lower part bit rounder:
-webkit-clip-path: polygon(100% 0%, 100% 100%, 100% 100%, 25% 100%, 5% 70%,1% 60%, 0% 50%, 25% 0%);
oh, yes, or SVG as comment people here.. :)
You could use a child element and do a nested clip-path on that and the child's pseudo element. The parent will do a polygon clip on the shape first, then the pseudo will have an ellipse to round the borders. The clips will have a combined effect.
.parent, .parent div, .parent div:before {
width: 423px;
height: 90px;
position: absolute;
}
.parent {
right: 0;
background-image: linear-gradient(to right, transparent 210px, #b0102d 210px);
margin-top: 15vh;
}
.parent div {
clip-path: polygon(100% 0%, 100% 100%, 25% 100%, 0 50%, 25% 0);
}
.parent div:before {
content: "";
background-color: #b0102d;
clip-path: ellipse(200px 45px at 210px);
}
<div class="parent">
<div></div>
</div>
Here is the demo with some adaptations to illustrate what's going on:
.parent, .parent div, .parent div:before {
width: 423px;
height: 90px;
position: absolute;
}
.parent {
right: 0;
background-image: linear-gradient(to right, transparent 210px, yellow 210px);
margin-top: 15vh;
}
.parent div {
background-color: blue;
clip-path: polygon(90% 0%, 90% 100%, 25% 100%, 0 50%, 25% 0);
}
.parent div:before {
content: "";
background-color: #b0102d;
clip-path: ellipse(200px 45px at 210px);
}
<div class="parent">
<div></div>
</div>
The horizontal size and position of the ellipse can be used to get a different effect on the edges. Note that the background starting postion of the parent needs to be adjusted to the same value as the placement of the ellipse (last value in the clip-path) because it fills up whatever gets clipped off on the right side. This can be visualised by removing background-color: blue from .parent div in the second demo.
Here is an additional Codepen to to try it out.

Double trapezium-like shape

I am busting my head with getting this double trapezium like shape on a webpage. The CSS class seen below creates a trapezium that could be duplicated and rotaded, I'm however insure how to expand it to the full width of the browser and make it responsive.
.warpedbanner {
border-right: 150px solid red;
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
height: 4em;
width: 4px;
}
You can check LINK for an shape.
div {
width: 400px;
height: 150px;
clip-path: polygon(50% 0%, 100% 15%, 100% 84%, 50% 100%, 0 85%, 0 18%);
background-color: red;
}
<div></div>
The above snippet will work in chrome but not in FireFox. Snippet which is working in both browser is given below
div {
width: 400px;
height: 150px;
background-color: red;
-webkit-clip-path: url("#clipping");
clip-path: url("#clipping");
}
<div></div>
<svg width='0' height='0'>
<defs>
<clipPath id="clipping" clipPathUnits="objectBoundingBox">
<polygon points="0 0.25, 0.5 0, 1 0.25, 1 0.75, 0.5 1,0 0.75" />
</clipPath>
</defs>
</svg>

Create a shape with three vertical lines (stripes) [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
How to create the 3 vertical lines as in the following image using CSS?
This is pretty easy to create with linear-gradient background images and we don't need more than one div element to create this with gradients. All we need is a couple of gradient images.
Below is an explanation of how the shape was achieved:
One linear gradient image which is 85% the size of the container in the X-axis and 75% the size of the container in the Y-axis is used to create the large white portion and it is positioned on left of the container.
One more linear gradient image which is 15% of the size of the container in X-axis and 15% of the container's size in Y-axis is used to create the three stripes at the end. The stripes are created by splitting the gradient into colored and transparent portions. The colored portions are sized equally to produce a stripe like effect.
Note: The third bar in the image in question seems to be a little lower than the others, I am assuming this to be an error in the image. If it is not, it could still be achieved with the below approach.
body {
background: yellow;
}
.shape {
height: 100px;
width: 400px;
transform: skew(-30deg);
transform-origin: left bottom;
background-image: linear-gradient(to left, rgba(255,255,255,0.5) 25%, transparent 25%, transparent 33%, rgba(255,255,255,0.75) 33%, rgba(255,255,255,0.5) 60%, transparent 60%, transparent 66%, rgba(255,255,255,1) 66%, rgba(255,255,255,0.75) 93%, transparent 93%), linear-gradient(white, white);
background-size: 15% 100%, 85% 75%;
background-position: 100% 100%, 0% 0%;
background-repeat: no-repeat;
}
<div class='shape'></div>
You could also make use of SVG path elements to create this shape.
.shape {
position: relative;
height: 100px;
width: 300px;
}
.shape svg {
position: absolute;
height: 100%;
width: 100%;
top: 0px;
left: 0px;
}
.shape svg path#white-bar {
fill: rgba(255, 255, 255, 1);
}
.shape svg path#translucent-bar-1 {
fill: rgba(255, 255, 255, 0.75);
}
.shape svg path#translucent-bar-2 {
fill: rgba(255, 255, 255, 0.5);
}
body {
background: yellow;
}
<div class='shape'>
<svg viewBox='0 0 300 100'>
<path d='M0,75 25,0 240,0, 221.5,75z M245,0 220,100 235,100 260,0' id='white-bar' />
<path d='M265,0 240,100 255,100 280,0' id='translucent-bar-1' />
<path d='M285,0 260,100 275,100 300,0' id='translucent-bar-2' />
</svg>
</div>
Note: It may well be possible to create this using a single path element and an angled gradient fill but I am not that good with SVG.
I did a fiddle.
trick is you need to transform the figure and use vertical-align property.
-webkit-transform: skew(20deg);
vertical-align: text-top;
Tweaking #Siddarth's code, this might be more suited to the above given image:
div{
display:inline-block;
vertical-align: text-top;
-webkit-transform: skew(-20deg);
-moz-transform: skew(-20deg);
-o-transform: skew(-20deg);
background: white;
}
.one{
width: 450px;
height: 100px;
}
div:not(.one){
margin-left:0px;
width: 20px;
height: 200px;
}
.two{
opacity:.8;
}
.three{
opacity:.6;
}
.four{
opacity:.4;
}
body {
background-color: rgb(255, 210, 2);
}
<body>
<div class="one">
</div>
<div class="two">
</div>
<div class="three">
</div>
<div class="four">
</div>
</body>

How to round out corners when using CSS clip-path

I want to be able to round out the 3 leftmost corners on this shape that I have created, any idea how that can be done?
div {
position: absolute;
z-index: 1;
width: 423px;
height: 90px;
background-color: #b0102d;
color: white;
right: 0;
margin-top: 10vw;
-webkit-clip-path: polygon(100% 0%, 100% 50%, 100% 100%, 25% 100%, 0% 50%, 25% 0%);
clip-path: polygon(100% 0%, 100% 50%, 100% 100%, 25% 100%, 0% 50%, 25% 0%);
}
<div></div>
use inset with round property :
inset(0% 45% 0% 45% round 10px)
An SVG filter can round any kind of clip-path. You simply need to apply it to a parent element. Adjust the stdDeviation to control the radius:
.box {
width: 423px;
height: 90px;
background-color: #b0102d;
color: white;
clip-path: polygon(100% 0%, 100% 50%, 100% 100%, 25% 100%, 0% 50%, 25% 0%);
}
.parent {
filter: url('#goo');
overflow:hidden;
position: fixed;
right:-50px;
z-index: 1;
margin-top: 10vw;
}
<div class="parent">
<div class="box"></div>
</div>
<svg style="visibility: hidden; position: absolute;" width="0" height="0" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="goo"><feGaussianBlur in="SourceGraphic" stdDeviation="8" result="blur" />
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" />
<feComposite in="SourceGraphic" in2="goo" operator="atop"/>
</filter>
</defs>
</svg>
Related: https://stackoverflow.com/a/65485455/8620333
I've recently found success experimenting with approaches like this...
SVG
<svg width="0" height="0">
<defs>
<clipPath id="clipped">
<circle cx="var(--myRad)" cy="var(--myRad)" r="var(--myRad)"></circle>
<circle cx="var(--myRad)" cy="calc(var(--myHeight) - var(--myRad))" r="var(--myRad)"></circle>
<circle cx="calc(var(--myWidth) - var(--myRad))" cy="calc(var(--myHeight) - var(--myRad))" r="var(--myRad)"></circle>
<circle cx="calc(var(--myWidth) - var(--myRad))" cy="var(--myRad)" r="var(--myRad)"></circle>
<rect y="var(--myRad)" width="var(--myWidth)" height="calc(var(--myHeight) - (2 * var(--myRad)))"></rect>
<rect x="var(--myRad)" width="calc(var(--myWidth) - (2 * var(--myRad)))" height="var(--myHeight)"></rect>
</clipPath>
</defs>
</svg>
CSS
.clipped {
--myWidth: 100vw;
--myHeight: 10rem;
--myRad: 2rem;
clip-path: url(#clipped);
}
I found this useful as compared to using border-radius with overflow set to hidden, because this approach doesn't create a BFC or break things like sticky position and css perspective effects. Also, this allows you to "inset" the position of the svg paths to clip inside the element with a "corner-radius" if you want.
You can also mess around with the circle to get some different effects.
-webkit-clip-path: circle(60.0% at 50% 10%);
clip-path: circle(50.0% at 50% 50%);
Codepen
Too bad you can't combine the polygon and circle... or maybe you can and I haven't played around with it enough to figure it out. HTH
clip-path: inset(45% 0% 33% 10% round 10px)
I don't have a comment option yes, so I'm writing it as an answer..
you need to write as many points as possible to round the corner. Nothig else...
for, example a few more points to make lower part bit rounder:
-webkit-clip-path: polygon(100% 0%, 100% 100%, 100% 100%, 25% 100%, 5% 70%,1% 60%, 0% 50%, 25% 0%);
oh, yes, or SVG as comment people here.. :)
You could use a child element and do a nested clip-path on that and the child's pseudo element. The parent will do a polygon clip on the shape first, then the pseudo will have an ellipse to round the borders. The clips will have a combined effect.
.parent, .parent div, .parent div:before {
width: 423px;
height: 90px;
position: absolute;
}
.parent {
right: 0;
background-image: linear-gradient(to right, transparent 210px, #b0102d 210px);
margin-top: 15vh;
}
.parent div {
clip-path: polygon(100% 0%, 100% 100%, 25% 100%, 0 50%, 25% 0);
}
.parent div:before {
content: "";
background-color: #b0102d;
clip-path: ellipse(200px 45px at 210px);
}
<div class="parent">
<div></div>
</div>
Here is the demo with some adaptations to illustrate what's going on:
.parent, .parent div, .parent div:before {
width: 423px;
height: 90px;
position: absolute;
}
.parent {
right: 0;
background-image: linear-gradient(to right, transparent 210px, yellow 210px);
margin-top: 15vh;
}
.parent div {
background-color: blue;
clip-path: polygon(90% 0%, 90% 100%, 25% 100%, 0 50%, 25% 0);
}
.parent div:before {
content: "";
background-color: #b0102d;
clip-path: ellipse(200px 45px at 210px);
}
<div class="parent">
<div></div>
</div>
The horizontal size and position of the ellipse can be used to get a different effect on the edges. Note that the background starting postion of the parent needs to be adjusted to the same value as the placement of the ellipse (last value in the clip-path) because it fills up whatever gets clipped off on the right side. This can be visualised by removing background-color: blue from .parent div in the second demo.
Here is an additional Codepen to to try it out.

Resources