Here is a codepen of what I did:
https://codepen.io/dickeddocks/pen/opWBwQ
and this is what I am trying to achieve:
a rough picture made in MS-Paint
so I am trying to make box 2, a div overlap box 1 which is also a div
and I want to make the yellow border cover the shape and not the container box. I did some research on stackoverflow and an answer to adding a border to a clip path shape was to add the the same clip path to the container.
But I am a little confused as the div itself is the container so why is the border not wrapping it.
html:
<div class="box-1">
BOX 1
</div>
<div class="box-2">
BOX 2
</div>
css:
* {
padding: 0;
margin: 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
body {
background-color: aqua;
}
.box-1 {
padding: 25vh;
background-color: aqua;
}
.box-2 {
z-index: 200;
-webkit-clip-path: polygon(50% -10%, 100% 11%, 100% 100%, 0 100%, 0 11%);
clip-path: polygon(50% -10%, 100% 11%, 100% 100%, 0 100%, 0 11%);
padding: 25vh;
background-color: aquamarine;
border-top: 10px solid yellow;
}
If you want to go with clip-path for this, you have to first make the second box overlap the first one by using negative margin or change the top value. Then you have to create the small arrow using pseudo element (you can read more about How do CSS triangles work?)
So you will have something like this (without clip path):
* {
padding: 0;
margin: 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
body {
background-color: aqua;
}
.box-1 {
padding: 25vh;
background-color: aqua;
}
.box-2 {
z-index: 2;
position: relative;
margin-top: -50px;
padding: 25vh;
background-color: #dede3b;
border-top: 50px solid yellow;
}
.box-2:before {
content: "";
position: absolute;
border-bottom: 40px solid #dede3b;
border-right: 50px solid transparent;
border-left: 50px solid transparent;
right: 50%;
margin-right: -50px;
top: -40px;
}
<div class="box-1">
BOX 1
</div>
<div class="box-2">
BOX 2
</div>
Then create the clip-path to hide the non needed part like this :
* {
padding: 0;
margin: 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
body {
background-color: aqua;
}
.box-1 {
padding: 25vh;
background-color: aqua;
}
.box-2 {
z-index: 2;
position: relative;
margin-top: -50px;
padding: 25vh;
background-color: #dede3b;
border-top: 50px solid yellow;
clip-path: polygon(0% 40px, 0% 100%, 100% 100%, 100% 40px, calc(50% + 50px) 40px, 50% 0, calc(50% - 50px) 40px);
;
}
.box-2:before {
content: "";
position: absolute;
border-bottom: 40px solid #dede3b;
border-right: 50px solid transparent;
border-left: 50px solid transparent;
right: 50%;
margin-right: -50px;
top: -40px;
}
<div class="box-1">
BOX 1
</div>
<div class="box-2">
BOX 2
</div>
Here is an illustration to understand the polygon I used for clip-path:
Here is another solution without using clip-path (which will work better with all the browser). The idea is to use 2 pseudo element to create the double arrow:
* {
padding: 0;
margin: 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
body {
background-color: aqua;
}
.box-1 {
padding: 25vh;
background-color: aqua;
}
.box-2 {
position: relative;
padding: 25vh;
background-color: #dede3b;
border-top: 10px solid yellow;
}
.box-2:before {
content: "";
position: absolute;
border-bottom: 50px solid yellow;
border-right: 60px solid transparent;
border-left: 60px solid transparent;
right: 50%;
margin-right: -60px;
top: -55px;
z-index: 1;
}
.box-2:after {
content: "";
position: absolute;
border-bottom: 40px solid #dede3b;
border-right: 50px solid transparent;
border-left: 50px solid transparent;
right: 50%;
margin-right: -50px;
top: -40px;
z-index: 2;
}
<div class="box-1">
BOX 1
</div>
<div class="box-2">
BOX 2
</div>
Related
i am making block with arrow and border looks like
And i have tried this.
* {
box-sizing: border-box;
}
.block-arr {
background: purple;
margin: 20px;
margin-right: 100px;
position: relative;
}
.block-arr .inner {
min-height: 100px;
display: flex;
padding: 20px;
align-items: center;
position: relative;
}
.block-arr .inner:after {
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-left: 50px solid purple;
content: '';
position: absolute;
left: 100%;
top: 0;
}
.block-arr:after {
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-left: 50px solid purple;
content: '';
position: absolute;
left: 100%;
top: 0;
}
<div class="block-arr">
<div class="inner">
<strong>Main Heading</strong>
<span>Sub Heading</span>
</div>
</div>
How can i make block like image? And can we make this arrow height responsive?
I would consider a mix of skew transformation, inset box-shadow and some linear-gradient:
* {
box-sizing: border-box;
}
.block-arr {
padding: 50px;
margin: 20px;
margin-right: 100px;
position: relative;
background: linear-gradient(#fff, #fff)2px 0/2px 100% no-repeat, purple;
border-left: 2px solid purple;
z-index: 0;
}
.block-arr:before {
content: "";
position: absolute;
top: 0;
bottom: 50%;
left: 0;
right: 0;
background: purple;
border: 5px solid purple;
border-bottom: none;
border-left: none;
box-shadow: -2px 2px 0px #fff inset;
transform: skew(25deg);
transform-origin: top left;
z-index: -1;
}
.block-arr:after {
content: "";
position: absolute;
top: 50%;
bottom: 0;
left: 0;
right: 0;
background: purple;
border: 5px solid purple;
border-top: none;
border-left: none;
box-shadow: -2px -2px 0px #fff inset;
transform: skew(-25deg);
transform-origin: bottom left;
z-index: -1;
}
<div class="block-arr">
<strong>Main Heading</strong>
<span>Sub Heading</span>
</div>
<div class="block-arr">
<strong>Main Heading</strong><br/>
<span>Sub Heading</span>
</div>
<div class="block-arr">
</div>
And here is a more compressed version with some CSS variable to easily handle color. You can also do the same to handle others variables:
* {
box-sizing: border-box;
}
.block-arr {
--c1:purple;
--c2:#fff;
padding: 50px;
margin: 20px;
margin-right: 100px;
position: relative;
background: linear-gradient(var(--c2), var(--c2))2px 0/2px 100% no-repeat, var(--c1);
border-left: 2px solid var(--c1);
z-index: 0;
}
.block-arr:before,
.block-arr:after {
left: 0;
right: 0;
content: "";
position: absolute;
background: var(--c1);
border: 5px solid var(--c1);
border-left: none;
z-index: -1;
}
.block-arr:before {
top: 0;
bottom: 50%;
border-bottom: none;
box-shadow: -2px 2px 0px var(--c2) inset;
transform: skew(25deg);
transform-origin: top left;
}
.block-arr:after {
top: 50%;
bottom: 0;
border-top: none;
box-shadow: -2px -2px 0px var(--c2) inset;
transform: skew(-25deg);
transform-origin: bottom left;
}
<div class="block-arr">
</div>
<div class="block-arr" style="--c1:red;--c2:yellow">
<strong>Main Heading</strong>
<span>Sub Heading</span>
<p>And yes it is reponsive and grow when height grow</p>
</div>
BONUS
Another fancy and more complex way with only linear-gradient:
* {
box-sizing: border-box;
}
.block-arr {
--c1:purple;
--c2:#fff;
padding: 50px;
margin: 20px;
margin-right: 100px;
position: relative;
border:1px solid;
background:
linear-gradient(to top left,transparent calc(50% + 4px),var(--c2) calc(50% + 4px),var(--c2) calc(50% + 6px),transparent 0) 100% 100%/50px 50% no-repeat,
linear-gradient(to bottom left,transparent calc(50% + 4px),var(--c2) calc(50% + 4px),var(--c2) calc(50% + 6px),transparent 0) 100% 0/50px 50% no-repeat,
linear-gradient(var(--c2),var(--c2)) 4px calc(100% - 4px)/calc(100% - 58px) 2px no-repeat,
linear-gradient(var(--c2),var(--c2)) 4px 4px/calc(100% - 58px) 2px no-repeat,
linear-gradient(var(--c2),var(--c2)) 4px 4px/2px calc(100% - 8px) no-repeat,
linear-gradient(to top left ,transparent 50%,var(--c1) 50%) 100% 100%/50px 50% no-repeat,
linear-gradient(to bottom left,transparent 50%,var(--c1) 50%) 100% 0/50px 50% no-repeat,
linear-gradient(var(--c1),var(--c1)) 0 0/calc(100% - 50px) 100% no-repeat;
}
<div class="block-arr">
</div>
Using :after and :before pseudo elements, i have made this design.
Hope it fulfills your requirement.
Thanks
CSS and HTML:
* {
box-sizing: border-box;
}
p { margin:0; }
.block-arr {
background: purple;
margin: 20px;
margin-right: 100px;
position: relative;
}
.block-arr .inner {
min-height: 100px;
/*display: flex;*/
padding: 20px;
align-items: center;
position: relative;
}
.block-arr .inner:after {
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-left: 50px solid purple;
content: '';
position: absolute;
left: 100%;
top: 0;
}
.block-arr:after {
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-left: 50px solid purple;
content: '';
position: absolute;
left: 100%;
top: 0;
}
.bordered { position:relative; border:1px solid #fff; border-right:none; display: flex; align-items: center; padding:20px; }
.bordered:before, .bordered:after {
content: "";
position: absolute;
height: 72%;
width: 1px;
background: #fff;
top: 0;
right: 0;
z-index: 4;
}
.bordered:before {
transform: rotate(45deg);
top: auto;
right: -3.3%;
bottom: -11%;
}
.bordered:after {
transform: rotate(-45deg);
top: -12%;
right: -3.3%;
}
<div class="block-arr">
<div class="inner"><div class="bordered">
<p><strong>Main Heading</strong>
<span>Sub Heading</span></p>
</div></div>
</div>
I want to build the following layout:
Preferable i want only use css for that. But even with an background-image i wouldn't know how to build it. I searched the web, but didn't find the help i needed.
The Layout contains a div with some text in it. The background-color is a light gray. Then i would love to add a darker triangle background as shown in the picture. This should work as a responsive layout, too.
What i tried:
# html
<div class="wrapper">
<h1>Das ist ein test</h1>
<h2>subheadline</h2>
</div>
#css
.wrapper {
padding-top: 100px;
text-align: center;
width: 100%;
background-color: #4d4d4d;
height: 400px;
color: #fff;
position: relative;
}
.wrapper:before{
height: 50%;
width:100%;
position:relative;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
transform: rotate(45deg);
content:'';
display:block;
position:absolute;
top: 0;
background-color: #3d3d3d;
}
But this does not work and i can't figure it out on my own.
Thank you for your help!
You can set 2 light gradients on top of the darker background.
They overlap each other and leave only the remaining triangle darker
div {
width: 400px;
height: 200px;
border: solid 1px green;
background: linear-gradient(to top left, lightgreen 50%, transparent 50%),
linear-gradient(to top right, lightgreen 50%, transparent 50%), green;
}
<div></div>
Try this one, but still need some work on the responsive part.
.box{
position: relative;
width: 100%;
max-width: 600px;
background: #ccc;
min-height: 300px;
}
.box:before {
width: 0;
height: 0;
content: "";
position: absolute;
z-index: 0;
top: 0;
left: 0;
border-left: 300px solid transparent;
border-right: 300px solid transparent;
border-top: 180px solid #555;
}
.box .content{
z-index: 10;
position: relative;
color: #fff;
text-align: center;
padding-top: 40px;
}
h1, h2{
margin: 0;
padding: 0;
}
h2{
margin-bottom: 80px;
}
.btn{
background: #f00;
color: #fff;
display: inline-block;
padding: 5px 10px;
text-align: center;
text-decoration: none;
min-width: 200px;
font-size: 20px;
}
<div class="box">
<div class="content">
<h1>Headline</h1>
<h2>Headline</h2>
CTA
</div><!--// end .content -->
</div><!--// end .box -->
This should get you close, and illustrates a CSS only approach:
* {
margin: 0;
padding: 0
}
body {
background: #ccc;
min-height: 500px;
}
div {
width: 0;
height: 0;
margin: 0px auto;
border: 200px solid transparent;
border-top-color: grey;
}
a {
display: block;
background: blue;
color: white;
padding: 5px 10px;
width: 200px;
margin: 0px auto;
position: relative;
top: -200px;
text-align: center;
text-decoration: none;
}
<div></div>
link
I want to make a down arrow on the bottom of a <section> element. It should be in the middle of the bottom. But unfortunately I have not found any methods how to do this with css. And I can't figure it out myself.
Here's my html:
<div class="down-btn">
<svg class="down-btn-img">
<polyline points="0,0 50,50 100,0" />
</svg>
</div>
Try this
.down-arrow {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 50px solid red;
}
Or this
HTML:
<section style="background: green; border-color: green;">Your section</section>
CSS:
section {
margin: 50px;
padding: 50px;
position: relative;
}
section:after {
content: "";
position: absolute;
top: 100%;
left: 50px;
border-top: 50px solid green;
border-top-color: inherit;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
}
JSFiddle
You can do this with a rotated pseudo-element. No borders required and it updates based on the background color of your section.
You can even make it responsive by using viewport units
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
section {
height: 50px;
background: #bada55;
position: relative;
}
section::after {
content: '';
position: absolute;
top: 100%;
width: 4vw;
height: 4vw;
left: 50%;
background: inherit;
transform: translate(-50%, -50%) rotate(45deg);
z-index: -1;
}
<section></section>
Codepen Demo
I just did the thing with margins and I attached it to the bottom with bottom: 0
.down-btn {
bottom: 0;
position: absolute;
min-width: 30px;
margin: 0px calc(50vw - 15px);
}
I actually googled and searched some info but couldn't find it.
My aim is to achieve something similar to progress bar styling such as filling inside of triangle. Is there any ways?
JSFiddle
.angle {
width: 0;
height: 0;
border-left: 75px solid transparent;
border-right: 75px solid transparent;
border-bottom: 75px solid black;
}
In order to make the triangle, I would use two pseudo elements to 'cut it out' of the square div. Then, with a nested div, use absolute positioning to allow you to 'fill' it to a certain value (by setting the .amount div's height in %).
.amount {
position: absolute;
height: 0%;
width: 100%;
bottom: 0;
left: 0;
transition: all 1s;
background: tomato;
}
.tri {
position: relative;
height: 200px;
width: 200px;
background: lightgray;
}
.tri:before,
.tri:after {
content: "";
position: absolute;
border-top: 200px solid white;
top: 0;
z-index: 8;
}
.tri:before {
border-left: 100px solid transparent;
left: 50%;
}
.tri:after {
border-right: 100px solid transparent;
left: 0;
}
.tri:hover .amount {
height: 100%;
}
<div class="tri">
<div class="amount"></div>
</div>
May something like this?
.angle {
position: relative;
width: 0;
height: 0;
border-left: 100px solid transparent;
border-right: 100px solid transparent;
border-bottom: 100px solid blue;
}
.angle:after {
position: absolute;
content: "";
top: 0;
left: 50%;
margin-left: -50px;
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid black;
}
fiddle: http://jsfiddle.net/bkaxzLnu/3/
Here is another CSS ONLY, NO-BORDERS, NO AFTER/BEFORE HACKS option:
You could use clip-path. It allows you to show only part of an element and hide the rest.
So you could do something like this:
.amount {
position: absolute;
height: 100%;
width: 0%;
bottom: 0;
left: 0;
transition: all 1s;
background: tomato;
}
.tri {
position: relative;
width: 500px;
height: 50px;
background: #ddd;
/* triangle */
clip-path: polygon( 100% 0%,100% 100%, 0% 100%);
}
.tri:hover .amount {
width: 100%;
background: chartreuse ;
}
<div class="tri">
<div class="amount"></div>
</div>
Just realized I have yet to see this.
But can not believe it isn't possible.
I'm looking to draw a triangle in pure CSS/HTML. An equilateral if possible.
Clarification:
I don't wish to use an image to achieve this.
You would need to be able to put content inside the div.
One Solution
Diagonals are not easy. One solution is to overlay pseudo-elements to create the border, assuming you are dealing with solid background colors. Then you have to position the content to make it look nice. You could even do some text wrapping.
Here is a basic example using this code:
CSS & HTML Respectively
.triangleBorder {
position: relative;
width: 200px;
height: 173.2px; /* for equalateral = Width * (sq.root 3) / 2 */
}
.triangleBorder:before {
content: '';
width: 0;
height: 0;
position: absolute;
z-index: -2;
border: 100px solid transparent;
border-top-width: 0;
border-bottom: 173.2px solid black;
}
.triangleBorder:after {
content: '';
width: 0;
height: 0;
position: absolute;
left: 1px;
top: 1px;
z-index: -1;
border: 99px solid transparent;
border-top-width: 0;
border-bottom: 171.5px solid white;
}
.triangleBorder span {
position: absolute;
width: 100%;
text-align: center;
top: 50%;
}
<div class="triangleBorder">
<span>Content<span>
</div>
Here are a few different approaches for creating the equilateral triangle shape using CSS. Creation of diagonals is still not any easier but now the shape can at-least have a transparent background even when the body has a gradient (or) an image as its background.
Option 1: Using Pseudo-elements and Skew Transforms
In this method we use a couple of pseudo-elements and skew them in opposite directions (inward) to create the diagonal lines whereas the line at the bottom is produced using a border-bottom on the parent. We can also produce trapezoids using this approach.
Cons: This approach would not work if the body background and shape background are different and the body background is not a solid color.
.triangle {
position: relative;
width: 200px;
border-bottom: 2px solid white;
color: white;
margin: 20px auto;
overflow: hidden;
}
.shape1 {
height: 174px;
}
.shape2 {
height: 101px;
}
.triangle:before,
.triangle:after {
position: absolute;
content: '';
height: 100%;
width: 0%;
bottom: 0px;
transform-origin: left bottom;
}
.triangle:before {
left: 0px;
border-right: 2px solid white;
}
.triangle.shape1:before {
transform: skew(-30deg);
}
.triangle.shape2:before {
transform: skew(-45deg);
}
.triangle:after {
right: 0px;
border-left: 2px solid white;
}
.triangle.shape1:after {
transform: skew(30deg);
}
.triangle.shape2:after {
transform: skew(45deg);
}
.triangle span {
position: absolute;
width: 100%;
text-align: center;
top: 50%;
}
/* Just for demo */
*{
box-sizing: border-box;
}
body {
background: radial-gradient(ellipse at center, #400, #100);
}
.trapezoid {
position: relative;
border-bottom: 2px solid white;
color: white;
margin: 20px auto;
width: 200px;
height: 50px;
}
.trapezoid:before,
.trapezoid:after {
position: absolute;
content: '';
height: 100%;
width: 40%;
bottom: -1px;
border-top: 2px solid white;
transform-origin: left bottom;
}
.trapezoid:before {
left: 0px;
border-left: 2px solid white;
transform: skew(-45deg);
}
.trapezoid:after {
right: 0px;
border-right: 2px solid white;
transform: skew(45deg);
}
.trapezoid span {
position: absolute;
width: 100%;
text-align: center;
top: 30%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='triangle shape1'>
<span>content</span>
</div>
<div class='triangle shape2'>
<span>content</span>
</div>
<br/>
<!-- Just something extra to illustrate -->
<div class='trapezoid'>
<span>content</span>
</div>
<br/>
Here is a variation of Option 1 which would work when the background of the body and that of the shape are different and the body background is a solid color.
.triangle{
position: relative;
width: 200px;
border-bottom: 2px solid black;
color: red;
background: beige;
margin: 20px auto;
overflow: hidden;
}
.shape1{
height: 174px;
}
.shape2{
height: 101px;
}
.triangle:before, .triangle:after{
position: absolute;
content: '';
height: 101%;
width: 100%;
bottom: 0px;
background: red;
transform-origin: left bottom;
}
.triangle:before{
left: -200px;
border-right: 2px solid black;
}
.triangle.shape1:before{
transform: skew(-30deg);
}
.triangle.shape2:before{
transform: skew(-45deg);
}
.triangle:after{
right: -200px;
border-left: 2px solid black;
}
.triangle.shape1:after{
transform: skew(30deg);
}
.triangle.shape2:after{
transform: skew(45deg);
}
.triangle span{
position: absolute;
width: 100%;
text-align: center;
top: 50%;
}
/* Just for demo */
*{
box-sizing: border-box;
}
body{
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='triangle shape1'>
<span>content</span>
</div>
<div class='triangle shape2'>
<span>content</span>
</div>
Here is another variation of Option 1 which supports gradient background for both inside and outside the triangle shape.
.triangle {
position: relative;
width: 200px;
border-bottom: 2px solid white;
color: white;
margin: 20px auto;
overflow: hidden;
}
.shape1 {
height: 174px;
}
.shape2 {
height: 101px;
}
.triangle:before,
.triangle:after {
position: absolute;
content: '';
height: 99%;
width: 50%;
z-index: -1;
transform-origin: left bottom;
}
.triangle:before {
left: 0px;
top: 100%;
border-top: 3px solid white;
background: linear-gradient(90deg, #003333, #773333);
}
.triangle.shape1:before {
border-top: 4px solid white;
transform: skewY(-60deg);
}
.triangle.shape2:before {
transform: skewY(-45deg);
}
.triangle:after {
right: 0px;
top: 0%;
border-top: 3px solid white;
background: linear-gradient(90deg, #773333, #FF3333);
}
.triangle.shape1:after {
border-top: 4px solid white;
transform: skewY(60deg);
}
.triangle.shape2:after {
transform: skewY(45deg);
}
.triangle span {
position: absolute;
width: 100%;
text-align: center;
top: 50%;
}
/* Just for demo */
*{
box-sizing: border-box;
}
body {
background: radial-gradient(ellipse at center, #400, #100);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='triangle shape1'>
<span>content</span>
</div>
<div class='triangle shape2'>
<span>content</span>
</div>
Screenshot:
Triangles with different angles can be easily created by modifying the skew angle and the height of the parent div. But, as we are using skew the borders tend to become thinner as the skew angle approaches 90deg (or -90deg) but that shouldn't be too big a problem because with such high angles you can barely have fit any text inside.
Option 2: Using Linear Gradients
In this method, we use a couple of angled linear-gradient backgrounds (each of which are 50% width of the container) and slant them in opposite directions to produce the diagonal lines.
.triangle {
position: relative;
border-bottom: 2px solid white;
color: white;
margin: 20px auto;
height: 174px;
width: 200px;
background: linear-gradient(to top left, transparent 49.5%, white 49.5%, white 50.5%, transparent 50.5%), linear-gradient(to top right, transparent 49.5%, white 49.5%, white 50.5%, transparent 50.5%);
background-size: 50% 100%;
background-position: 1px 0px, 99px 0px;
background-repeat: no-repeat;
}
.triangle span {
position: absolute;
width: 100%;
text-align: center;
top: 50%;
}
/* Just for demo*/
body {
background: radial-gradient(ellipse at center, #400, #100);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='triangle'>
<span>content</span>
</div>
Cons: Angled gradients are known for producing jagged lines.
Note: Irrespective of which approach is chosen, you would still have to do text wrapping to make the text stay inside the shape.