I'm trying to achieve the effect below with pure CSS3. I think that repeating-radial-gradient is the right path to take, but I can't figure out how to get the radial gradient to go "from big to small" horizontally. Any advice?
This is the closest I've gotten jsfiddle. It's close, but it doesn't go "from big to small" horizontally.
.dotted {
padding: 2.25em 1.6875em;
background-color: #ffb55d;
background-image: -webkit-repeating-radial-gradient(center center, #ff9d4b, #ff9d4b 2px, transparent 2px, transparent 100%);
background-image: -moz-repeating-radial-gradient(center center, #ff9d4b, #ff9d4b 2px, transparent 2px, transparent 100%);
background-image: -ms-repeating-radial-gradient(center center, #ff9d4b, #ff9d4b 2px, transparent 2px, transparent 100%);
background-image: repeating-radial-gradient(center center, #ff9d4b, #ff9d4b 2px, transparent 2px, transparent 100%);
-webkit-background-size: 5px 5px;
-moz-background-size: 3px 3px;
background-size: 5px 5px;
}
Much Closer to what you are looking for:
.dotted {
height:100px;
width:100%;
background: radial-gradient(orange 15%, transparent 16%) 1px 1px,
radial-gradient(orange 15%, transparent 16%) 8px 8px,
radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 0 1px,
radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 8px 9px;
background-color:#ffb55d;
background-size:16px 16px;
}
Modified jbutler483's find on codepen (just for fun) (with Chrome):
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="background: rgba(0,0,0,1);">
<div class='halftone' height='100px'></div>
<div class='halftone2' height='100px'></div>
</div>
<style>
* {
margin: 0;
padding: 0;
position: relative;
box-sizing: border-box;
}
html,
body {
height: 100%;
}
div {
height: 100%;
background-color: 0;
}
.halftone {
/*
size progressively decreasing
*/
background-image: radial-gradient(circle, dodgerblue 85%, transparent 0), radial-gradient(circle, dodgerblue 80%, transparent 0), radial-gradient(circle, dodgerblue 75%, transparent 0), radial-gradient(circle, dodgerblue 70%, transparent 0), radial-gradient(circle, dodgerblue 65%, transparent 0), radial-gradient(circle, dodgerblue 60%, transparent 0), radial-gradient(circle, dodgerblue 55%, transparent 0), radial-gradient(circle, dodgerblue 50%, transparent 0), radial-gradient(circle, dodgerblue 45%, transparent 0), radial-gradient(circle, dodgerblue 40%, transparent 0), radial-gradient(circle, dodgerblue 35%, transparent 0), radial-gradient(circle, dodgerblue 30%, transparent 0), radial-gradient(circle, dodgerblue 25%, transparent 0), radial-gradient(circle, dodgerblue 20%, transparent 0);
/*
change all other values when changing this.
I suppose this'd be easier to do in Sass.
*/
background-size: 1em 1em;
/*
If you want a vertical pattern change to repeat-x, also remember to switch the background-positions' values. Eg. "2em 0" becomes "0 2em".
*/
background-repeat: repeat-y;
/*
based on background-size value
*/
background-position: 0 0, 1em 0, 2em 0, 3em 0, 4em 0, 5em 0, 6em 0, 7em 0, 8em 0, 9em 0, 10em 0, 11em 0, 12em 0, 13em 0;
}
.halftone2 {
/*
size progressively increasing
*/
background-image: radial-gradient(circle, dodgerblue 20%, transparent 0), radial-gradient(circle, dodgerblue 25%, transparent 0), radial-gradient(circle, dodgerblue 30%, transparent 0), radial-gradient(circle, dodgerblue 35%, transparent 0), radial-gradient(circle, dodgerblue 40%, transparent 0), radial-gradient(circle, dodgerblue 45%, transparent 0), radial-gradient(circle, dodgerblue 50%, transparent 0), radial-gradient(circle, dodgerblue 55%, transparent 0), radial-gradient(circle, dodgerblue 60%, transparent 0), radial-gradient(circle, dodgerblue 65%, transparent 0), radial-gradient(circle, dodgerblue 70%, transparent 0), radial-gradient(circle, dodgerblue 75%, transparent 0), radial-gradient(circle, dodgerblue 80%, transparent 0), radial-gradient(circle, dodgerblue 85%, transparent 0);
/*
change all other values when changing this.
I suppose this'd be easier to do in Sass.
*/
background-size: 1em .8em;
/*
If you want a vertical pattern change to repeat-x, also remember to switch the background-positions' values. Eg. "2em 0" becomes "0 2em".
*/
background-repeat: repeat-y;
/*
based on background-size value
*/
background-position: 0 0, 1em 0, 2em 0, 3em 0, 4em 0, 5em 0, 6em 0, 7em 0, 8em 0, 9em 0, 10em 0, 11em 0, 12em 0, 13em 0;
}
.halftone {
animation: rt 4s infinite;
animation-direction: alternate;
}
.halftone2 {
animation: rt2 4s infinite;
animation-direction: alternate;
}
#keyframes rt {
0% {
opacity: 0;
transform: rotateY(0deg);
}
25% {
opacity: 1
}
50% {
opacity: 0;
transform: rotateY(180deg);
}
75% {
opacity: 1
}
100% {
opacity: 0;
transform: rotateY(360deg);
}
}
#keyframes rt2 {
0% {
opacity: 1;
transform: rotateY(0deg) translateY(-405px);
}
25% {
opacity: 0
}
50% {
opacity: 1;
transform: rotateY(180deg) translateY(-405px);
}
75% {
opacity: 0
}
100% {
opacity: 1;
transform: rotateY(360deg) translateY(-405px);
}
}
</style>
Okay, looks like this isn't possible via CSS3. I did make it work with an image though, so I guess that's the best answer.
Related
I've put together an animation which indicates a countdown until a toast notification disappears:
.toastDiv {
animation: toastProgress 3s ease;
border: 1px solid rgba(0, 0, 0, .5);
border-radius: 5px;
box-shadow: 0 0 5px 0 rgba(0, 0, 0, .25);
margin: 0 0 1ex 0;
padding: 1ex 1em;
}
#keyframes toastProgress {
0% {
background: linear-gradient(to right, aliceblue 0%, aliceblue 0%, white 0%, white 100%);
}
10% {
background: linear-gradient(to right, aliceblue 0%, aliceblue 10%, white 10%, white 100%);
}
20% {
background: linear-gradient(to right, aliceblue 0%, aliceblue 20%, white 20%, white 100%);
}
30% {
background: linear-gradient(to right, aliceblue 0%, aliceblue 30%, white 30%, white 100%);
}
40% {
background: linear-gradient(to right, aliceblue 0%, aliceblue 40%, white 40%, white 100%);
}
50% {
background: linear-gradient(to right, aliceblue 0%, aliceblue 50%, white 50%, white 100%);
}
60% {
background: linear-gradient(to right, aliceblue 0%, aliceblue 60%, white 60%, white 100%);
}
70% {
background: linear-gradient(to right, aliceblue 0%, aliceblue 70%, white 70%, white 100%);
}
80% {
background: linear-gradient(to right, aliceblue 0%, aliceblue 80%, white 80%, white 100%);
}
90% {
background: linear-gradient(to right, aliceblue 0%, aliceblue 90%, white 90%, white 100%);
}
100% {
background: linear-gradient(to right, aliceblue 0%, aliceblue 100%, white 100%, white 100%);
}
}
<div class="toastDiv">hello</div>
However, it is very tedious to have to spell out the individual animation stages and at the granularity I chose, I am getting choppy results.
I tried using this:
#keyframes toastProgress {
from {
background: linear-gradient(to right, aliceblue 0%, aliceblue 0%, white 0%, white 100%);
}
to {
background: linear-gradient(to right, aliceblue 0%, aliceblue 100%, white 100%, white 100%);
}
}
But this transitions from one solid background to the next instead of animating the color stops from left to right.
Is there a way to make this progress-style gradient animation using only from and to and not percent-steps?
You can rely on background-size animation and steps() like below:
.toastDiv {
border: 1px solid rgba(0, 0, 0, .5);
border-radius: 5px;
box-shadow: 0 0 5px 0 rgba(0, 0, 0, .25);
margin: 0 0 1ex 0;
padding: 1ex 1em;
background:
linear-gradient(aliceblue,aliceblue) left no-repeat,
white;
animation: toastProgress 5s steps(10,start);
}
#keyframes toastProgress {
0% {
background-size:0% 100%;
}
100% {
background-size:100% 100%;
}
}
<div class="toastDiv">hello</div>
<div class="toastDiv" style="animation-timing-function:ease">without Steps</div>
Related to understand how steps() works: https://stackoverflow.com/a/51843473/8620333
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>
When I use this snippet on Chrome, IE, and Firefox and it works fine! But on Safari it doesn't work.
This issue happens:
.circle-red {
border: 2px solid;
border-radius: 51%;
width: 40px;
height: 40px;
background: radial-gradient(ellipse at 80px 40px, rgba(255, 255, 255, 0.75) 10%, rgba(255,255,255,0.5) 32%, rgba(255,255,255,0) 70% ), linear-gradient(160deg, transparent 10%, red 30%);
background-size: 87.5% 55%, 100% 100%;
background-repeat: no-repeat;
}
<div class="circle-red"></div>
Try This adding a webkit prefix on your background-size property and on your background gradient value. Here is an example:
.circle-red {
border: 2px solid;
border-radius: 51%;
width: 40px;
height: 40px;
background: radial-gradient(ellipse at 80px 40px, rgba(255, 255, 255, 0.75) 10%, rgba(255,255,255,0.5) 32%, rgba(255,255,255,0) 70% ), linear-gradient(160deg, transparent 10%, red 30%);
background: -webkit-radial-gradient(ellipse at 80px 40px, rgba(255, 255, 255, 0.75) 10%, rgba(255,255,255,0.5) 32%, rgba(255,255,255,0) 70% ), linear-gradient(160deg, transparent 10%, red 30%);
background-size: 87.5% 55%, 100% 100%;
-webkit-background-size: 87.5% 55%, 100% 100%;
background-repeat: no-repeat;
}