Layering Multiple Gradients on CSS Background - css

I want to create a background with two gradients - layered atop one another.
I created the below example, and it seems like I can't put multiple gradients together. (The example was created based on MDN-Using multiple backgrounds & MDN-gradient)
.radial-gradient {
background: radial-gradient(red, yellow, rgb(30, 144, 255));
}
.linear-repeat {
background: repeating-linear-gradient(45deg,
blue, blue 5px, white 5px, white 10px);
}
.combined-gradient {
background: radial-gradient(red, yellow, rgb(30, 144, 255)),
repeating-linear-gradient(45deg, blue, blue 5px, white 5px, white 10px);
}
<div class="radial-gradient">radial gradient</div><br/>
<div class="radial-gradient linear-repeat">linear gradient</div><br/>
<div class="radial-gradient linear-repeat">combined gradient 1</div><br/>
<div class="combined-gradient">combined gradient 2</div>
Maybe the following constraint prevents layering gradients:
Only the last background can include a background color.
If it's not allowed to layer two gradients as a background, how should I layer them in another way?

I think what you're looking for is this.
What's the problem with your code?
Well, each of your gradient is non-transparent, so one will overlap the other completely and that's why only one is visible. The workaround is, you make use of rgba(x,y,z,alpha) to give them alpha transparency which gives the background a fade effect to see through each other.
.combined-gradient1 {
background: repeating-linear-gradient(45deg, rgba(00, 00, 255, 0.8), rgba(00, 00, 255, 0.8) 5px, rgba(255, 255, 255, 0) 5px, rgba(255, 255, 255, 0) 10px), radial-gradient(rgba(255, 0, 0, 0.8), rgba(255, 255, 0, 0.8), rgba(30, 144, 255, 0.8));
}
.combined-gradient2 {
background: radial-gradient(rgba(255, 0, 0, 0.8), rgba(255, 255, 0, 0.8), rgba(30, 144, 255, 0.8)), repeating-linear-gradient(45deg, rgba(00, 00, 255, 1), rgba(00, 00, 255, 1) 5px, rgba(255, 255, 255, 0) 5px, rgba(255, 255, 255, 0) 10px);
}
<div class="combined-gradient1">combined gradient 1</div>
<br>
<div class="combined-gradient2">combined gradient 2</div>

Related

Same background color, different gradient width

