Montag, 17. März 2014

Fluidity




CSS-Tricks





Fluidity



It's a fun little soundbite to talk about how the web is responsive right out of the box. With no authored CSS at all, a website will flow to whatever screen width is available. If your site isn't responsive, you broke it.


Well that's almost true, but as Adam Morse says in this new project:


HTML is almost 100% responsive out of the box. These 115 bytes of css fix the 'almost' part.


Things like images and tables can have a set widths that would force a layout wider than a viewport. And of course, the meta tag.


And look at that TLD!


Direct Link to ArticlePermalink



Fluidity is a post from CSS-Tricks








Mittwoch, 12. März 2014

Icon System with SVG Sprites




CSS-Tricks





Icon System with SVG Sprites



I've been a big proponent of icon fonts. Lots of sites really need a system for icons, and icon fonts offer a damn fine system. However, I think assuming you're good with IE 9+, using inline SVG and the <use> element to reference an icon is a superior system.


First let's cover how it works.



A nice way to handle your icons is to have a folder full of .svg files.



That's one of the cool things about working with SVG - they are the source files.


They can be colored, not colored, multiple shapes, sizes, whatever.



You can let Illustrator (or whatever) save it however, with all the cruft that comes along for the ride:


<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="100px" height="100px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
<g>
<path d="M50.049,0.3c14.18,0.332,25.969,5.307,35.366,14.923S99.675,36.9,100,51.409c-0.195,11.445-3.415,21.494-9.658,30.146 - yadda yadda yadda"/>
</g>
</svg>

Combine the .svg files


You can manually do this if you want. I've done it. You don't even have to look at the final file. Just call it svg-defs.svg or something.


It should just be an <svg> tag, with a <defs> tag (which just means you are defining stuff to use later), and then a bunch of <g> (group) tags. Each <g> tag will have a unique ID, and will wrap all the paths and whatnot for each icon.


<svg>
<defs>

<g id="shape-icon-1">
<!-- all the paths and shapes and whatnot for this icon -->
<g>

<g id="shape-icon-2">
<!-- all the paths and shapes and whatnot for this icon -->
<g>

<!-- etc -->

</defs>
</svg>

Again you can do that by hand, but of course that's a bit laborious. Fabrice Weinberg has created a Grunt plugin called grunt-svgstore that automates this.


If you've never used Grunt, you can do it. Here's a screencast to get you started.


You can install it with:


npm install grunt-svgstore --save-dev

Make sure the task is available with:


grunt.loadNpmTasks('grunt-svgstore');

And then in the config:


svgstore: {
options: {
prefix : 'shape-', // This will prefix each <g> ID
},
files: {
'processed/svg-defs.svg': ['source/*.svg']
}
},

In the output file, svg-defs.svg, each icon (whatever paths and stuff from the source .svg file) will be wrapped up in a tag with a unique, prefixed ID, and the file name (minus the .svg). Like:


<g id="shape-codepen">

Inject that SVG at the top of the document


Literally include it, like:


<!DOCTYPE html>
<html lang="en">

<head>
...
</head>

<body>
<?php include_once("processed/svg-defs.svg"); ?>

Or however you want to do that.


It's gotta be at the top, sadly, as there is a Chrome bug in which this isn't going to work if defined later.


Use the icons wherever


Now you can use them wherever! Like:


<svg viewBox="0 0 100 100" class="icon shape-codepen">
<use xlink:href="#shape-codepen"></use>
</svg>

Make sure you use those class names on the svg to size it.


/* Do whatever makes sense here.
Just know that the svg will be an
enormous 100% wide if you don't
reign in the width. */
.icon {
display: inline-block;
width: 25px;
height: 25px;
}

Yay: you can style them (and their parts) with CSS


One of the reasons we loved icon fonts is the ability to style them with CSS. This technique one-ups that in that we do everything we could there, and more, because:



  1. We can style all the separate parts

  2. SVG has even more things you can control, like special filters and strokes


The svg is (kinda) in the DOM, so JavaScript too. Here's some styling possibilities and a demo of this all at work:


