Why can't you create a checkered background using something like this?
background-color:#ccc;
background-image:linear-gradient(90deg, transparent 50%, #aaa 50%),
linear-gradient(90deg, #aaa 50%, #ccc 50%);
background-size:50px 50px,50px 50px;
background-position:0 0, 0 25px;
The idea is to layer the alternating colors on the bottom of a striped square. It doesn't work but it seems like it should.
Here is an exact replica of what a checkered background looks in a graphic design editor like Photoshop or Illustrator. (ALL CSS)
.checkered{
height: 240px;
background: -webkit-linear-gradient(45deg, rgba(0, 0, 0, 0.0980392) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.0980392) 75%, rgba(0, 0, 0, 0.0980392) 0), -webkit-linear-gradient(45deg, rgba(0, 0, 0, 0.0980392) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.0980392) 75%, rgba(0, 0, 0, 0.0980392) 0), white;
background: -moz-linear-gradient(45deg, rgba(0, 0, 0, 0.0980392) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.0980392) 75%, rgba(0, 0, 0, 0.0980392) 0), -moz-linear-gradient(45deg, rgba(0, 0, 0, 0.0980392) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.0980392) 75%, rgba(0, 0, 0, 0.0980392) 0), white;
background: linear-gradient(45deg, rgba(0, 0, 0, 0.0980392) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.0980392) 75%, rgba(0, 0, 0, 0.0980392) 0), linear-gradient(45deg, rgba(0, 0, 0, 0.0980392) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.0980392) 75%, rgba(0, 0, 0, 0.0980392) 0), white;
background-repeat: repeat, repeat;
background-position: 0px 0, 5px 5px;
-webkit-transform-origin: 0 0 0;
transform-origin: 0 0 0;
-webkit-background-origin: padding-box, padding-box;
background-origin: padding-box, padding-box;
-webkit-background-clip: border-box, border-box;
background-clip: border-box, border-box;
-webkit-background-size: 10px 10px, 10px 10px;
background-size: 10px 10px, 10px 10px;
-webkit-box-shadow: none;
box-shadow: none;
text-shadow: none;
-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
transition: none;
-webkit-transform: scaleX(1) scaleY(1) scaleZ(1);
transform: scaleX(1) scaleY(1) scaleZ(1);
}
You can see a working example in my pen here
This implementation yields a checkered background on Chrome, Firefox and Safari:
body {
background-image:
linear-gradient(45deg, #000 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, #000 75%),
linear-gradient(45deg, transparent 75%, #000 75%),
linear-gradient(45deg, #000 25%, #fff 25%);
background-size:100px 100px;
background-position:0 0, 0 0, -50px -50px, 50px 50px;
}
This style defines a four part background image. Each linear-gradient defines a black triangle. The triangles are shifted so that they align to form squares (two triangles each). The last linear-gradient defines the color of the other two squares (the negative space). The positioning of the third and fourth triangle is what makes it work. (They would otherwise be positioned on top of the other two similar styles.) See the result in the fiddles provided (for a better understanding replace #000 with four different colors and change #fff to transparent):
http://jsfiddle.net/1o0f34hp
Applied to a div:
http://jsfiddle.net/1o0f34hp/1
However there does seem to be some tearing along the edges between triangles in the Firefox. This artifact is referenced here:
background image, linear gradient jagged edged result needs to be smooth edged
I've also implemented this as a React styled-component as follows:
let dark = '#777';
let light = '#ccc';
export const Checkerboard = styled.div`
background-image: linear-gradient(45deg, ${dark} 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, ${dark} 75%),
linear-gradient(45deg, transparent 75%, ${dark} 75%),
linear-gradient(45deg, ${dark} 25%, ${light} 25%);
background-size: ${props => `${props.size} ${props.size}`};
background-position: 0 0, 0 0,
${props =>
`calc(${props.size} / -2) calc(${props.size} / -2), calc(${
props.size
} / 2) calc(${props.size} / 2)`};
`;
After a lot of playing around and trying to do this in other ways I actually understood what you wanted to do :-). And you were actually very close. You had one single problem: Both your gradients have 90deg, so they covered each other. Also there's no need for the background color since the gradient in the back does not have any transparency and it covers everything.
html {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
background-image:linear-gradient(0deg, transparent 50%, #aaa 50%),
linear-gradient(90deg, #aaa 50%, #ccc 50%);
background-size:50px 50px,50px 50px;
background-position:0 0, 0 25px;
}
Also see this great post for how to create a proper checkerboard: http://lea.verou.me/2011/02/checkerboard-pattern-with-css3/
I made this simplified version. Set color & size in root properties in CSS.
:root {
--checker-color-1: #abcedf;
--checker-color-2: #123456;
--checker-size: 20px;
--checker-gradient: linear-gradient(45deg, var(--checker-color-1) 25%, transparent 25%, transparent 75%, var(--checker-color-1) 75%);
}
body {
background-color: var(--checker-color-2);
background-image: var(--checker-gradient), var(--checker-gradient);
background-position: 0 0, var(--checker-size) var(--checker-size);
background-size: calc(var(--checker-size) * 2) calc(var(--checker-size) * 2);
}
<!DOCTYPE html>
<html>
<head>
<title>CSS Checkered Background</title>
<meta charset="utf-8">
</head>
<body>
</body>
</html>
Updates:
This snippet was derived from CSS Checkered Background which shows a few more options.
But I have also since learned a new way of achieving the same effect, but it uses SVG (as well as JavaScript to create the SVG) SVG Checkered Background. Each method though has its own caveats.
Here is another tweak on this design but on a bias.
Please note that the background-size is important to keep a smooth transition in this pattern.
html {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
background:repeating-linear-gradient(135deg, rgba(0,64,101,0.7) 40%, #004065 60%),
repeating-linear-gradient(45deg, rgba(0,80,126,0.7) 40%, #004065 60%);
background-size:12px 18px;
background-position: 0 0;
}
To change the color of the background, alter the second hex color in both repeating linear gradients.
Hope this helps someone
While the previous answers show that it is possible, in most cases it's probably better to use an actual background image.
A 10x10 PNG checker image is around 80 bytes.
That is 108 bytes base64-encoded, and 148 bytes for the complete CSS rule - less than the shortest pure-CSS solution.
A 2x2 PNG image is not much smaller, but needs additional CSS for scaling and rendering.
The best solution I came up with is to use conic-gradient(). This also avoids the artifacts produced by linear-gradient() with 45deg.
function setVar(name, value) {
document.getElementById('checkered').style.setProperty(name, value);
}
.checkered {
--color-1: #808080;
--color-2: #a9a9a9;
--size: 8px;
background-image: conic-gradient(var(--color-1) 25%, var(--color-2) 25%, var(--color-2) 50%, var(--color-1) 50%, var(--color-1) 75%, var(--color-2) 75%);
background-size: calc(var(--size)*2) calc(var(--size)*2);
}
input {
margin: 4px;
height: 32px;
box-sizing: border-box;
border: 2px solid lightgray;
border-radius: 4px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Checkered Background Image (Pure CSS)</title>
</head>
<body style="margin:0; width:100vw; height:100vh;">
<div id="checkered" class="checkered" style="width:100%; height:100%; padding: 20px; box-sizing:border-box; display:flex; align-items:start;">
<div style="background-color:white; padding:8px; border-radius:9px; display:flex;">
<input type="color" name="color-1" value="#808080" oninput="setVar('--color-1', this.value)">
<input type="color" name="color-2" value="#a9a9a9" oninput="setVar('--color-2', this.value)">
<input type="number" name="size" min="1" value="8" oninput="setVar('--size', this.value + 'px')">
</div>
</div>
</body>
</html>
I made a checkerboard pattern based on 10x10 squares in the Terminal with ImageMagick like this:
magick -size 10x10 xc:"gray(154)" xc:"gray(102)" +append \( +clone -flop \) -append -strip checkerboard.png
That looks like this:
Now, if I want the base64 representation I can do:
magick -size 10x10 xc:"gray(154)" xc:"gray(102)" +append \( +clone -flop \) -append -strip png:- | base64
That gives this:
iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAAAAACo4kLRAAAAH0lEQVQY02OcxQADZ+AsJgYsYKgIsiD8YTJInEShIAA1NwKQeKc4/QAAAABJRU5ErkJggg==
which is just 120 characters!!!
Then I can use that for the repeating background like this:
<div style="background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAAAAACo4kLRAAAAH0lEQVQY02OcxQADZ+AsJgYsYKgIsiD8YTJInEShIAA1NwKQeKc4/QAAAABJRU5ErkJggg==)">'
And if I put a red <img> with a gradient transparency, on that background, I get:
Related
It's easy to create a rainbow in CSS using linear-gradient.
#grad1 {
height: 200px;
background: linear-gradient(45deg, red, orange, yellow, green, blue, indigo, violet, red);
}
<div id="grad1"></div>
But look at it! This gradient is aesthetically horrifying. It's streaky, there's ugly strips of pure colour where the endpoints meet, it doesn't loop very well, it's not smooth, and the colours clearly contrast against each other when they should seamlessly blend.
In short: it's a terrible gradient.
I'd like to find the perfect gradient. One that encompasses the rainbow in a slick, smooth way, one that doesn't leave any obvious bumps or visual tearing. Instead of a spiky mess, this gradient is a smooth curve.
Does this gradient exist?
You need to choose colors that will blend nicely together and more color steps.
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%);
.rainbow-box {
width: 80vw;
height: 200px;
border-radius: 5px;
background: linear-gradient(
90deg,
rgba(255, 0, 0, 1) 0%,
rgba(255, 154, 0, 1) 10%,
rgba(208, 222, 33, 1) 20%,
rgba(79, 220, 74, 1) 30%,
rgba(63, 218, 216, 1) 40%,
rgba(47, 201, 226, 1) 50%,
rgba(28, 127, 238, 1) 60%,
rgba(95, 21, 242, 1) 70%,
rgba(186, 12, 248, 1) 80%,
rgba(251, 7, 217, 1) 90%,
rgba(255, 0, 0, 1) 100%
);
}
<div class="rainbow-box"></div>
I made it using CSS gradient generator:
https://cssgradient.io/
You can get something that looks better by overlaying the individual red, green, and blue colours, trying to match the human colour cone sensitivities.
Here's an example, but it could be improved by adjusting some of the % numbers in the linear-gradients, and by having smother gradient shapes (currently triangles with cut-off tops).
<!DOCTYPE html>
<html>
<head>
<title>Rainbow</title>
<meta charset="UTF-8" />
<style>
* { box-sizing: border-box; }
.separate { width: 100%; height: 10em; }
.separate>* { width: 100%; height: 100%; margin-top: 1em; }
.overlay { width: 100%; height: 10em; filter: brightness(3); }
.overlay>* { width: 100%; height: 100%; position: absolute; }
.overlay>:nth-of-type(1) { opacity: 1; }
.overlay>:nth-of-type(2) { opacity: .5; }
.overlay>:nth-of-type(3) { opacity: .33; }
.overlay>:nth-of-type(4) { opacity: .25; }
.blue { background: linear-gradient(
90deg, rgb(0,0,256) 0%, rgb(0,0,256) 5%, rgb(0,0,0) 20% ); }
.green { background: linear-gradient(
90deg, rgb(0,0,0) 0%, rgb(0,256,0) 25%, rgb(0,256,0) 35%, rgb(0,0,0) 55% ); }
.red { background: linear-gradient(
90deg, rgb(0,0,0) 15%, rgb(256,0,0) 35%, rgb(256,0,0) 45%, rgb(0,0,0) 100% ); }
.blue2 { background: linear-gradient(
90deg, rgb(0,0,0) 65%, rgb(0,0,256) 95%, rgb(0,0,256) 100% ); }
</style>
</head>
<body>
<h1>Rainbow</h1>
<div class="overlay">
<div class="blue"></div>
<div class="green"></div>
<div class="red"></div>
<div class="blue2"></div>
</div>
<div class="separate">
<div class="blue"></div>
<div class="green"></div>
<div class="red"></div>
<div class="blue2"></div>
</div>
</body>
</html>
"Rainbow" or "Color wheel" is often referred to as Hue.
CSS has the hsl() function (stands for Hue, Saturation, Lightness).
To create the gradients, simply divide the 360 hue degrees by 12 main colors (= 30 deg. steps).
Apply increments on the Hue by 30 degrees:
#hue {
height: 40px;
background: linear-gradient(90deg,
hsl(0, 100%, 50%),
hsl(30, 100%, 50%),
hsl(60, 100%, 50%),
hsl(90, 100%, 50%),
hsl(120, 100%, 50%),
hsl(150, 100%, 50%),
hsl(180, 100%, 50%),
hsl(210, 100%, 50%),
hsl(240, 100%, 50%),
hsl(270, 100%, 50%),
hsl(300, 100%, 50%),
hsl(330, 100%, 50%),
hsl(360, 100%, 50%)
);
}
<div id="hue"></div>
I’m not a CSS programmer, but just using the linear gradient fill in MS Word/Excel/PowerPoint, I like to create my rainbow with just the following 4 RGB colors:
(255,0,0) ; (255,255,0) ; (0,192,255) ; (192,0,255).
That looks pretty good to me, and with very little effort! {See Images >>}
Another variation of the rainbow above is “Sunset over the Ocean”. (It will make a great background for a webpage). Start with the rainbow, replace the last (purple) color with the following dark blue one: (60,70,200). Then move the yellow slider right up against the light blue one (mine is at 60% and 61%). And that’s it! {See Image >>}
I managed to do it in CSS! :-) >>
.Rainbow-4Color-Mix
{ width:200px; height:350px;
background: linear-gradient(180deg,
rgba(255, 0, 0, 1) 0%,
rgba(255, 255, 0, 1) 33%,
rgba(0, 192, 255, 1) 66%,
rgba(192, 0, 255, 1) 100%);
}
.Gap {width:200px; height:50px; background-color:white;}
.Ocean-Sunset
{ width:200px; height:350px;
background: linear-gradient(180deg,
rgba(255, 0, 0, 1) 0%,
rgba(255, 255, 0, 1) 60%,
rgba(0, 192, 255, 1) 61%,
rgba(60, 70, 200, 1) 100%);
}
<div class="Rainbow-4Color-Mix"></div>
<div class="Gap"></div>
<div class="Ocean-Sunset"></div>
Just an idea: Instead of explicitly specifying all of the colors in the rainbow, you could just specify red, yellow, and blue. The colors should then just blend naturally.
Another idea: If you don't like these particular shades of yellow, red, and blue, you could try custom ones with RGB values. The basic idea is the same though with only using the three primary colors in the rainbow.
EDIT: You can add violet back in by adding red at the end.
#grad1 {
height: 200px;
background: linear-gradient(45deg, red, yellow, blue, red);
}
<div id="grad1"></div>
Instead of falling back on SVG, I'd love to accomplish this with pure CSS.
There are a number of tutorials on clipped edges using a series of Linear Gradients, i.e.
background: linear-gradient(135deg, transparent 15px, blue 0) top left,
linear-gradient(-135deg, transparent 15px, blue 0) top right,
linear-gradient(-45deg, transparent 15px, blue 0) bottom right,
linear-gradient(45deg, transparent 15px, blue0) bottom left;
background-size: 50% 50%;
background-repeat: no-repeat;
And a diagonal "linear gradient" can also be accomplished quite easily, i.e.
background: linear-gradient(290deg, blue 50%, darkblue 50%);
Is there a way to combine these two techniques to get something like the box pictured below?
Edit: Internet Explorer compatibility would be great.
-webkit-clip-path
clip-path
Are not IE compatible to my knowledge.
You can define one transparent corner via background gradient. However, when you declare more than one, they paint over the transparency defined by the previous rule. In essence, they paint over each other.
A better solution is to use clip-path. For simple shapes, you can use clippy.
body {
background: black;
}
#gradients {
width: 200px;
height: 50px;
background: linear-gradient(135deg, rgba(255, 255, 255, 0) 15px, rgba(255, 0, 0, 1) 0) top left, linear-gradient(-135deg, rgba(255, 255, 255, 0) 15px, rgba(255, 0, 0, 1) 0) top right, linear-gradient(-45deg, rgba(255, 255, 255, 0) 15px, rgba(255, 0, 0, 1) 0) bottom right, linear-gradient(45deg, rgba(255, 255, 255, 0) 15px, blue) bottom left;
}
#gradientsPaintover {
margin: 30px 0 0 0;
width: 200px;
height: 50px;
background: linear-gradient(135deg, rgba(255, 255, 255, 0) 15px, rgba(0, 255, 0, 0.4) 0) top left, linear-gradient(-135deg, rgba(255, 255, 255, 0) 15px, rgba(0, 0, 255, 1) 0) top right;
}
#clip {
background: red;
margin: 30px 0 0 0;
width: 200px;
height: 50px;
-webkit-clip-path: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%);
clip-path: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%);
}
<div id="gradients"></div>
<div id="gradientsPaintover"></div>
<div id="clip"></div>
Serg's answer was helpful in solving the problem, but I thought'd I'd post a complete solution.
background: linear-gradient(290deg, blue 50%, darkblue 50%);
-webkit-clip-path: polygon(5% 0, 95% 0, 100% 10%, 100% 90%, 95% 100%, 5% 100%, 0 90%, 0 10%);
clip-path: polygon(5% 0, 95% 0, 100% 10%, 100% 90%, 95% 100%, 5% 100%, 0 90%, 0 10%);
A note that this will not work at all in IE and you should pursue the SVG option in that case.
Edit: spending some more time with this, there's no reason you couldn't create pseudo elements before and after your div that contains a linear-gradient to add the 'cut edge' look.
See codepen here or CSS below.
/*div and interior BG*/
div {
width: 80%;
height: 300px; /*Make sure your content has a height specified*/
display: inline-block;
background: linear-gradient(290deg, blue 50%, darkblue 50%);
position: relative;
margin-left: 10%;
}
/*Shared styles across pseudo elements*/
div:before, div:after {
content: '';
width: 20%;
min-height: 300px; /*Fits psuedo element height to content*/
position: absolute;
display:inline-block;
}
/*Position and cuts for left side*/
div:before {
left: -9.9%;
background: linear-gradient(135deg, transparent 15px, darkblue 0) top left,
linear-gradient(45deg, transparent 15px, darkblue 0) bottom left;
background-size: 100% 51%;
background-repeat: no-repeat;
}
/*Position and cuts for left right*/
div:after {
right: -9.9%;
background:
linear-gradient(-135deg, transparent 15px, blue 0) top right,
linear-gradient(-45deg, transparent 15px, blue 0) bottom right;
background-size: 100% 51%;
background-repeat: no-repeat;
}
I made a progress bar which is styled and animated. It is looking good on Opera and Chrome, however I have 2 problems with Firefox and Safari:
The animation effect is not working on Firefox
The progress bar is not appearing at all on Safari
Can anyone help? I write the code below.
Thanks in advance!
Bobby
HTML CODE
<progress value="67" min="0" max="100"></progress>
CSS CODE
progress {
width: 400px;
height: 14px;
/*margin: auto;*/
display: block;
padding: 1px;
appearance:none;
-moz-appearance:none;
-webkit-appearance: none;
border: none;
background-size:auto;
border-radius:15px;
background: -moz-linear-gradient(top, #747467, #515145 49%, #414137 50%, #54544B);
/*background: -ms-linear-gradient(top, #747467, #515145 49%, #414137 50%, #54544B);
background: -o-linear-gradient(top, #747467, #515145 49%, #414137 50%, #54544B);
background: linear-gradient(to bottom, #747467, #515145 49%, #414137 50%, #54544B);*/
/*background-image: none;*/
}
progress::-webkit-progress-bar {
background: -webkit-linear-gradient(top, #747467, #515145 49%, #414137 50%, #54544B);
border-radius: 15px;
padding: 1px;
box-shadow: 0 1px 0px 0 rgba(255, 255, 255, 0.2);
text-align:left;
}
progress::-moz-progress-bar {
background:
-moz-linear-gradient(45deg, transparent, transparent 33%, rgba(0, 0, 0, 0.1) 33%, rgba(0, 0, 0, 0.1) 66%, transparent 66%),
-moz-linear-gradient(top, #70AAE2, #4791DA 49%, #3385D6 50%, #4791DA);
/*-moz-linear-gradient(left, #70AAE2, #4791DA);*/
border-radius: 15px;
box-shadow: 0 1px 0px 0 rgba(255, 255, 255, 0.2);
text-align:left;
background-size: 25px 14px, 100% 100%, 100% 100%;
-moz-animation: move 5s linear 0 infinite;
}
progress::-webkit-progress-value {
border-radius: 15px;
box-shadow: inset 0 1px 1px 0 rgba(255, 255, 255, 0.4);
background:
-webkit-linear-gradient(45deg, transparent, transparent 33%, rgba(0, 0, 0, 0.1) 33%, rgba(0, 0, 0, 0.1) 66%, transparent 66%),
-webkit-linear-gradient(top, #70AAE2, #4791DA 49%, #3385D6 50%, #4791DA);
/*-webkit-linear-gradient(left, #70AAE2, #4791DA);*/
background-size: 25px 14px, 100% 100%, 100% 100%;
-webkit-animation: move 5s linear 0 infinite;
}
#-webkit-keyframes move {
0% {background-position: 0px 0px, 0 0, 0 0}
100% {background-position: -100px 0px, 0 0, 0 0}
}
#-moz-keyframes move {
0% {background-position: 0px 0px, 0 0, 0 0}
100% {background-position: -100px 0px, 0 0, 0 0}
}
Its not exactly an answer but more of a suggestion.
Why dont you use bootstrap? It takes care of everything for you:
Normal Progress Bar:
<div class="progress">
<div class="bar" style="width: 60%;"></div>
</div>
Striped:
<div class="progress progress-striped">
<div class="bar" style="width: 20%;"></div>
</div>
and much more.. Check this: http://getbootstrap.com/2.3.2/components.html#progress
To include bootstrap, do:
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
The HTML <progress> Element is used to view the completion progress of a task. While the specifics of how it's displayed is left up to the browser developer, it's typically displayed as a progress bar but looks differently in every browser. JavaScript can be used to manipulate the value of progress bar.
Chrome: works as you expect it to
Firefox: component implementation is like this way.
Safari: check your browser version
for more detailed info:
http://www.w3schools.com/tags/tag_progress.asp
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress
It probably requires a workaround, or extra elements to achieve, but I'll ask anyway.
I have a simple image. The image is split into two diagonally. The top is a solid color and the bottom is transparent. If I apply the following code, the background color fills in the transparency of the image. Is there a way to position the color or not have it show through where my image area is and instead just fill the remainder of the element?
#content:before {
position: absolute;
z-index: -1;
bottom: -35px;
content: "";
width: 35px;
height: 465px;
left: -35px;
background: #121314 url(library/images/content-fold-left.png) 0 bottom no-repeat;
}
Use CSS3 Gradients:
html, body {
height: 100%;
}
body {
background: -webkit-gradient(linear, 50% 0%, 50% 100, color-stop(100%, rgba(0, 0, 0, 0)), color-stop(100%, #fa8072));
background: -webkit-linear-gradient(top, rgba(0, 0, 0, 0) 100px, #fa8072 100px);
background: -moz-linear-gradient(top, rgba(0, 0, 0, 0) 100px, #fa8072 100px);
background: -o-linear-gradient(top, rgba(0, 0, 0, 0) 100px, #fa8072 100px);
background: linear-gradient(top, rgba(0, 0, 0, 0) 100px, #fa8072 100px);
}
Here is a demo.
You'll notice I used Sass and Compass. The different gradient syntaxes are a nightmare, but with Sass and Compass, all you have to write is:
body
+background(linear-gradient(top, rgba(0,0,0,0) 100px, salmon 100px))
And it will compile all the vendor prefixes and different legacy syntaxes for you.
I'm wondering if I can get a sort of glass-effect border around boxes in CSS. For example, a navigation div that contains a ul etc. Here's an example of what I mean
A glass effect in 2020
When I answered this in 2012, I used only features that were well-supported by browsers at that time. You can find it below for posterity, but first I'll share a slightly more interesting glass effect which looks a bit different from the one in the original question.
I also no longer care so much about an extra element or two, but if you hate presentational elements, check out the old answer to see how you can use a pseudoelement to avoid them.
Full demo
.glass {
backdrop-filter: contrast(130%) brightness(120%) blur(2px);
background:
radial-gradient(
ellipse at 16.7% -10%,
hsla(0, 0%, 100%, 0.44) 24%,
hsla(0, 0%, 100%, 0.4) 25%,
hsla(0, 0%, 100%, 0.2) 45%,
hsla(0, 0%, 100%, 0.1)
);
background-size: 300% 100%;
border-radius: 10px;
box-shadow:
0 2px 1px hsla(0, 0%, 100%, 0.5) inset,
0 -2px 1px hsla(250, 70%, 5%, 0.3) inset,
0 -2px 6px hsla(0, 0%, 100%, 0.25);
}
/* -------------------------------------------
Decorative (not relevant to technique)
------------------------------------------- */
html {
background:
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.15) 30%, rgba(255,255,255,.3) 32.9%, rgba(255,255,255,0) 33%) 0 0,
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.1) 11%, rgba(255,255,255,.3) 13.9%, rgba(255,255,255,0) 14%) 0 0,
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.2) 17%, rgba(255,255,255,.43) 19.9%, rgba(255,255,255,0) 20%) 0 110px,
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.2) 11%, rgba(255,255,255,.4) 13.9%, rgba(255,255,255,0) 14%) -130px -170px,
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.2) 11%, rgba(255,255,255,.4) 13.9%, rgba(255,255,255,0) 14%) 130px 370px,
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.1) 11%, rgba(255,255,255,.2) 13.9%, rgba(255,255,255,0) 14%) 0 0,
linear-gradient(45deg, #343702 0%, #184500 20%, #187546 30%, #006782 40%, #0b1284 50%, #760ea1 60%, #83096e 70%, #840b2a 80%, #b13e12 90%, #e27412 100%);
background-size: 470px 470px, 970px 970px, 410px 410px, 610px 610px, 530px 530px, 730px 730px, 100% 100%;
background-color: #840b2a;
font: 17px/21px Segoe UI, Tahoma, Helvetica, sans-serif;
height: 100%;
idth: 100%;
}
.frame {
padding: 20px;
}
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.content {
background: lemonchiffon;
border: 1px solid sienna;
padding: 20px 25px;
width: 300px;
}
.content > :first-child { margin-top: 0; }
.content > :last-child { margin-bottom: 0; }
c {
background: rgba(255,255,255,.5);
box-shadow: 0 0 3px rgba(0,0,0,.4);
color: #840b2a;
font-family: Consolas, Courier New, Courier, monospace;
font-weight: bold;
padding: 0 3px;
}
<div class="glass frame centered">
<section class="content">
<p>A glass-effect frame using pure CSS.</p>
</section>
</div>
Breaking it down
Backdrop filter
Blurring what lies behind the pane gives the impression that light is being defocused as it passes through the glass. Also, the contrast and brightness are increased to make the background stand out through the surface reflection effect.
backdrop-filter: contrast(130%) brightness(120%) blur(2px);
CSS gradients
This conveys the impression of light reflecting non-uniformly from the surface of the glass. This example uses a radial gradient to imply a light source a finite distance from the pane, but you could also use a linear or conical gradient (less support) to convey a different lighting effect.
The background size is also increased so that the edges of the ellipse do not show.
background:
radial-gradient(
ellipse at 16.7% -10%,
hsla(0,0%,100%,.44) 24%,
hsla(0,0%,100%,.4) 25%,
hsla(0,0%,100%,.2) 45%,
hsla(0,0%,100%,.1)
);
background-size: 300% 100%;
Multiple box shadows
A couple of inset shadows are used to highlight the top edge and shade the other, while an outer shadow implies that light is being cast onto the background around the edges of the box. Changing the position and intensity of these shadows will imply different things about the position of the implied light source.
box-shadow:
0 2px 1px hsla(0,0%,100%,.5) inset, /* Highlight upper edge */
0 -2px 1px hsla(250,70%,5%,.3) inset, /* Shade lower edge */
0 -2px 6px hsla(0,0%,100%,.5); /* Imply light cast around the edges */
A glass effect in 2012 (original answer)
You can achieve an effect very close to this—almost identical to the example in the question—using simpler CSS. This example uses a single element with an RGBA border colour and multiple box shadows to add the highlights and shadows.
.box {
background: #f0edcc;
background-clip: padding-box; /* Background stops at border */
border: 4px solid rgba(255,255,255,.2);
border-radius: 3px;
box-shadow:
0 0 1px rgba(255,255,255,.8), /* Bright outer highlight */
0 0 3px rgba(0,0,0,.8), /* Outer shadow */
1px 1px 0 rgba(0,0,0,.8) inset, /* Inner shadow (top + left) */
-1px -1px 0 rgba(0,0,0,.8) inset; /* Inner shadow (bottom + right) */
padding: 10px;
}
/* -------------------------------------------
Decorative (not relevant to technique)
------------------------------------------- */
html {
background:
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.15) 30%, rgba(255,255,255,.3) 32.9%, rgba(255,255,255,0) 33%) 0 0,
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.1) 11%, rgba(255,255,255,.3) 13.9%, rgba(255,255,255,0) 14%) 0 0,
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.2) 17%, rgba(255,255,255,.43) 19.9%, rgba(255,255,255,0) 20%) 0 110px,
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.2) 11%, rgba(255,255,255,.4) 13.9%, rgba(255,255,255,0) 14%) -130px -170px,
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.2) 11%, rgba(255,255,255,.4) 13.9%, rgba(255,255,255,0) 14%) 130px 370px,
radial-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.1) 11%, rgba(255,255,255,.2) 13.9%, rgba(255,255,255,0) 14%) 0 0,
linear-gradient(45deg, #343702 0%, #184500 20%, #187546 30%, #006782 40%, #0b1284 50%, #760ea1 60%, #83096e 70%, #840b2a 80%, #b13e12 90%, #e27412 100%);
background-size: 470px 470px, 970px 970px, 410px 410px, 610px 610px, 530px 530px, 730px 730px, 100% 100%;
background-color: #840b2a;
font: 13px/17px Segoe UI, Tahoma, Helvetica, sans-serif;
height: 100%;
width: 100%;
}
c {
background: rgba(255,255,255,.5);
box-shadow: 0 0 3px rgba(0,0,0,.4);
color: #840b2a;
font-family: Consolas, Courier New, Courier, monospace;
font-weight: bold;
padding: 0 3px;
}
.box {
bottom:0;
height: 150px;
left:0;
margin:auto;
position:absolute;
top:0;
right:0;
width: 250px;
}
.box > :first-child { margin-top: 0; }
.box > :last-child { margin-bottom: 0; }
<div class="box">Your message.</div>
Note that box-shadow and RGBA border colours are only supported in IE9+ and more recent versions of Firefox, Chrome, Opera and Safari. (Although older versions of the latter browsers may support prefixed versions of the property.) In browsers that don't support either, this degrades to just the inner yellow box.
You can't create a Glass/Blur effect width CSS for now. But width transparent border and box shadow you can attenuate the background.
You can see the result in my jsfiddle : http://jsfiddle.net/DoubleYo/hyETB/1/
Since there is a pattern in the example border, you will probably need one or more PNG background images with alpha channel (so that the parent's background can shine through where and to the extent desired); borders with uniform RGBA colors alone will not suffice here.
Then nest another block element in the element that has that background. With one background image, example HTML:
<div id="glass-box">
<div id="inner">
<p>Text</p>
</div>
</div>
Example CSS:
#glass-box
{
background: transparent url(glass.png) 0 0 no-repeat;
}
#glass-box #inner
{
margin: 10px;
background-color: white;
}
Instead of transparent you might want to try an RGBA color with opacity < 1.0; perhaps you would use a semi-transparent greyscale glass background image which you could project on top of any hue.
Until multiple borders are better supported natively (see my comment), you can achieve multiple borders by nesting block elements and giving each one different borders. Margins on some of those elements will help to reduce the number of elements that need to be nested for the desired effect.
And until CSS Backgrounds and Borders Level 3's multiple background images are better supported (but it is a CR already, so you may be lucky), you can achieve the illusion of multiple background images by using differently positioned (different) background images for nested (positioned) block elements. That way you do not need a box and background image of fixed size.