I'm trying to get a background color on part of some tds, so that it looks similar to a progress bar background:
From left to somewhere in the middle, it's colored, and after that percentage, it's white.
And if it's 100%, of course, the whole td is colored.
The color, a linear-gradient, is the same on all tds, but the length will differ. I only have 3 lengths:
30%
70%
100%
Also 0%, but it's just empty then, so this is out of the question
For this, I'm using a specific class for each variation, .progress_**.
Every class has two linear-gradients on the background property.
This is my current working CSS:
.progress_30 {
background:
linear-gradient(to right,
rgba(0, 0, 0, 0) 0%,
rgba(255, 255, 255, 0) 30%,
rgba(255, 255, 255, 1) 30%
),
linear-gradient(to right, yellow, green)
;
}
.progress_70 {
background:
linear-gradient(to right,
rgba(0, 0, 0, 0) 0%,
rgba(255, 255, 255, 0) 70%,
rgba(255, 255, 255, 1) 70%
),
linear-gradient(to right, yellow, green)
;
}
.progress_100 {
background:
linear-gradient(to right,
rgba(0, 0, 0, 0) 0%,
rgba(255, 255, 255, 0) 100%,
rgba(255, 255, 255, 1) 100%
),
linear-gradient(to right, yellow, green)
;
}
As you can see, there is a lot that repeats.
I want at least to put the color in a separate .progress class, so it can be changed easily without altering the lengths, and so I can add or alter some lengths without touching the colors in the future.
So I tried this:
.progress {
background: linear-gradient(to right, yellow, green);
}
.progress_30 {
background:
linear-gradient(to right,
rgba(0, 0, 0, 0) 0%,
rgba(255, 255, 255, 0) 30%,
rgba(255, 255, 255, 1) 30%
)
;
}
.progress_70 {
background:
linear-gradient(to right,
rgba(0, 0, 0, 0) 0%,
rgba(255, 255, 255, 0) 70%,
rgba(255, 255, 255, 1) 70%
)
;
}
.progress_100 {
background:
linear-gradient(to right,
rgba(0, 0, 0, 0) 0%,
rgba(255, 255, 255, 0) 100%,
rgba(255, 255, 255, 1) 100%
)
;
}
This doesn't fully work: the white part on the right is the correct length. But on the left, I don't see my linear-gradient, only the page's background color (which isn't white).
Is there a way I can get as few repetitions as possible in CSS, at least have the linear-gradient's color set only once, or do I have to do it like in my first example?
You can rely on background-size and keep the gradient declaration within the same class:
div {
min-height: 50px;
}
.progress {
background:
linear-gradient(#fff, #fff) right no-repeat,
linear-gradient(to right, yellow, green);
}
.progress_30 {
background-size: 70% 100%, auto;
}
.progress_70 {
background-size: 30% 100%, auto;
}
.progress_100 {
background-size: 0% 100%, auto;
}
<div class="progress progress_30"></div>
<div class="progress progress_70"></div>
<div class="progress progress_100"></div>
You can simplify more using CSS variable in case you want to consider more percentage values:
div {
min-height: 50px;
}
.progress {
background:
linear-gradient(#fff, #fff) right/calc(100% - var(--p,50%)) 100% no-repeat,
linear-gradient(to right, yellow, green);
}
<div class="progress" style="--p:30%"></div>
<div class="progress" style="--p:68%"></div>
<div class="progress" style="--p:80%"></div>
<div class="progress" ></div>

Two linear gradients layers on div

I have a coloured rectangle div on which I put linear gradient at 45 degrees to achieve zebra-like effect. I'd like to layer the second gradient, on 135 degrees (orthogonal to the previous one).
height: 30px;
background-color: rgb(255, 0, 0);
background-image:
repeating-linear-gradient(45deg, rgb(255, 0, 0), rgb(255, 0, 0) 10px, rgb(0, 255, 0) 10px, rgb(0, 255, 0) 20px),
repeating-linear-gradient(135deg, rgb(255, 0, 0), rgb(255, 0, 0) 10px, rgb(0, 0, 255) 10px, rgb(0, 0, 255) 20px);
The main color is red, the first stripes are green and the last ones are intended to be blue. However I cannot see the last ones stripes in blue.
Achieved effect:
Expected effect:
How do I add multiple gradients overlapping themselves?
I don't believe you can layer two gradients on top of each other like that if they are all solid colors.
However, you can use some transparency and a bit of creative thinking to get your desired effect.
Your background-color, is already red, so replace all the references to red in your first gradient with transparent. Now you've got a pattern of stripes that are green and transparent. The transparent stripes appear red since that's the background color.
Then do a similar color-transparent stripe pattern for your second gradient: blue and transparent.
That ends up giving us our pattern backwards from how you want it, so the final step is to swap the two gradients, so the blue stripes are on top of the green ones.
div {
height: 30px;
background-color: rgb(255, 0, 0);
background-image: repeating-linear-gradient(135deg, transparent, transparent 10px, rgb(0, 0, 255) 10px, rgb(0, 0, 255) 14px), repeating-linear-gradient(45deg, transparent, transparent 10px, rgb(0, 255, 0) 10px, rgb(0, 255, 0) 20px);
}
<div class="one"></div>
#vals points out that you could also use transparency with your blue stripes on top of a red-green stripe pattern. So in your original code, in the red-blue stripe pattern, you'd replace the red references with transparent. Then, as with the first option, you'd flip the order of the gradients, so the blue-transparent pattern is first.
With that approach, the overall pattern wouldn't rely on the background-color, so it'd be more of a fallback.
div {
height: 30px;
background-color: rgb(255, 0, 0);
background-image: repeating-linear-gradient(135deg, transparent, transparent 10px, rgb(0, 0, 255) 10px, rgb(0, 0, 255) 14px), repeating-linear-gradient(45deg, rgb(255, 0, 0), rgb(255, 0, 0) 10px, rgb(0, 255, 0) 10px, rgb(0, 255, 0) 20px);
}
<div></div>

Using multiple CSS gradients

I want to create a rainbow effect that fades using CSS gradients.
Vertically, I want the rainbow effect:
background: linear-gradient(to bottom, red, orange, yellow, green, blue, violet);
Horizontally, I want the fading effect:
background: linear-gradient(to right, rgba(1,1,1,1), rgba(1,1,1,0));
My initial thought was to have two divs, the outer with the transparency, and the inner with the rainbow, but the transparency just got swallowed. Then it occurred to me that background on the outer element is not what will make this work. It'd need to be filter for that pattern to work.
So either I need to figure out how to make filter work with a gradient (possibly an SVG that I can stretch?), or I need to use a single <div> whose background somehow takes into account both linear gradients. I'd prefer the latter, since it's much simpler.
Are either of these possible?
Update
Looking at How to add multiple css gradient as a multiple background? makes it look like I should just be able to do:
background: linear-gradient(to right, rgba(1,1,1,1), rgba(1,1,1,0)), linear-gradient(to bottom, red, orange, yellow, green, blue, violet);
This is getting me close, but the horizontal gradient isn't causing the vertical gradient to gain transparency; rather, it's causing it to go from black to fully visible.
.rainbow {
height: 200px;
background: linear-gradient(to right, rgba(1,1,1,1), rgba(1,1,1,0)), linear-gradient(to bottom, red, orange, yellow, green, blue, violet);
}
<div class='rainbow'></div>
I've also noticed that in the first gradient, the first three values in rgba() don't matter--only the alpha does. I don't know what to make of this.
.rainbow {
height: 200px;
background: linear-gradient(to right, rgba(255, 255, 255, 0.7), rgba(1, 1, 1, 0)), linear-gradient(to bottom, red, orange, yellow, green, blue, violet);
}
<div class='rainbow'></div>
Check this Out
Just less complications when you can use a gradient generator for css backgrounds. Handy and easy to use. Some things are better left off lazy.
rainbow {
background: red; /* not working, let's see some red */
background: -moz-linear-gradient( top ,
rgba(255, 0, 0, 1) 0%,
rgba(255, 255, 0, 1) 15%,
rgba(0, 255, 0, 1) 30%,
rgba(0, 255, 255, 1) 50%,
rgba(0, 0, 255, 1) 65%,
rgba(255, 0, 255, 1) 80%,
rgba(255, 0, 0, 1) 100%);
background: -webkit-gradient(linear, left top, left bottom,
color-stop(0%, rgba(255, 0, 0, 1)),
color-stop(15%, rgba(255, 255, 0, 1)),
color-stop(30%, rgba(0, 255, 0, 1)),
color-stop(50%, rgba(0, 255, 255, 1)),
color-stop(65%, rgba(0, 0, 255, 1)),
color-stop(80%, rgba(255, 0, 255, 1)),
color-stop(100%, rgba(255, 0, 0, 1)));
}

How can I avoid the gradient that is generated only in Chrome?

This gradient from one color to another only happens in chrome.
In Firefox:
In Chrome:
The full code:
background: rgb(216, 216, 216);
background: -moz-linear-gradient(top, rgba(255, 255, 255, 1) 5%, rgba(216, 216, 216, 1) 33%, rgba(255, 255, 255, 1) 33%, rgba(255, 255, 255, 1) 70%, rgba(216, 216, 216, 1) 70%, rgba(255, 255, 255, 1) 93%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(5%, rgba(255, 255, 255, 1)), color-stop(33%, rgba(216, 216, 216, 1)), color-stop(33%, rgba(255, 255, 255, 1)), color-stop(70%, rgba(255, 255, 255, 1)), color-stop(70%, rgba(216, 216, 216, 1)), color-stop(93%, rgba(255, 255, 255, 1)));
background: -webkit-linear-gradient(top, rgba(255, 255, 255, 1) 5%, rgba(216, 216, 216, 1) 33%, rgba(255, 255, 255, 1) 33%, rgba(255, 255, 255, 1) 70%, rgba(216, 216, 216, 1) 70%, rgba(255, 255, 255, 1) 93%);
background: -o-linear-gradient(top, rgba(255, 255, 255, 1) 5%, rgba(216, 216, 216, 1) 33%, rgba(255, 255, 255, 1) 33%, rgba(255, 255, 255, 1) 70%, rgba(216, 216, 216, 1) 70%, rgba(255, 255, 255, 1) 93%);
background: -ms-linear-gradient(top, rgba(255, 255, 255, 1) 5%, rgba(216, 216, 216, 1) 33%, rgba(255, 255, 255, 1) 33%, rgba(255, 255, 255, 1) 70%, rgba(216, 216, 216, 1) 70%, rgba(255, 255, 255, 1) 93%);
background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 5%, rgba(216, 216, 216, 1) 33%, rgba(255, 255, 255, 1) 33%, rgba(255, 255, 255, 1) 70%, rgba(216, 216, 216, 1) 70%, rgba(255, 255, 255, 1) 93%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#d8d8d8', endColorstr='#ffffff', GradientType=0);
Yesterday I stumbled upon a similar problem and decided to post my solution.
I am using SCSS but I really don't think it matters.
The idea is to use two maps: one with colors and one with stops.
Then iterate over the maps and generate multiple backgrounds.
TL;DR You can see the demo live here
I am using a mixin for this because I like to reuse things:
/**
* Create a single background image using CSS gradients
* without blur between color stops.
* This can be achieved with a single linear-gradient,
* but in only Firefox will render it properly.
* All other browsers will blur the edges of the stops.
*
* #param $colors - Map of colors
* #param $stops - Map of color stops
* #param $direction - One of 'horizontal' or 'vertical'
* #return - Multiple background declaration consisting of
* many linear gradients
*
* It's important that the keys of both maps are the same.
*/
#mixin rainbow($colors, $stops, $direction: 'horizontal') {
$dir: to right;
$background: '';
#if $direction == 'vertical' {
$dir: to bottom;
}
#each $name, $color in $colors {
$list: map-keys($colors);
$slash: unquote('/');
$index: index($list, $name);
$comma: unquote(', ');
#if $index == length($list) {
$comma: unquote('');
}
$offset: map-get($stops, $name);
$gradient: linear-gradient($dir, $color 0%, $color 100%);
$size: $offset 100%;
#if $direction == 'vertical' {
$size: 100% $offset;
}
// prettier-ignore
$background: $background + $gradient no-repeat 0% 0% $slash $size + $comma;
}
$background: unquote($background);
background: $background;
}
And then I am creating two maps - one with colors and one with color stops.
It's important to mention that the keys of the maps should be the same:
// DEMO
body {
background: black;
}
div {
$blue: blue;
$green: green;
$orange: orange;
$purple: purple;
$red: red;
$colors: (
'blue': $blue,
'green': $green,
'orange': $orange,
'purple': $purple,
'red': $red
);
$stops: (
'blue': 30%,
'green': 45%,
'orange': 62%,
'purple': 87%,
'red': 100%
);
height: 20px;
#include rainbow($colors, $stops);
}
Now let's see how will it work for your use case.
I am using a dummy span element:
span {
$white: #fff;
$gray: #d8d8d8;
$colors: (
'1': $white,
'2': $gray,
'3': $white,
'5': $gray
);
$stops: (
'1': 5%,
'2': 33%,
'3': 70%,
'5': 100%
);
height: 200px;
display: block;
#include rainbow($colors, $stops, 'vertical');
}
Use Browser prefixes for different browsers, for mozilla, go through this.
background: -moz-linear-gradient(top, rgba(255,255,255,1) 5%,rgba(216,216,216,1) 33%,rgba(255,255,255,1) 33%,rgba(255,255,255,1) 70%,rgba(216,216,216,1) 70%,rgba(255,255,255,1) 93%);
i had the same problem, here's a workaround i just found, at least works for me (Chrome 48.0):
For direction (first argument) use angle instead of descriptive direction, and for Chrome change the angle just slightly, like by 0.01deg. It won't be noticeable, but it will render crisp.
You can put it into browser specific property, so other browsers aren't affected (because it will work the other way around for them - slightly slanted direction will get you slightly blurry gradient).
Just bear in mind that -webkit-linear-gradient has different angle defaults: vertical 'to bottom' gradient equals 180deg angle value in other browsers, while in webkit it's -90deg.
Thus, for vertical gradient, add:
-webkit-linear-gradient(-89.99deg, colorstops....)
...and add it after linear-gradient, to override it, because Chrome reads both declarations (standard and vendor-prefixed)