See the Pen EBHlD by Chris Coyier (@chriscoyier) on CodePen.


Browser Support


On the browser support front, the danger zones are IE 8 and down, Safari 5 and down, iOS 4.3 and down, and Android 2.3 and down. But if your policy is "the last two major versions" - you're looking at pretty much 100% support.


Remember that icons can be used as a supporting role only, like always accompanied by a word. If that's the case, support isn't too big of a deal. If these are stand-alone, and non-display would make the site unusable, that's a big deal.


I probably would go for icon fonts, as the support there is much deeper. Just make sure you do it up right.


This is going to get a lot better


Ideally we'd be able to do this:


<svg viewBox="0 0 100 100" class="icon shape-codepen">
<use xlink:href="http://cdn.css-tricks.com/images/svg-defs.svg#shape-codepen"></use>
</svg>

This does work in some browsers, meaning you could skip the include at the top of the document. Doing it this way means an extra HTTP request, but that means you can utilize caching more efficiently (not bloat document caching). In testing, Jonathan Neal discovered you need to have the xmlns attribute on the <svg> for it to work:


<svg xmlns="http://www.w3.org/2000/svg">

But even then, no support in any IE. Unless you wanted to swap out the whole <svg><use> with an <object>, which does work. Jonathan Neal again figured this out:


/MSIE|Trident/.test(navigator.userAgent) && document.addEventListener('DOMContentLoaded', function () {
[].forEach.call(document.querySelectorAll('svg'), function (svg) {
var use = svg.querySelector('use');

if (use) {
var object = document.createElement('object');
object.data = use.getAttribute('xlink:href');
object.className = svg.getAttribute('class');
svg.parentNode.replaceChild(object, svg);
}
});
});

His demo now also has a method which makes an Ajax request for the contents and injects that, which allows the fills to work in IE 9. Not as efficient, but more like a polyfill.


I imagine someday straight up <svg><use> linking right to the .svg will be the way to go. Or even perhaps <img> working with URL fragment identifiers on the SVG.




Browsers treat <use> like the shadow DOM:



Right now, we can target, say, an individual <path> with CSS, like:


.targetting-a-path {
fill: red;
}

But that will affect all instances of that path. You'd think you could do:


svg.shape-version-2 .targetting-a-path {
fill: red;
}

But that doesn't work. It crosses that shadow DOM boundary. Ideally you'd use the "hat" selector to break that:


svg.shape-version-2 ^ .targetting-a-path {
fill: red;
}

But that's not supported yet either and it's not entirely clear if that's exactly how that will work or not.


"Versus" icon fonts


Vector-based: tie


Style with CSS: slight edge to SVG sprites (targeting parts, SVG specific styling like strokes)


Weird failures: SVG seems to just work (when supported). Icon fonts seem to fail in weird ways. For instance, you map the characters to normal letters, then the font loading fails and you get random characters abound. Or you map to "Private Use Area" and some browsers decide to re-map them to really weird characters like roses, but it's hard to replicate. Or you want to host the @font-face files on a CDN, but that's cross-origin and Firefox hates that, so you need your server to serve the right cross-origin headers, but your Nginx setup isn't picking that up right, SIGH. SVG wins this one.


Semantics: Not a huge deal, but I think an <svg> makes a bit more sense for an image than a <span>.


Accessibility: Maybe someone can tell me? Can we/should we give the <svg> a title attribute or something? Or a <text> element inside that we visually hide? Update: the <title> element might do. Or perhaps the <desc> element as used in this SVG access spec.


Ease of use: Tools like Fontello and IcoMoon are pretty good for an icon font workflow, but the folder-full-of-SVGs with Grunt squishing them together for you is even easier, I think.




Ian Feather posted an article about why they switched away from icon fonts as well and I agree with every single point.





Icon System with SVG Sprites is a post from CSS-Tricks








Dienstag, 11. März 2014

Popping Out of Hidden Overflow




CSS-Tricks





Popping Out of Hidden Overflow



