CSS browser detection for radial gradient? - css

I'm using a radial gradient as the background for a website. It works great on Safari, Chrome, and Firefox 3.5+, but Opera and Internet Explorer have problems. So, I made a background image to show on those browsers to give the same look. Right now, I'm detecting the browser and version server-side from the user-agent, and then including the correct CSS file. However, I feel like there must be a better way than having to maintain two seperate CSS files to do essentially the same thing (the only difference between the CSS files is html and body).
For good browsers:
html, body {
width: 100%;
height: 100%;
}
html {
background-image: -ms-radial-gradient(center, circle farthest-side, #23395D 0%, #122037 60%, #0A131F 100%);
background-image: -moz-radial-gradient(center, circle farthest-side, #23395D 0%, #122037 60%, #0A131F 100%);
background-image: -o-radial-gradient(center, circle farthest-side, #23395D 0%, #122037 60%, #0A131F 100%);
background-image: -webkit-gradient(radial, center center, 0, center center, 480, color-stop(0, #23395D), color-stop(0.6, #122037), color-stop(1, #0A131F));
background-image: -webkit-radial-gradient(center, circle farthest-side, #23395D 0%, #122037 60%, #0A131F 100%);
background-image: radial-gradient(center, circle farthest-side, #23395D 0%, #122037 60%, #0A131F 100%);
-moz-box-shadow:inset 0 0 100px #080f1a;
-webkit-box-shadow:inset 0 0 100px #080f1a;
box-shadow:inset 0 0 100px #080f1a;
background-attachment: fixed;
}
body {
font-family: arial, sans-serif;
font-size: 14px;
color: #fff;
line-height: 22px;
text-decoration: none;
background: url(/images/portal/checkered_bg.png) repeat;
}
For bad browsers:
html, body {
width: 100%;
height: 100%;
}
body {
font-family: arial, sans-serif;
font-size: 14px;
color: #fff;
line-height: 22px;
text-decoration: none;
background: #09101b url(/images/portal/big_bg.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/images/portal/big_bg.jpg', sizingMethod='scale');
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/images/portal/big_bg.jpg', sizingMethod='scale')";
}

Sounds like a job for Modernizr.
Modernizr is a small JavaScript library that detects the availability of native implementations for next-generation web technologies, i.e. features that stem from the HTML5 and CSS3 specifications. Many of these features are already implemented in at least one major browser (most of them in two or more), and what Modernizr does is, very simply, tell you whether the current browser has this feature natively implemented or not.

When you try to apply css that the browser doesn't recognize, it just reports nothing, so if you do...
//ommiting document ready for brevity
if ($("html").css("background-image").indexOf("radial") < 0) {
$("html").addClass("no-radial")
}
Then you can override the classes in CSS:
.no-radial body {
font-family: arial, sans-serif;
font-size: 14px;
color: #fff;
line-height: 22px;
text-decoration: none;
background: #09101b url(/images/portal/big_bg.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/images/portal/big_bg.jpg', sizingMethod='scale');
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/images/portal/big_bg.jpg', sizingMethod='scale')";
}

Rather then browser detection, use feature detection, a JavaScript plugin such as Modernizr will do the job very neatly.
It adds class names to the root element so you can check for it like in your css.

Modernizr is your friend...

Related

CSS Background Image Linear Gradient showing unwanted border in Chrome

I'm using a background image with linear gradient to create a highlight text effect but it's causing an unwanted bottom border:
.fancy-underline {
text-decoration: none;
background-image: -webkit-gradient(linear,left top, left bottom,from(rgba(255,255,255,.7)),to(rgba(255,255,255,.7))),-webkit-gradient(linear,left top, left bottom,from(#91c678),to(#91c678));
background-image: linear-gradient(rgba(255,255,255,.7),rgba(255,255,255,.7)),linear-gradient(#91c678,#91c678);
background-position: 0 100%;
background-repeat: no-repeat;
background-size: 100% 50%;
}
<p><span class="fancy-underline">here is some fancy underline</span></p>
I can't see anything under the computed styles in the debugger that might cause this so I'm thinking it must be an issue with my linear gradient. Can anyone point me in the right direction?
You can cover more area like below. You make the gradient big enough and you shift it to uncover the top 50% and you will have the same result as you did
.fancy-underline {
text-decoration: none;
background-image: linear-gradient(rgba(255,255,255,.7),rgba(255,255,255,.7)),linear-gradient(#91c678,#91c678);
background-position: 0 -50%;
background-repeat: no-repeat;
background-size: 100% 200%;
}
<p><span class="fancy-underline">here is some fancy underline</span></p>
Related question to understand how it works: Using percentage values with background-position on a linear-gradient
A zoomed version to better see:
.fancy-underline {
text-decoration: none;
font-size:100px;
background-image: linear-gradient(rgba(255, 255, 255, .7), rgba(255, 255, 255, .7)), linear-gradient(#91c678, #91c678);
}
.new {
background-position: 0 -50%;
background-size: 100% 200%;
background-repeat:no-repeat
}
.old {
background-position: 0 100%;
background-size: 100% 50%;
background-repeat:no-repeat
}
<span class="fancy-underline new">new</span>
<span class="fancy-underline old">old</span>

Add background property without overwriting the existing one

I have an issue with CSS.
I have a gradient, with more than one instruction to make it compatible with any browser.
background: no-repeat 20px center url("./img/pc.png"), -webkit-gradient(linear, left top, left bottom, from(#000000), to(#111111));
background: no-repeat 20px center url("./img/pc.png"), -webkit-linear-gradient(top, #000000, #111111);
background: no-repeat 20px center url("./img/pc.png"), -moz-linear-gradient(top, #000000, #111111);
background: no-repeat 20px center url("./img/pc.png"), -ms-linear-gradient(top, #000000, #111111);
background: no-repeat 20px center url("./img/pc.png"), -o-linear-gradient(top, #000000, #111111);
background: no-repeat 20px center url("./img/pc.png"), linear-gradient(to bottom, #000000, #111111);
As you can see, there is also an image for the background. Now, imagine if this image was inline. It would be an enormous waste of space to copy and paste it many times.
Is there a way to do sometning like this:
background: no-repeat 20px center url("./img/pc.png");
background: linear-gradient(to bottom, #000000, #111111);
But without overwriting (and destroying) the first property (image) with the second call (gradient)?
Thanks
If you don't want to repeat yourself use CSS variable:
:root {
--image:url("https://lorempixel.com/400/200/") center/100px no-repeat
}
.box {
height:200px;
background: var(--image), -webkit-gradient(linear, left top, left bottom, from(#000000), to(#111111));
background: var(--image), -webkit-linear-gradient(top, #000000, #111111);
background: var(--image), -moz-linear-gradient(top, #000000, #111111);
background: var(--image), -ms-linear-gradient(top, #000000, #111111);
background: var(--image), -o-linear-gradient(top, #000000, #111111);
background: var(--image), linear-gradient(to bottom, #000000, #111111);
}
<div class="box">
</div>
<div class="box" style="--image:url(https://lorempixel.com/400/400/) center/100px no-repeat ">
</div>
Use an :after psuedo-element to add the gradient on top the image background.
html,
body {
margin: 0;
padding: 0;
height: 100%;
}
div {
width: 100%;
height: 100%;
background: no-repeat center center url(http://via.placeholder.com/350x150);
position: relative;
}
div:after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to bottom, transparent, #111111);
}
<div></div>
Both linear-gradient and url affect the background-image, so no, you cannot use those two in conjunction; the second one would overwrite the first.
When you combine these two rules in the following shorthand order:
background: no-repeat 20px center url("./img/pc.png");
background: linear-gradient(to bottom, #000000, #111111);
Only the background-image of the second rule gets applied; the other rules from the first shorthand rule get ignored:
background-image: linear-gradient(rgb(0, 0, 0), rgb(17, 17, 17));
background-position-x: initial;
background-position-y: initial;
background-repeat-x: initial;
background-repeat-y: initial;
However, you can cause these additional rules to apply by specifying the gradient as the background-image manually:
background-image: url(./img/pc.png); /* Only rule to get overriden */
background-image: linear-gradient(rgb(0, 0, 0), rgb(17, 17, 17));
background-position-x: 20px;
background-position-y: center;
background-repeat-x: no-repeat;
background-repeat-y: no-repeat;
This way your background-position-x, background-position-y, background-repeat-x and background-repeat-y rules can be applied in conjunction with your gradient... though it is impossible to have both of your background-url rules apply to the same element at the same time.
To have both the image and the gradient show up, I would recommend making use of two elements positioned on top of each other with position: absolute, and applying one background-image to each. The gradient would go on top, and be transparent so that the background image can be seen.
This can be seen in the following:
div {
width: 100px;
height: 100px;
position: absolute;
}
.background {
background-image: url("http://placehold.it/100");
}
.gradient {
background-image: linear-gradient(to bottom, transparent, #111111);
}
<div class="background"></div>
<div class="gradient"></div>

Why is Sass turning a perfectly valid radial-gradient into an invalid one?

I've got a semi-circular radial-gradient working here: http://codepen.io/Inlesco/pen/bpgbKN?editors=1100
Gradient styles:
.el:after {
content: '\00a0';
background: radial-gradient(at 50% 0%, red 0%, rgba(0,0,0,0.2) 0%, transparent 70%);
background-size: 100% 30px;
background-repeat: no-repeat;
float:left;
width:100%;
}
The pen uses CSS. However, if you set a CSS preprocessor (LESS/SASS), no gradient is created as, fe., Chrome marks it as invalid (seen when inspecting).
And if I place the same code (HTML / CSS from CodePen) to a local file (CSS in body <style>), no gradient is created either.
How come it works in web code editors like CodePen, but only without any CSS preprocessors? Is the output of them somehow different for radial-gradient?
When compiled with Sass (SCSS), I get the following result:
.el:after {
content: '\00a0';
background: radial-gradient(at 50% 0% at 50% 0%, #ff0000 0%, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0) 70%);
background-size: 100% 30px;
background-repeat: no-repeat;
float: left;
width: 100%;
}
Sites like Codepen and Sassmeister don't compile with Sass, they compile with Compass (which is Sass with a bunch of extra stuff added to it).
Compass provides a function called radial-gradient (along with linear-gradient) that does a bunch of fancy stuff underneath the hood when combined with the background and background-image mixins to generate prefixes and inline SVGs for you.
Certain versions of Compass have a bug where they'll generate an invalid radial-gradient when you omit the optional shape argument. You just need to add it:
.el:after {
content: '\00a0';
background: radial-gradient(ellipse at 50% 0%, #ff0000 0%, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0) 70%);
// ^ added `ellipse` here
background-size: 100% 30px;
background-repeat: no-repeat;
float: left;
width: 100%;
}
See: https://github.com/Compass/compass/issues/1937
Maybe you are declaring the LESS syntax in an incorrect manner. Try this,
.el {
margin: 0 auto;
width: 6em;
text-align:center;
font-size:30px;
&::after {
content: '\00a0';
background: radial-gradient(at 50% 0%, red 0%, rgba(0,0,0,0.2) 0%, transparent 70%);
background-size: 100% 30px;
background-repeat: no-repeat;
float:left;
width:100%;
}
}

CSS Gradient on Android

I'm trying to make this gradient to work on Android but I don't know the right css option.
HTML:
<div class="bottom-logo">
<div id="logo" class="logo-menu-green">blaa</div>
</div>
Css:
#logo{
font-family: "Lato", "Open Sans";
font-weight: bold;
position: absolute;
z-index: 999;
background: #6699cc;
background: -moz-linear-gradient(left, #6699cc 0%, #3399cc 20%, #009999 37%, #009966 52%, #999999 68%, #9933cc 73%, #990099 90%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%,#6699cc), color-stop(20%,#3399cc), color-stop(37%,#009999), color-stop(52%,#009966), color-stop(68%,#999999), color-stop(73%,#9933cc), color-stop(90%,#990099));
background: -webkit-linear-gradient(left, #6699cc 0%,#3399cc 20%,#009999 37%,#009966 52%,#999999 68%,#9933cc 73%,#990099 90%);
background: -o-linear-gradient(left, #6699cc 0%,#3399cc 20%,#009999 37%,#009966 52%,#999999 68%,#9933cc 73%,#990099 90%);
background: -ms-linear-gradient(left, #6699cc 0%,#3399cc 20%,#009999 37%,#009966 52%,#999999 68%,#9933cc 73%,#990099 90%);
background: linear-gradient(to right, #6699cc 0%,#3399cc 20%,#009999 37%,#009966 52%,#999999 68%,#9933cc 73%,#990099 90%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#6699cc', endColorstr='#990099',GradientType=1 );
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
I tried but it doesn't work. Thank you.
EDIT:
A solution would be to use SVG filters.
Only solution i can think of after my fair share of issues with Android.
Replicate the gradient into a graphical tile, and merely change the following.
Took your code and imported it here.
Visual file
CSS
#logo{
font-family: "Lato", "Open Sans";
font-weight: bold;
position: absolute;
z-index: 999;
background-image: url(img/thegradient.jpg);
background-repeat: no-repeat;
}
Also the gradient didn't even appear until i removed these two lines
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
If this is not what you were looking for i recommend using the javascript method introduced in the comments on your post.
Best of luck.

CSS3 gradient background set on body doesn't stretch but instead repeats?

ok say the content inside the <body> totals 300px high.
If I set the background of my <body> using -webkit-gradient or -moz-linear-gradient
Then I maximize my window (or just make it taller than 300px) the gradient will be exactly 300px tall (the height of the content) and just repeat to fill the rest of the window.
I am assuming this is not a bug since it is the same in both webkit and gecko.
But is there a way to make the gradient stretch to fill the window instead of repeat?
Apply the following CSS:
html {
height: 100%;
}
body {
height: 100%;
margin: 0;
background-repeat: no-repeat;
background-attachment: fixed;
}
Edit: Added margin: 0; to body declaration per comments (Martin).
Edit: Added background-attachment: fixed; to body declaration per comments (Johe Green).
Regarding a previous answer, setting html and body to height: 100% doesn't seem to work if the content needs to scroll. Adding fixed to the background seems to fix that - no need for height: 100%;
E.g.:
body {
background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#cbccc8)) fixed;
}
I know I'm late to the party, but here's a more solid answer.
All you need to do is use min-height: 100%; rather than height: 100%; and your gradient background will extend the entire height of the content without repeating, even if the content is scrollable.
Like this:
html {
min-height: 100%;
}
body {
background: linear-gradient(#b5e48c, #457b9d);
}
There's a second solution though.
As others have said, adding the value fixed to the background declaration, will make the gradient extend the full height of the viewport.
Like this:
body {
background: linear-gradient(#b5e48c, #457b9d) fixed;
}
Granted, you still need to declare min-height: 100%; in the html.
Here's a demo in CodePen where you can play with both solutions: https://codepen.io/ricardozea/pen/abwGBmz?editors=1100
Here's what I did to solve this problem... it will show the gradient for the full length of the content, then simply fallback to the background color (normally the last color in the gradient).
html {
background: #cbccc8;
}
body {
background-repeat: no-repeat;
background: #cbccc8;
background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#cbccc8));
background: -moz-linear-gradient(top, #fff, #cbccc8);
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#cbccc8');
}
<body>
<h1>Hello world!</h1>
</body>
I've tested this in FireFox 3.6, Safari 4, and Chrome, I keep the background-color in the body for any browsers that for some reason don't support styling the HTML tag.
Setting html { height: 100%} can wreak havoc with IE. Here's an example (png). But you know what works great? Just set your background on the <html> tag.
html {
-moz-linear-gradient(top, #fff, #000);
/* etc. */
}
Background extends to the bottom and no weird scrolling behavior occurs. You can skip all of the other fixes. And this is broadly supported. I haven't found a browser that doesn't let you apply a background to the html tag. It's perfectly valid CSS and has been for a while. :)
There is a lot of partial information on this page, but not a complete one. Here is what I do:
Create a gradient here: http://www.colorzilla.com/gradient-editor/
Set gradient on HTML instead of BODY.
Fix the background on HTML with "background-attachment: fixed;"
Turn off the top and bottom margins on BODY
(optional) I usually create a <DIV id='container'> that I put all of my content in
Here is an example:
html {
background: #a9e4f7; /* Old browsers */
background: -moz-linear-gradient(-45deg, #a9e4f7 0%, #0fb4e7 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%,#a9e4f7), color-stop(100%,#0fb4e7)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(-45deg, #a9e4f7 0%,#0fb4e7 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(-45deg, #a9e4f7 0%,#0fb4e7 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(-45deg, #a9e4f7 0%,#0fb4e7 100%); /* IE10+ */
background: linear-gradient(135deg, #a9e4f7 0%,#0fb4e7 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a9e4f7', endColorstr='#0fb4e7',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
background-attachment: fixed;
}
body {
margin-top: 0px;
margin-bottom: 0px;
}
/* OPTIONAL: div to store content. Many of these attributes should be changed to suit your needs */
#container
{
width: 800px;
margin: auto;
background-color: white;
border: 1px solid gray;
border-top: none;
border-bottom: none;
box-shadow: 3px 0px 20px #333;
padding: 10px;
}
This has been tested with IE, Chrome, and Firefox on pages of various sizes and scrolling needs.
Adding a space and the word fixed to the end should be sufficient. No need to set heights.
body{
background: linear-gradient(#e4efe9,#93a5cf) fixed;
}
Dirty; maybe could you just add a min-height: 100%; to the html, and body tags? That or at least set a default background color that is the end gradient color as well.
I had trouble getting the answers in here to work.
I found it worked better to fix a full-size div in the body, give it a negative z-index, and attach the gradient to it.
<style>
.fixed-background {
position:fixed;
margin-left: auto;
margin-right: auto;
top: 0;
width: 100%;
height: 100%;
z-index: -1000;
background-position: top center;
background-size: cover;
background-repeat: no-repeat;
}
.blue-gradient-bg {
background: #134659; /* For browsers that do not support gradients */
background: -webkit-linear-gradient(top, #134659 , #2b7692); /* For Safari 5.1 to 6.0 */
background: -o-linear-gradient(bottom, #134659, #2b7692); /* For Opera 11.1 to 12.0 */
background: -moz-linear-gradient(top, #134659, #2b7692); /* For Firefox 3.6 to 15 */
background: linear-gradient(to bottom, #134659 , #2b7692); /* Standard syntax */
}
body{
margin: 0;
}
</style>
<body >
<div class="fixed-background blue-gradient-bg"></div>
</body>
Here's a full sample
https://gist.github.com/morefromalan/8a4f6db5ce43b5240a6ddab611afdc55
I have used this CSS code and it worked for me:
html {
height: 100%;
}
body {
background: #f6cb4a; /* Old browsers */
background: -moz-linear-gradient(top, #f2b600 0%, #f6cb4a 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f2b600), color-stop(100%,#f6cb4a)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #f2b600 0%,#f6cb4a 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #f2b600 0%,#f6cb4a 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #f2b600 0%,#f6cb4a 100%); /* IE10+ */
background: linear-gradient(top, #f2b600 0%,#f6cb4a 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2b600', endColorstr='#f6cb4a',GradientType=0 ); /* IE6-9 */
height: 100%;
background-repeat: no-repeat;
background-attachment: fixed;
width: 100%;
background-position: 0px 0px;
}
A related information is that you can create your own great gradients at http://www.colorzilla.com/gradient-editor/
/Sten
background: #13486d; /* for non-css3 browsers */
background-image: -webkit-gradient(linear, left top, left bottom, from(#9dc3c3), to(#13486d)); background: -moz-linear-gradient(top, #9dc3c3, #13486d);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#9dc3c3', endColorstr='#13486d');
background-repeat:no-repeat;
this is what I did:
html, body {
height:100%;
background: #014298 ;
}
body {
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#5c9cf2), color-stop(100%,#014298));
background: -moz-linear-gradient(top, rgba(92,156,242,1) 0%, rgba(1,66,152,1) 100%);
background: -o-linear-gradient(top, #5c9cf2 0%,#014298 100%);
/*I added these codes*/
margin:0;
float:left;
position:relative;
width:100%;
}
before I floated the body, there was a gap on top, and it was showing the background color of html. if I remove the bgcolor of html, when I scroll down, the gradient is cut. so I floated the body and set it's position to relative and the width to 100%. it worked on safari, chrome, firefox, opera, internet expl.. oh wait. :P
what do you guys think?
instead of 100% i just add some pixxel got this now and it works for whole page without gap:
html {
height: 1420px; }
body {
height: 1400px;
margin: 0;
background-repeat: no-repeat; }

Resources