I am looking to achieve this style with css
So far I have done:
.file {
width: 279px;
height: 326px;
background: linear-gradient(-135deg, transparent 66px, #A1A1A4 40px);
position: relative;
}
.file::before,
.file::after {
content: '';
position: absolute;
top: 0;
right: 0;
border-color: transparent;
border-style: solid;
}
.file::before {
border-top: 90px solid transparent;
border-left: 90px solid transparent;
}
.file::after {
margin-top: -2.6px;
width: 0;
height: 0;
border-bottom: 93px solid #281EBE;
border-right: 94px solid transparent;
}
<div class="file">
</div>
And it looks like this
The angle of triangle is not exactly 90deg. And how do I have that transparent spacing between the blue triangle and grey rectangle?
I would go with only linear gradient like this:
body {
background:pink;
}
.file {
width:300px;
height:600px;
background:
linear-gradient(to bottom left,transparent 50%,blue 50%) 100% 0/47px 47px no-repeat,
linear-gradient(grey,grey)0 0/calc(100% - 50px) 100% no-repeat,
linear-gradient(grey,grey)0 50px/100% 100% no-repeat;
}
<div class="file">
</div>
And if you want the border around the grey part you can add more gradient like this:
body {
background:pink;
}
.file {
width:300px;
height:600px;
background:
linear-gradient(to bottom left,transparent 50%,blue 50%) 100% 0/47px 47px no-repeat,
linear-gradient(grey,grey)0 2px/calc(100% - 52px) 100% no-repeat,
linear-gradient(grey,grey)0 52px/calc(100% - 2px) 100% no-repeat,
linear-gradient(#000,#000)0 0/calc(100% - 50px) 100% no-repeat,
linear-gradient(#000,#000)0 50px/100% 100% no-repeat;
border-left:2px solid #000;
border-bottom:2px solid #000;
}
<div class="file">
</div>
And to easily handle the shape you can use CSS variables:
body {
background:pink;
}
.file {
--d:50px;
width:150px;
height:200px;
display:inline-block;
background:
linear-gradient(to bottom left,transparent 50%,blue 50%) 100% 0/calc(var(--d) - 3px) calc(var(--d) - 3px) no-repeat,
linear-gradient(grey,grey)0 2px/calc(100% - var(--d) - 2px) 100% no-repeat,
linear-gradient(grey,grey)0 calc(var(--d) + 2px)/calc(100% - 2px) 100% no-repeat,
linear-gradient(#000,#000)0 0/calc(100% - var(--d)) 100% no-repeat,
linear-gradient(#000,#000)0 var(--d)/100% 100% no-repeat;
border-left:2px solid #000;
border-bottom:2px solid #000;
}
<div class="file">
</div>
<div class="file" style="--d:20px">
</div>
<div class="file" style="--d:110px">
</div>
Related
I have a gradient which I want to start from left top, it's endpoint can be left as is.
Here are my current testing scenario's:
.test-1{
height: 200px;
border: 1px solid red;
}
.test-2{
height: 400px;
border: 1px solid blue;
}
.test-3{
height: 500px;
border: 1px solid red;
}
.test-4{
height: 600px;
border: 1px solid blue;
}
.gradient{
/* height: 100%;
width: 100%; */
padding: 0;
margin: 0;
background:
linear-gradient(190deg, #FFFFFF 22%, transparent 22.1%),
linear-gradient(90deg, #5c9c9b 0%, #8ccdcc 100%);
}
<div class="test-1 gradient"></div>
<div class="test-2 gradient"></div>
<div class="test-3 gradient"></div>
<div class="test-4 gradient"></div>
In .test-1, the div is too small, so its gradient is cutting off at the top. In this case, I would want it to end on the top left corner so it doesn't appear as if it's ending abruptly.
.test-2 is the same.
.test-3 is fine, it's not ending abruptly.
.test-4 is also fine, it not in the top left corner, but it's not cut off.
How can I cater this gradient to accommodate different div sizes?
You can adjust the top gradient to make it a triangular shape:
.test-1{
height: 80vh;
border: 1px solid red;
background:
/* position /width height */
linear-gradient(to bottom left,#fff 49.5%,transparent 50%) top/100% 30% no-repeat,
linear-gradient(90deg, #5c9c9b 0%, #8ccdcc 100%);
}
<div class="test-1 gradient"></div>
And if you want more space at the top add some padding
.test-1{
height: 80vh;
border: 1px solid red;
padding-top: 10vh;
background:
linear-gradient(to bottom left,#fff 49.5%,transparent 50%) top/100% 30% no-repeat,
linear-gradient(90deg, #5c9c9b 0%, #8ccdcc 100%) no-repeat;
background-origin:content-box;
}
<div class="test-1 gradient"></div>
Or add offset to the gradients:
.test-1{
height: 80vh;
border: 1px solid red;
background:
linear-gradient(to bottom left,#fff 49.5%,transparent 50%)left 0 top 20px/100% 30% no-repeat,
linear-gradient(90deg, #5c9c9b 0%, #8ccdcc 100%) left 0 top 20px no-repeat;
}
<div class="test-1 gradient"></div>
Another idea is to consider skew transformation
.test-1{
height: 80vh;
border: 1px solid red;
position:relative;
overflow:hidden;
z-index:0;
}
.test-1:before {
content:"";
position:absolute;
z-index:-1;
top:20px; /* Control the space */
bottom:0;
left:0;
right:0;
background:linear-gradient(90deg, #5c9c9b 0%, #8ccdcc 100%);
transform:skewY(8deg);
transform-origin:left;
}
<div class="test-1 gradient"></div>
In the gradient can use vh instead of %
.test-1{
height: 200px;
border: 1px solid red;
}
.test-2{
height: 400px;
border: 1px solid blue;
}
.test-3{
height: 500px;
border: 1px solid red;
}
.test-4{
height: 600px;
border: 1px solid blue;
}
.gradient{
/* height: 100%;
width: 100%; */
padding: 0;
margin: 0;
background:
linear-gradient(190deg, #FFFFFF 60vh, transparent 34.1vh),
linear-gradient(90deg, #5c9c9b 0, #8ccdcc 100vh);
}
<div class="test-1 gradient"></div>
<div class="test-2 gradient"></div>
<div class="test-3 gradient"></div>
<div class="test-4 gradient"></div>
I have created a form that is responsive but I cannot get the :before and :after elements which make it look like a polygon to be responsive. I want to make it so the top and bottom triangles resize along with the form.
How would I fix this? code pen:
https://codepen.io/coolblow/pen/rKEOEa
.form{
flex:1;
}
form {
background-color: lightgreen;
margin: -10px auto;
padding: 20px;
width: 50%;
position: relative;
}
form::before {
content: '';
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-bottom: 20px solid red;
position: absolute;
top: -20px;
left: 50%;
margin-left: -20px;
}
form::after {
content: '';
width: 0;
height: 0;
border-left: 120px solid transparent;
border-right: 120px solid transparent;
border-top: 70px solid blue;
position: absolute;
bottom: -70px;
left: 0;
}
Use background to create the whole shape:
form {
padding: 50px 20px;
margin:20px;
width:50%;
height:200px;
background:
/*Top part*/
linear-gradient(to bottom left,transparent 49%,green 50%)top right/50.5% 50px,
linear-gradient(to bottom right,transparent 49%,green 50%)top left/50% 50px,
/*middle part*/
linear-gradient(green,green) center/100% calc(100% - 100px),
/*bottom part*/
linear-gradient(to top left,transparent 49%,green 50%)bottom right/50.5% 50px,
linear-gradient(to top right,transparent 49%,green 50%)bottom left/50% 50px;
background-repeat:no-repeat;
}
<form>
</form>
Update
If you want smaller triangle on the top you can do this:
form {
padding: 50px 20px;
margin:20px;
width:50%;
height:200px;
background:
/*Top part*/
linear-gradient(to bottom left,transparent 49%,green 50%)calc(50% + 25px) 0/50px 50px,
linear-gradient(to bottom right,transparent 49%,green 50%)calc(50% - 25px) 0/50px 50px,
/*middle part*/
linear-gradient(green,green) center/100% calc(100% - 100px),
/*bottom part*/
linear-gradient(to top left,transparent 49%,green 50%)bottom right/50.5% 50px,
linear-gradient(to top right,transparent 49%,green 50%)bottom left/50% 50px;
background-repeat:no-repeat;
}
<form>
</form>
And for more control you can use CSS variables to adjust dimensions:
form {
margin:20px;
width:50%;
height:120px;
--tw:50px; /*Top triangle*/
--bw:50px; /*Bottom triangle*/
padding: var(--tw) 20px var(--bw);
background:
/*Top part*/
linear-gradient(to bottom left,transparent 49%,green 50%)calc(50% + var(--tw)/2) 0/var(--tw) var(--tw),
linear-gradient(to bottom right,transparent 49%,green 50%)calc(50% - var(--tw)/2) 0/var(--tw) var(--tw),
/*middle part*/
linear-gradient(green,green) 50% var(--tw)/100% calc(100% - (var(--tw) + var(--bw))),
/*bottom part*/
linear-gradient(to top left,transparent 49%,green 50%)bottom right/50.5% var(--bw),
linear-gradient(to top right,transparent 49%,green 50%)bottom left/50% var(--bw);
background-repeat:no-repeat;
}
<form>
</form>
<form style="--tw:80px;--bw:60px;">
</form>
<form style="--tw:120px;--bw:120px;">
</form>
Tell me, can I set the background to the border formed in the following way?
https://jsfiddle.net/2Lous8vq/1/
.object {
position: relative;
width: 300px;
height: 0px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
background: transparent;
}
.object:after {
content: '';
position: absolute;
top: 2px;
left: calc(2.45px - 50px);
width: calc(300px - 2 * 1.4px);
height: 0px;
border-left: 49px solid transparent;
border-right: 49px solid transparent;
border-bottom: calc(100px - 2px) solid white;
background: transparent;
}
<div class="object"></div>
It's probably worth using the custom border-image, but it seemed to me that this still does not have enough functionality.
I want instead of a white color on the tab to display the image background (for example, https://cdn.pixabay.com/photo/2016/12/02/17/39/texture-1878273__340.jpg)
You can use multiple background and gradient:
.object {
width: 300px;
height: 100px;
background:
linear-gradient(to bottom left,#fff 49%,red 49%,red 51%,transparent 0) 100% 0/40px 100% no-repeat,
linear-gradient(to bottom right,#fff 49%,red 49%,red 51%,transparent 0) 0 0/40px 100% no-repeat,
linear-gradient(red,red) 0 0/100% 2px no-repeat,
url(https://cdn.pixabay.com/photo/2016/12/02/17/39/texture-1878273__340.jpg)0 0/cover no-repeat;
}
<div class='object'></div>
Another idea with clip-path:
body {
background:yellow;
}
.object {
width: 300px;
height: 100px;
border-bottom:none;
background:
linear-gradient(red,red) 0 0/100% 2px no-repeat,
linear-gradient(to bottom left,red 51%,transparent 51.5%) 100% 0/60px 100% no-repeat,
linear-gradient(to bottom right,red 51%,transparent 51.5%) 0 0/60px 100% no-repeat,
url(https://cdn.pixabay.com/photo/2016/12/02/17/39/texture-1878273__340.jpg)0 0/cover no-repeat;
-webkit-clip-path: polygon(20% 0%, 80% 0%, 100% 100%, 0% 100%);
clip-path: polygon(20% 0%, 80% 0%, 100% 100%, 0% 100%);
}
<div class='object'></div>
UPDATE
Another way more supported that rely on more elements:
body {
background:yellow;
}
* {
box-sizing:border-box;
}
.object {
width: 300px;
height: 100px;
border-bottom:none;
font-size:0;
}
.object .left,
.object .right {
width:50%;
display:inline-block;
height:100%;
border-top:2px solid red;
position:relative;
overflow:hidden;
}
.object .left {
border-left:2px solid red;
transform:skew(-20deg);
transform-origin:bottom left;
}
.object .right {
border-right:2px solid red;
transform:skew(20deg);
transform-origin:bottom right;
}
.object .left:before {
content:"";
position:absolute;
top:0;
left:-20px;
bottom:0;
right:-20px;
transform:skew(20deg);
background:url(https://cdn.pixabay.com/photo/2016/12/02/17/39/texture-1878273__340.jpg);
}
.object .right:before {
content:"";
position:absolute;
top:0;
left:-20px;
bottom:0;
right:-20px;
transform:skew(-20deg);
background:url(https://cdn.pixabay.com/photo/2016/12/02/17/39/texture-1878273__340.jpg);
}
<div class='object'>
<div class="left"></div>
<div class="right"></div>
</div>
This question already has answers here:
Is it possible to create an angled corner in CSS?
(6 answers)
How to achieve chamfered CSS Border Corners rather than rounded corners?
(8 answers)
Closed 5 years ago.
I'm hoping to draw a solid border around a div, the only catch is that I'd like 1 corner to be "dog eared" (see attached image).
Is this possible to do in CSS? I've found clip-path, but this doesn't seem to accept a border willingly.
Please note that I will want to fill this area with content as well - text/images.
Here is a solution with linear gradient:
.box {
height:100px;
width:200px;
background:linear-gradient(to bottom,red 50%,transparent 0) 0 0/calc(100% - 20px) 2px no-repeat,
linear-gradient(to bottom,transparent 50%,red 0) 0 100%/100% 2px no-repeat,
linear-gradient(to right,red 50%,transparent 0) 0 0/2px 100% no-repeat,
linear-gradient(to right,transparent 50%,red 0) 100% 20px/2px 100% no-repeat,
linear-gradient(to top right,transparent 50%,red 50%,red calc(50% + 1px),transparent calc(50% + 2px)) 100% 0/20px 20px no-repeat;
}
<div class="box">
</div>
For the clip-path solution you can do this:
.box {
height:100px;
width:200px;
background:linear-gradient(to top right,transparent 50% ,red 0) 100% 0/20px 20px no-repeat;
border:2px solid red;
clip-path:polygon(1px 1px,1px calc(100% - 1px),calc(100% - 1px) calc(100% - 1px),calc(100% - 1px) calc(100% - 84px), calc(100% - 20px) 1px);
}
<div class="box">
</div>
Here is another way using pseudo element and skew transformation:
.box {
height: 80px;
width: 200px;
margin-top: 50px;
border: 1px solid red;
border-top: none;
position: relative;
}
.box:before {
content: "";
position: absolute;
left: -1px;
right: 50%;
top: -20px;
height: 20px;
border-top: 1px solid red;
border-left: 1px solid red;
}
.box:after {
content: "";
position: absolute;
right: -1px;
left: 50%;
top: -20px;
height: 20px;
border-top: 1px solid red;
border-right: 1px solid red;
transform: skew(45deg);
transform-origin: bottom right;
}
<div class="box">
</div>
How can I create the following shape with CSS?
I tried this to be a solution:
.triangle:after {
position:absolute;
content:"";
width: 0;
height: 0;
margin-top:1px;
margin-left:2px;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid white;
}
.triangle:before {
position:absolute;
content:"";
width: 0;
height: 0;
border-left: 12px solid transparent;
border-right: 12px solid transparent;
border-bottom: 12px solid black;
}
You can see it working at Triangle. This is working, but with a trick of borders. Is there another way it could be done?
Using SVG vectors this can be done easily, but I don't want to go that lengthy way.
I've found a webkit-only solution, using the ▲ character:
.triangle {
-webkit-text-stroke: 12px black;
color: transparent;
font-size: 200px;
}
<div class="triangle">▲</div>
Extras:
CanIUse reference for text-stroke - all major browsers covered as of 2019
CSS-tricks article
Useful HTML shapes
CSS-border version:
.triangle {
position: relative;
width:0;
border-bottom:solid 50px black;
border-right:solid 30px transparent;
border-left:solid 30px transparent;
}
.triangle .empty {
position: absolute;
top:9px;
left:-21px;
width:0;
border-bottom:solid 36px white;
border-right:solid 21px transparent;
border-left:solid 21px transparent;
}
Adding a white triangle inside the black one: http://jsfiddle.net/samliew/Hcfsx/
Here is an idea using multiple background and linear-gradient:
.triangle {
width:100px;
height:100px;
background:
/* Left side */
linear-gradient(to bottom left,
transparent 49.5%,#000 50% calc(50% + 10px),
transparent calc(50% + 11px)) right/50% 100%,
/* right side */
linear-gradient(to bottom right,
transparent 49.5%,#000 50% calc(50% + 10px),
transparent calc(50% + 11px)) left/50% 100%,
/* bottom side*/
linear-gradient(#000,#000) bottom/calc(100% - 20px) 10px;
background-repeat:no-repeat;
}
<div class="triangle"></div>
You can consider CSS variables to easily adjust the shape:
.triangle {
--t:10px; /* Thickness */
--c:black; /* Color */
width:100px;
height:100px;
display:inline-block;
background:
/* Left side */
linear-gradient(to bottom left,
transparent 49.5%,var(--c) 50% calc(50% + var(--t)),
transparent calc(50% + var(--t) + 1px)) right/50% 100%,
/* right side */
linear-gradient(to bottom right,
transparent 49.5%,var(--c) 50% calc(50% + var(--t)),
transparent calc(50% + var(--t) + 1px)) left/50% 100%,
/* bottom side*/
linear-gradient(var(--c),var(--c)) bottom/calc(100% - 2*var(--t)) var(--t);
background-repeat:no-repeat;
}
body {
background:pink;
}
<div class="triangle"></div>
<div class="triangle" style="--t:5px;--c:blue;width:150px"></div>
<div class="triangle" style="--t:8px;--c:red;height:150px"></div>
<div class="triangle" style="--t:15px;--c:green;width:80px"></div>
A different syntax with less gradient:
.triangle {
--t:10px; /* Thickness */
--c:black; /* Color */
width:100px;
height:100px;
display:inline-block;
border:var(--t) solid transparent;
border-bottom-color:var(--c);
background:
/* Left side */
linear-gradient(to bottom left,
transparent 49.5%,var(--c) 50% calc(50% + var(--t)),
transparent calc(50% + var(--t) + 1px)) right,
/* right side */
linear-gradient(to bottom right,
transparent 49.5%,var(--c) 50% calc(50% + var(--t)),
transparent calc(50% + var(--t) + 1px)) left;
background-size:50% 100%;
background-origin:border-box;
background-repeat:no-repeat;
}
body {
background:pink;
}
<div class="triangle"></div>
<div class="triangle" style="--t:5px;--c:blue;width:150px"></div>
<div class="triangle" style="--t:8px;--c:red;height:150px"></div>
<div class="triangle" style="--t:15px;--c:green;width:80px"></div>
You can consider the same idea to create a rectangle triangle:
.triangle {
--t:10; /* Thickness */
--c:black; /* Color */
width:100px;
height:100px;
display:inline-block;
border:calc(var(--t)*1px) solid transparent;
border-image:
linear-gradient(to bottom left,
transparent 49.5%,var(--c) 50%) var(--t);
background:
/* Left side */
linear-gradient(to bottom left,
transparent 49.5%,var(--c) 50% calc(50% + var(--t)*1px),
transparent calc(50% + var(--t)*1px + 1px));
background-origin:border-box;
background-repeat:no-repeat;
}
body {
background:pink;
}
<div class="triangle"></div>
<div class="triangle" style="--t:5;--c:blue;width:150px"></div>
<div class="triangle" style="--t:8;--c:red;height:150px"></div>
<div class="triangle" style="--t:15;--c:green;width:80px"></div>
If you want an equilateral triangle simply keep a ratio bettween the width/height using the initial code
.triangle {
--t:10px; /* Thickness */
--c:black; /* Color */
width:100px;
display:inline-block;
border:var(--t) solid transparent;
border-bottom-color:var(--c);
background:
/* Left side */
linear-gradient(to bottom left,
transparent 49.5%,var(--c) 50% calc(50% + var(--t)),
transparent calc(50% + var(--t) + 1px)) right,
/* right side */
linear-gradient(to bottom right,
transparent 49.5%,var(--c) 50% calc(50% + var(--t)),
transparent calc(50% + var(--t) + 1px)) left;
background-size:50% 100%;
background-origin:border-box;
background-repeat:no-repeat;
}
.triangle:before {
content:"";
display:block;
padding-top:86.6%;
}
body {
background:pink;
}
<div class="triangle"></div>
<div class="triangle" style="--t:5px;--c:blue;width:150px"></div>
<div class="triangle" style="--t:8px;--c:red;width:50px"></div>
<div class="triangle" style="--t:15px;--c:green;width:80px"></div>
Related answer for more details about the calculation: How do CSS triangles work?
Try using SVG
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<polygon points="200,10 250,190 160,210"
style="fill:lime;stroke:purple;stroke-width:1"/>
</svg>
Here is the tutorial
You can use the method I described here : How does this CSS triangle shape work? with a rotated pseudo element. You can then add a border to the rotated pseudo element to create the effect you are looking for.
You can also use this technique to display the triangle with borders over an image, gradient or any non plain backgrounds :
DEMO
.tr{
width:40%;
padding-bottom: 28.28%; /* = width / sqrt(2) */
position:relative;
border-bottom: 6px solid rgba(0,0,0,0.8);
border-right: 6px solid transparent;
border-left: 6px solid transparent;
overflow:hidden;
}
.tr:before{
content:'';
position:absolute;
bottom:0; left:0;
width:100%; height:100%;
border-top:6px solid rgba(0,0,0,0.8);
border-left:6px solid rgba(0,0,0,0.8);
-moz-box-sizing:border-box;
box-sizing:border-box;
-webkit-transform-origin:0 100%;
-ms-transform-origin:0 100%;
transform-origin:0 100%;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
/* FOLLOWING JUST FOR THE DEMO */
body{background:url('https://picsum.photos/id/100/1000/1000');background-size:cover;}
<div class="tr"></div>
Consider using the <canvas> element. I build a simple triangle on jsfiddle - nothing fancy, yet.
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
context.beginPath();
context.moveTo(10, 0);
context.lineTo(20, 20);
context.lineTo(0, 20);
context.closePath();
context.fill();
<canvas id="myCanvas" width="20" height="20"></canvas>
.triangle{
width:0;
border-bottom:solid 30px black;
border-right:solid 30px transparent;
border-left:solid 30px transparent;
}
<div class="triangle">
</div>
This will be a triangle pointed towards the top. Don't specify the border to the side where you need it to be pointed.
The above is an equilateral triangle. Remove border-left to make it a right-angled triangle.
clip-path could also be considered:
html {
/* init size and shape to the triangle*/
--base: 155px;
--ratio: 1;
/* try too 0.71*/
;
}
[data-triangle] {
width: var(--base);
height: calc(var(--base) * var(--ratio));
clip-path: polygon( 0 100%, 50% 0, 100% 100%, 94% 96%, 50% 8%, 6% 96%, 96% 96%, 100% 100%);
background: gray;
}
/* demo makup */
html {
display: grid;
min-height: 100vh;
}
body {
background: repeating-linear-gradient(45deg, silver 0, #444, gold, blue, lime, tomato, purple, gray 5em) 0 0 / 100% 100%;
margin: auto;
text-align: center;
box-shadow: inset 0 0 0 100vw rgba(0, 0, 0, 0.5), 0 0 0 100vw rgba(0, 0, 0, 0.5);
color:gray
}
[data-triangle] {
transition: 1s;
}
body:hover [data-triangle]{
background: black;
}
body:hover {
filter: drop-shadow(0 0 1px gold)drop-shadow(0 0 1px white)drop-shadow(0 0 1px white)drop-shadow(0 0 1px white)drop-shadow(0 0 1px white)drop-shadow(0 0 10px white);
/*make that triangle obvious over that funny gradient*/
color: transparent;
box-shadow: 0 0;
}
}
<div data-triangle></div>
hover to highlight
to help you create your clip-path, you can use this online tool https://bennettfeely.com/clippy/
I found a nice solution, a bit tricky but for me it was the most easy way to do it:
link to code-pen
.triangle {
position: absolute;
margin: auto;
top: -70px;
left: 0;
right: 0;
width: 137px;
height: 137px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
border-right: 4px solid #e74c3c;
border-bottom: 4px solid #e74c3c;
}