CSS Background Gradient Pattern - Dashed Lines

I'm wanting to recreate the background pattern on https://meta.stackexchange.com/, and was wondering if it's achievable through CSS gradients?
I've managed to do the squares, but adding the dashed lines is proving troublesome.
background-color: #16A6DA;
background-image: linear-gradient(0deg, transparent 24%, rgba(255, 255, 255, .05) 25%, rgba(255, 255, 255, .05) 26%, transparent 27%, transparent 74%, rgba(255, 255, 255, .05) 75%, rgba(255, 255, 255, .05) 76%, transparent 77%, transparent), linear-gradient(90deg, transparent 24%, rgba(255, 255, 255, .05) 25%, rgba(255, 255, 255, .05) 26%, transparent 27%, transparent 74%, rgba(255, 255, 255, .05) 75%, rgba(255, 255, 255, .05) 76%, transparent 77%, transparent);
background-size:50px 50px;
http://jsfiddle.net/04fjos8x/
I suggest you to take a look in the following links. They're CSS generators which could save you some time. I hope they help you.
Ultimate CSS Gradient Generator
Linear gradients
CSS background patterns - this is good
Well its not semantic but its what you requested i think:
http://cssdeck.com/labs/full/zfogyyuf
I created a lot of empty div-s and added borders to those divs. Using the borders of the divs created using only HTML & CSS a design like you requested.
Probably some jQuery/Javascript could have been used there too to "infinitely" create new empty divs but i didnt wanted to use javascript since it was just an easy example.
http://jsfiddle.net/04fjos8x/1/
Apply your initial grid to your html then apply this to your body:
body {
width: 100%;
background-image: linear-gradient(0deg, transparent 24%, rgba(22, 166, 218, 1) 25%, rgba(22, 166, 218, 1) 26%, transparent 27%, transparent 74%, rgba(22, 166, 218, 1) 75%, rgba(22, 166, 218, 1) 76%, transparent 77%, transparent), linear-gradient(90deg, transparent 24%, rgba(22, 166, 218, 1) 25%, rgba(22, 166, 218, 1) 26%, transparent 27%, transparent 74%, rgba(22, 166, 218, 1) 75%, rgba(22, 166, 218, 1) 76%, transparent 77%, transparent);
background-size: 10px 10px;
height: 100%;
}
Make sure your html has its width and height set to 100%.
Basically applying blue lines on top of your white lines at a smaller distance (background-size).

Resources