So this is kind of hard to show, but I will try my best.
Basically I am trying to create a button, or div, that has some corner borders, which then expands on hover, just like this:
HTML:
<div class="container">
<div class="other-container">
<div class="corner-box">This is </div>
</div>
</div>
CSS:
.container {
display: grid;
}
.other-container {
width: 200px;
height: 100px;
transition: all 0.1s ease-in;
display: grid;
margin: 0px auto;
}
.corner-box {
box-sizing: border-box;
background:
linear-gradient(to right, black 2px, transparent 2px) 0 0,
linear-gradient(to right, black 2px, transparent 2px) 0 100%,
linear-gradient(to left, black 2px, transparent 2px) 100% 0,
linear-gradient(to left, black 2px, transparent 2px) 100% 100%,
linear-gradient(to bottom, black 2px, transparent 2px) 0 0,
linear-gradient(to bottom, black 2px, transparent 2px) 100% 0,
linear-gradient(to top, black 2px, transparent 2px) 0 100%,
linear-gradient(to top, black 2px, transparent 2px) 100% 100%;
transition: all 0.2s ease-in-out;
background-repeat: no-repeat;
background-size: 20px 20px;
width: 100%;
height: 100%;
&:hover {
background:
linear-gradient(to right, black 2px, transparent 2px) 0 0,
linear-gradient(to right, black 2px, transparent 2px) 0 100%,
linear-gradient(to left, black 2px, transparent 2px) 100% 0,
linear-gradient(to left, black 2px, transparent 2px) 100% 100%,
linear-gradient(to bottom, black 2px, transparent 2px) 0 0,
linear-gradient(to bottom, black 2px, transparent 2px) 100% 0,
linear-gradient(to top, black 2px, transparent 2px) 0 100%,
linear-gradient(to top, black 2px, transparent 2px) 100% 100%;
background-repeat: no-repeat;
background-size: 50% 50%;
transition: all 0.2s ease-in-out;
}
}
As such, this actually seems to work when I just run this code. So no problem there. However, when I try to implement it in my project something weird happens.
Basically I am trying to put it in my own code like this (modified of course) in my own code:
<div class="content">
<div class="corner-box">This is a test</div>
<div class="second-div">
<div class="corner-box">This is a test</div>
</div>
</div>
My CSS for this looks like this:
.content {
display: grid;
grid-template-columns: 1fr;
padding: 200px;
box-sizing: border-box;
align-content: start;
position: relative;
}
.second-div {
width: 100%;
min-height: 100vh;
padding-top: 150px;
align-self: start;
}
.corner-box {
box-sizing: border-box;
background:
linear-gradient(to right, teal 2px, transparent 2px) 0 0,
linear-gradient(to right, teal 2px, transparent 2px) 0 100%,
linear-gradient(to left, teal 2px, transparent 2px) 100% 0,
linear-gradient(to left, teal 2px, transparent 2px) 100% 100%,
linear-gradient(to bottom, teal 2px, transparent 2px) 0 0,
linear-gradient(to bottom, teal 2px, transparent 2px) 100% 0,
linear-gradient(to top, teal 2px, transparent 2px) 0 100%,
linear-gradient(to top, teal 2px, transparent 2px) 100% 100%;
background-repeat: no-repeat;
background-size: 20px 20px;
width: 200px;
height: 100%;
padding: 25px;
transition: all 1.0s ease-in-out;
&:hover {
background:
linear-gradient(to right, teal 2px, transparent 2px) 0 0,
linear-gradient(to right, teal 2px, transparent 2px) 0 100%,
linear-gradient(to left, teal 2px, transparent 2px) 100% 0,
linear-gradient(to left, teal 2px, transparent 2px) 100% 100%,
linear-gradient(to bottom, teal 2px, transparent 2px) 0 0,
linear-gradient(to bottom, teal 2px, transparent 2px) 100% 0,
linear-gradient(to top, teal 2px, transparent 2px) 0 100%,
linear-gradient(to top, teal 2px, transparent 2px) 100% 100%;
background-repeat: no-repeat;
background-size: 50% 50%;
transition: all 1.0s ease-in-out;
}
}
The problem, which I just can't figure out, is that the transition of the corner-box div inside the second-div looks like this (sorry for the bad gif):
I hope it shows that the transition/animation makes the right border of the box kind of shaky/wobbly, resulting in a not so pretty effect.
However, the box outside the second-div container works as intended, i.e.:
I honestly have no idea what is happening here. I have tried to strip anything not needed, and it seems that SOMETIMES it might be a positioning issue. So places where I have the box in containers that are center-aligned it sometimes disappear. But like in this case, there really are no positioning at all. Additionally, if I remove the display: grid it also seems to disappear in this case, but in other cases (as my example in the beginning) display: grid has no effect.
So it's kind of inconclusive. And I just can't remove my display: grid, as that is the basis of my entire setup.
So yeah, does anyone might have an answer to why this is happening ?
Related
I have tried so far.
body {
margin:0;
padding:20px;
background-color: #000;
}
.mobil-menu__icon {
height: 50px;
width: 50px;
background:
linear-gradient(to bottom, #fff 0%, #fff 20%, transparent 20%, transparent 100%),
linear-gradient(to bottom, transparent 0%, transparent 40%, #fff 40%, #fff 60%, transparent 60%, transparent 100%),
linear-gradient(to bottom, transparent 0%, transparent 80%, #fff 80%, #fff 100%);
}
<div class="mobil-menu__icon"></div>
Use only solid color in gradient and rely on background-size:
.mobil-menu__icon {
height: 50px;
width: 50px;
background:
/* position / width height */
linear-gradient(#fff,#fff) top left / 100% 20%,
linear-gradient(#fff,#fff) center left / 80% 20%,
linear-gradient(#fff,#fff) bottom left / 60% 20%,
red;
border:10px solid red;
background-repeat:no-repeat; /* Never forget this! */
}
<div class="mobil-menu__icon"></div>
With hover animation:
.mobil-menu__icon {
height: 50px;
width: 50px;
background:
linear-gradient(#fff,#fff) top left,
linear-gradient(#fff,#fff) center left,
linear-gradient(#fff,#fff) bottom left,
red;
background-size:
100% 20%,
80% 20%,
60% 20%;
border:10px solid red;
background-repeat:no-repeat;
transition:0.3s all;
}
.mobil-menu__icon:hover {
background-size:100% 20%;
}
<div class="mobil-menu__icon"></div>
And if you want with transparency:
.mobil-menu__icon {
height: 50px;
width: 50px;
background:
linear-gradient(red,red) 0 calc(1*100%/4) / 100% 20%,
linear-gradient(red,red) 0 calc(3*100%/4) / 100% 20%,
linear-gradient(red,red) 100% calc(2*100%/4) / 20% 20%,
linear-gradient(red,red) 100% calc(4*100%/4) / 40% 20%;
border:10px solid red;
background-repeat:no-repeat;
}
body {
background:repeating-linear-gradient(to right,white 0 5px,grey 10px);
}
<div class="mobil-menu__icon"></div>
You were also almost good with your code but you were missing the size and the repeat:
body {
margin: 0;
padding: 20px;
background-color: #000;
}
.mobil-menu__icon {
height: 50px;
width: 50px;
background:
linear-gradient(to bottom, #fff 0%, #fff 20%, transparent 20%, transparent 100%),
linear-gradient(to bottom, transparent 0%, transparent 40%, #fff 40%, #fff 60%, transparent 60%, transparent 100%),
linear-gradient(to bottom, transparent 0%, transparent 80%, #fff 80%, #fff 100%);
background-size:100% 100%,80% 100%, 60% 100%;
background-repeat:no-repeat;
}
<div class="mobil-menu__icon"></div>
Related question to get more details about the different values:
Using percentage values with background-position on a linear gradient
I don't how it can't be named in english - I neither don't know in french to be honest - but I need to design an infinite line composed by normal and invert chevron. It's seems to be called a chevron line.
Here's an example of what I want and I only need one line :
Here what I've done so far with before and after pseudo elements. Maybe there's another way that i can't think of. Right now i didn't achieve to display it as chevron, i don't understand how repeating linear gradient works for the position.
.chevron-line {
position: relative;
height: 15px;
background: white;
}
.chevron-line::before,
.chevron-line::after {
content: '';
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.chevron-line::before {
background: repeating-linear-gradient(135deg,
#000, #000 5px /* black stripe */,
transparent 0, transparent 20px /* blue stripe */
);
}
.chevron-line::after {
background: repeating-linear-gradient(-135deg,
transparent 0px, transparent 10px /* blue stripe */,
#000, #000 15px /* black stripe */,
transparent 0px, transparent 20px /* blue stripe */
);
}
<div class="chevron-line"></div>
you can do this with css gradient
div.box {
height: 500px;
background:
linear-gradient(135deg, #ffffff 25%, transparent 25%) -50px 0,
linear-gradient(225deg, #ffffff 25%, transparent 25%) -50px 0,
linear-gradient(315deg, #ffffff 25%, transparent 25%),
linear-gradient(45deg, #ffffff 25%, transparent 25%);
background-size: 100px 100px;
background-color: #000000;
}
<div class="box">
</div>
make it thin like this
div.box {
height: 500px;
background:
linear-gradient(135deg, #ffffff 35%, transparent 35%) -50px 0,
linear-gradient(225deg, #ffffff 35%, transparent 35%) -50px 0,
linear-gradient(315deg, #ffffff 35%, transparent 35%),
linear-gradient(45deg, #ffffff 35%, transparent 35%);
background-size: 100px 100px;
background-color: #000000;
}
<div class="box"></div>
I'm trying to draw using CSS gradients and a single div.
Unfortunately, there is no enough information about it so I needed to learn it myself by reading other people's code. Here are some examples:
https://codepen.io/PButcher/pen/JMRKpG
https://codepen.io/jkantner/pen/zdeJYg
https://codepen.io/jkantner/pen/ppjRBP
https://codepen.io/jkantner/pen/XMLVXa
So far, I've learned how to create only a few basic shapes:
div
{
height: 20em;
width: 20em;
background:
linear-gradient( 0deg, #000 0%, #000 100% ) 1em 1em / 5em 5em,
radial-gradient( circle at center, #000 70%, transparent 70% ) 1em 7em / 5em 5em,
linear-gradient( 45deg, #000 0%, #000 50%, transparent 50% ) 1em 13em / 5em 5em,
linear-gradient( -45deg, #000 0%, #000 50%, transparent 50% ) 7em 1em / 5em 5em,
linear-gradient( 135deg, #000 0%, #000 50%, transparent 50% ) 7em 7em / 5em 5em,
linear-gradient( -135deg, #000 0%, #000 50%, transparent 50% ) 7em 13em / 5em 5em,
radial-gradient( 100% 100% at top, #000 50%, transparent 50% ) 14em 1em / 5em 5em,
radial-gradient( 100% 100% at bottom, #000 50%, transparent 50% ) 14em 2em / 5em 5em,
linear-gradient( 45deg, #000 0%, #000 50%, transparent 50% ) 14em 7em / 4em 7em,
radial-gradient( 100% 50%, #000 0%, #000 50%, transparent 50% ) 14em 14em / 5em 5em;
background-repeat: no-repeat;
}
<div></div>
But, I wanna create more complicated shapes like, for example, this eagle's beak & feathers, or the shadow on it.
Can it be achieved using CSS and a single div?
As I commented above, we can use multiple techniques to achieve something like this :
radial-gradient with either circle or ellipse and by adjusting size and position
.elem {
width:300px;
height:200px;
border:1px solid;
background:
radial-gradient(ellipse at center, red 15%,transparent 15%),
radial-gradient(circle at 40px 120px, #ffc20f 20%,transparent 20%),
radial-gradient(circle at right bottom, #000 25%,transparent 25%);
}
<div class="elem"></div>
Linear-gradient that we can rotate and adjust size and position:
.elem {
width:300px;
height:200px;
border:1px solid;
background:
linear-gradient(20deg,transparent 20%,#ffc20f 20%,#ffc20f 30%,transparent 30%) no-repeat 98px -50px / 51px 151px,
linear-gradient(-20deg,transparent 20%,#ffc20f 20%,#ffc20f 30%,transparent 30%) no-repeat 98px -50px /51px 151px,
linear-gradient(30deg,red 20%,transparent 20%) no-repeat 10px 30px / 50px 50px,
linear-gradient(to right,blue 20%,transparent 20%) no-repeat 70px 20px / 50px 60px,
linear-gradient(40deg,#000 20%,transparent 20%) no-repeat 200px 20px / 15px 100px,
linear-gradient(-40deg,#000 20%,transparent 20%) no-repeat 200px 20px / 15px 100px;
}
<div class="elem" ></div>
There is also the clip-path that can help you to cut your element and adjust the global shape. This will also allow you to have you element above any background. (but this feature is not yet supported by all the browser) :
body {
background: #f2f2f5;
}
.elem {
background: #000;
width: 300px;
height: 200px;
-webkit-clip-path: polygon(3% 39%, 13% 21%, 26% 13%, 47% 14%, 69% 21%, 83% 25%, 90% 33%, 72% 37%, 87% 45%, 62% 49%, 87% 58%, 72% 61%, 58% 62%, 42% 62%, 29% 59%, 17% 64%, 18% 50%, 21% 42%, 10% 48%, 5% 59%);
clip-path: polygon(3% 39%, 13% 21%, 26% 13%, 47% 14%, 69% 21%, 83% 25%, 90% 33%, 72% 37%, 87% 45%, 62% 49%, 87% 58%, 72% 61%, 58% 62%, 42% 62%, 29% 59%, 17% 64%, 18% 50%, 21% 42%, 10% 48%, 5% 59%);
}
<div class="elem"></div>
you can also use pseudo-elements that will allow you to add at max 2 new elements on which you can apply the 3 techniques above and also other CSS property like box-shadow, opacity, filter, transform, etc. This will allow you to divide the shape more easily.
Then the main trick is to use them above each other in order to obtain the final shape.
Here is an ugly start to show that it's possible if you are able to cut the design into different part and calulate different size/positions:
body {
background: red;
}
.eagle {
width: 300px;
height: 200px;
position: relative;
background: radial-gradient(circle at 100px 70px, #000 2.5%, transparent 2.5%), linear-gradient(10deg, transparent 20%, #000 20%, #000 29%, transparent 30%) no-repeat 98px -8px / 142px 86px, linear-gradient(6deg, transparent 20%, #ffc20f 20%, #ffc20f 35%, transparent 35%) no-repeat 98px -50px / 141px 168px, radial-gradient(circle at 150px 100px, #000 15%, transparent 15%), radial-gradient(circle at 110px 130px, #000 15%, transparent 15%), radial-gradient(circle at 100px 100px, #ffc20f 20%, transparent 20%), radial-gradient(circle at 100px 100px, #000 25%, transparent 25%), #ffffff;
clip-path: polygon(18% 35%, 23% 27%, 43% 14%, 64% 10%, 81% 27%, 79% 41%, 62% 66%, 48% 74%, 63% 49%, 46% 47%, 43% 53%, 33% 53%, 34% 52%, 29% 64%, 31% 77%, 20% 69%, 20% 69%, 17% 62%, 15% 52%, 16% 41%);
;
}
.eagle:before {
content: "";
position: absolute;
top: 17%;
left: 60%;
height: 22px;
width: 30px;
border-radius: 50%;
background-image: radial-gradient(circle at center, #000 29%, #ffc20f 20%);
}
.eagle:after {
content: "";
position: absolute;
top: 36%;
left: 58%;
height: 84px;
width: 27px;
transform: rotate(45deg) skewY(-61deg);
background-image: linear-gradient(to right, #000 29%, #ffc20f 20%, #ffc20f 80%, #000 80%);
}
<div class="eagle"></div>
I have created this pattern, consisting of blue and red lines. But I can't find a way to blend the red and the blue lines (to something like dark purple if I'm correct) where they cross each-other (see third case). Any ideas? Using transparency doesn't help as I only want it where they cross.
div{
width:50px; height:100px;
border: solid 2px black;
float:left;
margin:10px;
font-size:30px;
font-weight:bold;
}
.caro-pattern1 {
background-color:#2ECC40;
background-image: linear-gradient(-45deg, blue 5%, transparent 5%, transparent 45%, blue 45%, blue 55%, transparent 55%, transparent 95%, blue 95% );
background-size:50px 50px;
}
.caro-pattern2 {
background-color:#2ECC40;
background-image:
linear-gradient(45deg, red 5%, transparent 5%, transparent 45%, red 45%, red 55%, transparent 55%, transparent 95%, red 95% );
background-size:50px 50px;
}
.caro-pattern3 {
background-color:#2ECC40;
background-image:
linear-gradient(45deg, red 5%, transparent 5%, transparent 45%, red 45%, red 55%, transparent 55%, transparent 95%, red 95% ),
linear-gradient(-45deg, blue 5%, transparent 5%, transparent 45%, blue 45%, blue 55%, transparent 55%, transparent 95%, blue 95% );
background-size:50px 50px;
}
<div class="caro-pattern1">1</div>
<div class="caro-pattern2">2</div>
<div class="caro-pattern3">3</div>
You have one posibility, without changing much your current approach.
Just set the red stripes twice, the first without transparency. On top, set the blue stripes, and on top set againg the red ones, now with alpha:
div {
width: 50px;
height: 100px;
border: solid 2px black;
float: left;
margin: 10px;
font-size: 30px;
font-weight: bold;
}
.caro-pattern3 {
background-color: #2ECC40;
background-image:
linear-gradient(45deg, rgba(255, 0, 0, .5) 5%, transparent 5%, transparent 45%, rgba(255, 0, 0, .5) 45%, rgba(255, 0, 0, .5) 55%, transparent 55%, transparent 95%, rgba(255, 0, 0, .5) 95%),
linear-gradient(-45deg, blue 5%, transparent 5%, transparent 45%, blue 45%, blue 55%, transparent 55%, transparent 95%, blue 95%),
linear-gradient(45deg, red 5%, transparent 5%, transparent 45%, red 45%, red 55%, transparent 55%, transparent 95%, red 95%);
background-size: 50px 50px;
}
<div class="caro-pattern3">3</div>
Another posibility, as posted by Abhitalks, is to use blend mode (with limited browser support). But you need to set it on a pseudo element to avoid blending it with the solid background:
div {
width: 50px;
height: 100px;
border: solid 2px black;
float: left;
margin: 10px;
font-size: 30px;
font-weight: bold;
}
.caro-pattern3 {
background-color: #2ECC40;
position: relative;
}
.caro-pattern3:after {
content: "";
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-image:
linear-gradient(-45deg, blue 5%, transparent 5%, transparent 45%, blue 45%, blue 55%, transparent 55%, transparent 95%, blue 95%),
linear-gradient(45deg, red 5%, transparent 5%, transparent 45%, red 45%, red 55%, transparent 55%, transparent 95%, red 95%);
background-size: 50px 50px;
background-blend-mode: screen;
}
<div class="caro-pattern3">3</div>
You can experiment with the new background-blend-mode, which is currently in editor's draft for Compositing and blending Level 1.
References: background-blend-mode and mix-blend-mode.
Be advised though, that this is currently not supported by IE, Edge and Opera, with partial support in Safari. That leaves only Chrome and Firefox :(
Example Snippet:
div {
width: 50px; height: 100px;
border: solid 2px black;
margin: 10px;
}
.caro-pattern3 {
background-color: #2ECC40;
background-image:
linear-gradient(45deg, red 5%, transparent 5%, transparent 45%, red 45%, red 55%, transparent 55%, transparent 95%, red 95% ),
linear-gradient(-45deg, blue 5%, transparent 5%, transparent 45%, blue 45%, blue 55%, transparent 55%, transparent 95%, blue 95% );
background-size: 50px 50px;
background-blend-mode: color, hard-light;
}
<div class="caro-pattern3">3</div>
I'm trying to make a shape with four negatively curved corners, and I tried the radial gradients. However, only one of the corners is being applied, and I can't figure out why.
https://jsfiddle.net/xiej/1Lqysaho/1/
#shape2 {
width: 120px;
height: 120px;
position: absolute;
top: 400px;
right: 400px;
background-image:
radial-gradient(circle at 0px 0px, #FFF 0px, #FFF 60px, #F00 60px),
radial-gradient(circle at 0px 120px, #FFF 0px, #FFF 60px, #F00 60px),
radial-gradient(circle at 120px 0px, #FFF 0px, #FFF 60px, #F00 60px),
radial-gradient(circle at 120px 120px, #FFF 0px, #FFF 60px, #F00 60px);
}
The last color stop of each radial gradient is covering up the rest of the square, think of them layering over each other. I'm not sure that my fix is the best way to get the shape you're looking for, but I think this will make the shape at least! I shortened the stops to end the radial gradient before it would cover any of the other three corners.
https://jsfiddle.net/1Lqysaho/2/
background: #F00;
background-image:
radial-gradient(circle at 0px 0px, #FFF 60px, #f00 1px, transparent 1px),
radial-gradient(circle at 0px 120px, #FFF 60px,#f00 1px, transparent 1px),
radial-gradient(circle at 120px 0px, #FFF 60px,#f00 1px, transparent 1px),
radial-gradient(circle at 120px 120px, #FFF 60px,#f00 1px, transparent 1px);
div.round {
background:
-webkit-radial-gradient(0 100%, circle, rgba(204,0,0,0) 14px, #c00 15px),
-webkit-radial-gradient(100% 100%, circle, rgba(204,0,0,0) 14px, #c00 15px),
-webkit-radial-gradient(100% 0, circle, rgba(204,0,0,0) 14px, #c00 15px),
-webkit-radial-gradient(0 0, circle, rgba(204,0,0,0) 14px, #c00 15px);
}
div, div.round {
background-position: bottom left, bottom right, top right, top left; c
-moz-background-size: 50% 50%;
-webkit-background-size: 50% 50%;
background-repeat: no-repeat;
}
div {
width: 130px;
height:100px;
margin:15px auto;
padding:13px 15px;
}
<div class="round"></div>