The following is a guest post by Agop Shirinian. Agop ran into an interesting scenario where he needed an element to be scrollable in one direction, while allowing the overflow in the other direction. You'd think that's what overflow-x and overflow-y are for, but it's not that simple. I'll let Agop explain.



So you're tasked with creating a scrollable menu with submenus that pop out when you hover over a parent menu item.


Simple!


Create a list for the menu, add some nested lists for the submenus, position the nested lists based on their parent list items, voilà!


See the Pen Scrollable menu with pop out submenus (broken) by Agop (@agop) on CodePen.


Wait, that's not right. Oh, of course, we used overflow: auto - perhaps if we use overflow-x: visible, the horizontal overflow of the submenus will be visible:


See the Pen Scrollable menu with pop out submenus (broken #2) by Agop (@agop) on CodePen.


What gives? Why do we still get scrollbars?


The Problem


If we look at the W3C spec, we find the following explanation:


The computed values of ‘overflow-x’ and ‘overflow-y’ are the same as their specified values, except that some combinations with ‘visible’ are not possible: if one is specified as ‘visible’ and the other is ‘scroll’ or ‘auto’, then ‘visible’ is set to ‘auto’.


Basically, this:


overflow-x: visible;
overflow-y: auto;

Turns into this:


overflow-x: auto;
overflow-y: auto;

So we can't have visible horizontal overflow if the vertical overflow is invisible, and vice versa.


And if we can't have visible horizontal overflow, we can't have our pop out submenus!


The Solution


Interestingly enough, if we omit the position: relative from the menu items, the submenus do show up, positioned based on their closest positioned ancestor. In this case, they don't have a positioned ancestor, so they're positioned relative to <body>:


See the Pen Scrollable menu with pop out submenus (step 1) by Agop (@agop) on CodePen.


Basically, in order for an absolutely positioned element to appear outside of an element with overflow: hidden, its closest positioned ancestor must also be an ancestor of the element with overflow: hidden.


Knowing this, we can add a wrapper around the menus to act as the closest positioned ancestor for each submenu. Then, whenever the user hovers over a menu item, we can position the submenu wrappers using a bit of JavaScript:


See the Pen Scrollable menu with pop out submenus by Agop (@agop) on CodePen.


And that's it! Since neither the menus nor the menu items are positioned, the submenus are able to pop out of the hidden/scrollable overflow. Now we can have as many levels of nested submenus as we want, and we won't get any undesired clipping.


Takeaway


Unfortunately, this method of showing items that would otherwise be hidden is very obscure.


It'd be nice if we could specify a clip depth, which would control which ancestor in the hiearchy would be responsible for clipping a particular element:


./* Fair warning: not real code */
.submenu {
/* only an ancestor 2 levels up can clip this element */
clip-depth: 2;
}

Or, even better, perhaps we could specify the clipping parent by a CSS selector:


/* Fair warning: not real code */
.submenu {
/* only an ancestor that matches the .panel selector can clip this element */
clip-parent: .panel;
}




Popping Out of Hidden Overflow is a post from CSS-Tricks








Montag, 10. März 2014

Filling the Space in the Last Row with Flexbox




CSS-Tricks





Filling the Space in the Last Row with Flexbox



Chris Albrecht posted a question on StackOverflow about grids. Essentially: imagine you have an element with an unknown number of children. Each of those children is some percentage of the width of parent such that they make equal rows, like 25% wide each for four columns, 33.33% wide each for three columns, etc. The goal is to fill the space of this "grid" evenly. There are an unknown number of children, so let's say you were going with 25% and there were 7 children, that would be 4 in the first row and 3 in the second. Chris needed the final 3 to adjust in width to fill the space, rather than leaving the gap.


Flexbox has just the answer for this, which would otherwise likely need to be a JavaScript intervention.



The solution is essentially making the children able to wrap with flex-wrap, and then filling the space with flex-grow.


.grid {
display: flex;
flex-wrap: wrap;
}

.grid-item {
flex-grow: 1;
min-width: 25%;
}

Here's a visual example of that when each grid item is red and separated with a border:



By adjusting the min-width at different @media query breakpoints, you can make it responsive pretty easily:


.grid-item {
flex-grow: 1;
min-width: 25%;
}
@media (max-width: 1200px) {
.grid-item {
min-width: 33.33%;
}
}


Here's that demo:


See the Pen Wrapping Flexbox with Media Query Widths by Chris Coyier (@chriscoyier) on CodePen.


If you like to balk at flexbox for not being ready to use yet, this example is for you. flex-wrap wasn't in Firefox at all until pretty recently, and isn't even in stable yet, so probably not a super practical solution for Chris just yet. But remember Firefox auto-updates so when 28 rolls out everyone will have it pretty quickly. I'm still optimistic flexbox will be a pretty standard layout mechanism on new sites within a year or so.


If you only need flexbox for single-directional stuff, falling back to display: table is sometimes an option, if by fallback you mean to replicate the layout with some accuracy. If you need the wrapping, inline-block might work. You can test for flexbox wrapping support with:


@supports not (flex-wrap: wrap) {

}

And possibly fall back to inline-block (with no space between them) If you did that, here's how you might adjust that last row if needed with JavaScript:


var leftovers = $(".child").removeAttr("style").length % 4;

if (leftovers > 0) {
var newWidth = 100 / leftovers;
var fromHere = $(".child").length - leftovers + 1;
$(".child:nth-child(n+" + fromHere + ")").css("width", newWidth + "%");
}

Note the hard-coded 4 in there, which assumes 25% children. You could get fancier and detect that. I'll leave that to you. Selecting the last few stragglers (determined by that modulus (%) operator) I did with a bit of an :nth-child recipe. Here's a demo of it though:


See the Pen Wrapping Flexbox with Media Query Widths by Chris Coyier (@chriscoyier) on CodePen.


Remember there is a big ol' guide to all the flexbox properties here.





Filling the Space in the Last Row with Flexbox is a post from CSS-Tricks








Freitag, 7. März 2014

Flexbox Bar Navigation Demo




CSS-Tricks





Flexbox Bar Navigation Demo



Someone wrote in to me asking how to create a simple bar navigation with icons. This is a pretty simple layout thing that could be accomplished loads of different ways. List items as inline-block probably makes the most sense in general.


But I've been enjoying tinkering with flexbox, so I decided to toss it together with that, and it made for a pretty educational example I think.



Here it is:


See the Pen Bar Navigation with Flexbox and SVG icons by Chris Coyier (@chriscoyier) on CodePen.


Flexbox makes it easy to align the items however you want:



Flexbox makes it easy to allow the menu items to take up as much space as they need, without specifying any exact numbers:



But if you want to apply exact numbers, you can:



Flex items can wrap and the properties can change with media queries:



Flex items are easy to align how you want, even vertically, even with centering:



In the demo, feel free to turn on the outlines to see how the boxes align themselves.


I realize not everyone can use flexbox on everything they work on. Yadda yadda browser support, clients, etc. Some people can, on some projects. After playing with it for stuff like this, I think it becomes clear how important it is going to become.





Flexbox Bar Navigation Demo is a post from CSS-Tricks








Donnerstag, 6. März 2014

Thoughts on Media Queries for Elements




CSS-Tricks





Thoughts on Media Queries for Elements



Imagine something like these Transformer Tabs as a widget in a fluid column in a responsive design. Depending on the browser window width, perhaps this design is either 4, 2, or 1 column wide. When it breaks from 4 to 2, the column probably temporarily gets wider than it was, even though the screen is narrower. It would be preferable when writing the media query logic for those tabs to consider how much space the widget has available rather than the entire window, which might be totally unrelated, especially when re-using this widget.


Jonathan Neal has some thoughts on how this might work, including the complicated bits you might not have thought about, like how a widgets contents might affect its parent container and cause an infinite loop.


Direct Link to ArticlePermalink




Thoughts on Media Queries for Elements is a post from CSS-Tricks








Mittwoch, 5. März 2014

CSS Gradients




CSS-Tricks





CSS Gradients



This article was originally published on March 2, 2010. It was updated April 1, 2011, July 20, 2011, and again March 3, 2014, each time to clarify and correct browser prefixes and best practices.

Just as you can declare the background of an element to be a solid color in CSS, you can also declare that background to be a gradient. Using gradients declared in CSS, rather using an actual image file, is better for control and performance.


Gradients are typically one color that fades into another, but in CSS you can control every aspect of how that happens, from the direction to the colors (as many as you want) to where those color changes happen. Let's go through it all.



Gradients are background-image


While declaring the a solid color uses background-color property in CSS, gradients use background-image. This comes in useful in a few ways which we'll get into later. The shorthand background property will know what you mean if you declare one or the other.


.gradient {

/* can be treated like a fallback */
background-color: red;

/* will be "on top", if browser supports it */
background-image: linear-gradient(red, orange);

/* these will reset other properties, like background-position, but it does know what you mean */
background: red;
background: linear-gradient(red, orange);

}

Linear Gradient


Perhaps the most common and useful type of gradient is the linear-gradient(). The gradients "axis" can go from left-to-right, top-to-bottom, or at any angle you chose.


Not declaring an angle will assume top-to-bottom:


.gradient {
background-image:
linear-gradient(
red, #f06d06
);
}

See the Pen BdhbD by Chris Coyier (@chriscoyier) on CodePen.


Those comma-separated colors can type of color you normally use: Hex, named colors, rgba, hsla, etc.


To make it left-to-right, you pass an additional parameter at the beginning of the linear-gradient() function starting with the word "to", indicating the direction, like "to right":


.gradient {
background-image:
linear-gradient(
to right,
red, #f06d06
);
}

See the Pen zFoxn by Chris Coyier (@chriscoyier) on CodePen.


This "to" syntax works for corners as well. For instance if you wanted the axis of the gradient to start at the bottom left corner and go to the top right corner, you could say "to top right":


.gradient {
background-image:
linear-gradient(
to top right,
red, #f06d06
);
}

See the Pen cruJe by Chris Coyier (@chriscoyier) on CodePen.


If that box was square, the angle of that gradient would have been 45°, but since it's not, it isn't. If you wanted to make sure it was 45°, you could declare that:


.gradient {
background-image:
linear-gradient(
45deg,
red, #f06d06
);
}

You aren't limited to just two colors either. In fact you can have as many comma-separated colors as you want. Here's four:


.gradient {
background-image:
linear-gradient(
to right,
red,
#f06d06,
rgb(255, 255, 0),
green
);
}

See the Pen niIjA by Chris Coyier (@chriscoyier) on CodePen.


You can also declare where you want any particular color to "start". Those are called "color-stops". Say you wanted yellow to take up the majority of the space, but red only a little bit in the beginning, you could make the yellow color-stop pretty early:


.gradient {
height: 100px;
background-color: red;
background-image:
linear-gradient(
to right,
red,
yellow 10%
);
}

See the Pen xnqfj by Chris Coyier (@chriscoyier) on CodePen.


We tend to think of gradients as fading colors, but if you have two color stops that are the same, you can make a solid color instantly change to another solid color. This can be useful for declaring a full-height background that simulates columns.


.columns-bg {
background-image:
linear-gradient(
to right,
#fffdc2,
#fffdc2 15%,
#d7f0a2 15%,
#d7f0a2 85%,
#fffdc2 85%
);
}

See the Pen csgoD by Chris Coyier (@chriscoyier) on CodePen.


Browser Support / Prefixes


So far we've only looked at the new syntax, but CSS gradients have been around for quite a while. Browser support is good. Where it gets tricky is syntax and prefixing. There are three different syntaxes that browsers have supported. This isn't what they are officially called, but you can think of it like:



  1. Old: original WebKit-only way, with stuff like from() and color-stop()

  2. Tweener: old angle system, e.g. "left"

  3. New: new angle system, e.g. "to right"


And then prefixing as well.


Let's try a chart:

































Chrome
1-9: Old, prefixed

10-25: Tweener, prefixed

26: New, unprefixed
Safari
3-: No support

4-5.0: Old, prefixed

5.1-6.0: Tweener, prefixed

6.1: New, unprefixed
Firefox
3.5-: No support

3.6-15: Tweener, prefixed

16: New, unprefixed
Opera
11.0-: No support

11.1-11.5: Tweener, prefixed, only linear

11.6-12: Tweener, prefixed, added radial

12.1: Tweener, unprefixed

15: New, unprefixed
IE
8-: No support

9: filters only

10+: New, unprefixed (also supports Tweener w/ prefix)
Android
2.0-: No support

2.1-3.0: Tweener, prefixed

4.0-4.3: New, prefixed

4.4+: New, unprefixed
iOS
3-: No support

3.2-4.3: Tweener, prefixed

5.0-6.1: New, prefixed

7.0: New, unprefixed

There is some overlap in there. For instance when a browser supports the New syntax they probably also support the older syntaxes as well, including the prefix. Best practice is: if it supports New, use New.


So if you wanted to absolute deepest possible browser support, a linear gradient might look like this:


.gradient {

/* Fallback (could use .jpg/.png alternatively) */
background-color: red;

/* SVG fallback for IE 9 (could be data URI, or could use filter) */
background-image: url(fallback-gradient.svg);

/* Safari 4, Chrome 1-9, iOS 3.2-4.3, Android 2.1-3.0 */
background-image:
-webkit-gradient(linear, left top, right top, from(red), to(#f06d06));

/* Safari 5.1, iOS 5.0-6.1, Chrome 10-25, Android 4.0-4.3 */
background-image:
-webkit-linear-gradient(left, red, #f06d06);

/* Firefox 3.6 - 15 */
background-image:
-moz-linear-gradient(left, red, #f06d06);

/* Opera 11.1 - 12 */
background-image:
-o-linear-gradient(left, red, #f06d06);

/* Opera 15+, Chrome 25+, IE 10+, Firefox 16+, Safari 6.1+, iOS 7+, Android 4.4+ */
background-image:
linear-gradient(to right, red, #f06d06);

}

That's an awful lot of code there. Doing it by hand would be error-prone and a lot of work. Autoprefixer does a good job with it, allowing you to trim that amount of code back as you decide what browsers to support.


The Compass mixin can do SVG data URI's for IE 9 if that's important to you.


IE filters


Internet Explorer (IE) 6-9, while they don't support the CSS gradient syntax, do offer a programatic way to do background gradients


/* "Invalid", but works in 6-8 */
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr=#1471da, endColorstr=#1C85FB);

/* Valid, works in 8-9 */
-ms-filter: "progid:DXImageTransform.Microsoft.gradient (GradientType=0, startColorstr=#1471da, endColorstr=#1C85FB)";

There are some considerations here on deciding to use this or not:



  1. filter is generally considered a bad practice for performance,

  2. background-image overrides filter, so if you need to use that for a fallback, filters are out. If a solid color is an acceptable fallback (background-color), filter is a possibility


Even though filters only work with hex values, you can still get alpha transparency by prefacing the hex value with the amount of transparency from 00 (0%) to FF (100%). Example:


rgba(92,47,90,1) == #FF5C2F5A

rgba(92,47,90,0) == #005C2F5A


Radial Gradients


Radial gradient differ from linear in that they start at a single point and emanate outwards. Gradients are often used to simulate a lighting, which as we know isn't always straight, so they can be useful to make a gradient seem even more natural.


The default is for the first color to start in the (center center) of the element and fade to the end color toward the edge of the element. The fade happens at an equal rate no matter which direction.


.gradient {
background-image:
radial-gradient(
yellow,
#f06d06
);
}

See the Pen blcqw by Chris Coyier (@chriscoyier) on CodePen.


You can see how that gradient makes an elliptical shape, since the element is not a square. That is the default (ellipse, as the first parameter), but if we say we want a circle we can force it to be so:


.gradient {
background-image:
radial-gradient(
circle,
yellow,
#f06d06
);
}

Notice the gradient is circular, but only fades all the way to the ending color along the farthest edge. If we needed that circle to be entirely within the element, we could ensure that by specifying we want the fade to end by the "closest-side" as a space-separated value from the shape, like:


.gradient {
background-image:
radial-gradient(
circle closest-side,
yellow,
#f06d06
);
}

See the Pen EFyvp by Chris Coyier (@chriscoyier) on CodePen.


The possible values there are: closest-corner, closest-side, farthest-corner, farthest-side. You can think of it like: "I want this radial gradient to fade from the center point to the __________, and everywhere else fills in to accommodate that."


A radial gradient doesn't have to start at the default center either, you can specify a certain point by using "at ______" as part of the first parameter, like:


.gradient {
background-image:
radial-gradient(
circle at top right,
yellow,
#f06d06
);
}

I'll make it more obvious here by making the example a square and adjusting a color-stop:


See the Pen iuaDL by Chris Coyier (@chriscoyier) on CodePen.


Browser Support


It's largely the same as linear-gradient(), except a very old version of Opera, right when they started supporting gradients, only did linear and not radial.


But similar to linear, radial-gradient() has gone through some syntax changes. There is, again: "Old", "Tweener", and "New".


/* Example of Old */
background-image:
-webkit-gradient(radial, center center, 0, center center, 141, from(black), to(white), color-stop(25%, blue), color-stop(40%, green), color-stop(60%, red), color-stop(80%, purple));

/* Example of Tweener */
background-image:
-webkit-radial-gradient(45px 45px, farthest-corner, #F00 0%, #00F 100%) repeat scroll 0% 0% rgba(0, 0, 0, 0);

/* Example of New */
background-image:
radial-gradient(circle farthest-side at right, #00F, #FFF);

The hallmarks being:



  • Old: Prefixed with -webkit-, stuff like from() and color-stop()

  • Tweener: First param was location of center. That will completely break now in browsers that support new syntax unprefixed, so make sure any tweener syntax is prefixed.

  • New: Verbose first param, like "circle closest-corner at top right"


Again, I'd let Autoprefixer handle this. You write in the newest syntax, it does fallbacks. Radial gradients are more mind-bending than linear, so I'd recommend attempting to just get comfortable with the newest syntax and going with that (and if necessary, forget what you know about older syntaxes).


Repeating Gradients


With ever-so-slightly less browser support are repeating gradients. They come in both linear and radial varieties.


There is a trick, with non-repeating gradients, to create the gradient in such a way that if it was a little tiny rectangle, it would line up with other little tiny rectangle versions of itself to create a repeating pattern. So essentially create that gradient and set the background-size to make that little tiny rectangle. That made it easy to make stripes, which you could then rotate or whatever.


With repeating-linear-gradient(), you don't have to resort to that trickery. The size of the gradient is determined by the final color stop. If that's at 20px, the size of the gradient (which then repeats) is a 20px by 20px square.


.repeat {
background-image:
repeating-linear-gradient(
45deg,
yellow,
yellow 10px,
red 10px,
red 20px /* determines size */
);
}

See the Pen lAkyo by Chris Coyier (@chriscoyier) on CodePen.


Same with radial:


.repeat {
background:
repeating-radial-gradient(
circle at 0 0,
#eee,
#ccc 50px
);
}

See the Pen Repeating Gradients by Chris Coyier (@chriscoyier) on CodePen.


Improper Fallback Loading


As we've covered, some really old browsers don't support any CSS gradient syntax at all. If you need a fallback that is still a gradient, an image (.jpg / .png) could do the trick. The scary part with that is that some slightly-less-old browsers, that were just starting to support CSS gradients, would load the fallback image. As in, make the HTTP request for the image even though it would render the CSS gradient.


Firefox 3.5.8 did this (see screenshot), as well as Chrome 5- and Safari 5.0.1. See:




Safari 5.0.1 loading fallbacks improperly


The good news is this isn't really any issue anymore. The only offending browsers were Chrome and Safari and Chrome hasn't done it since 6 and Safari hasn't done it as of 5.1, going on three years ago.


Additional Resources






CSS Gradients is a post from CSS-Tricks