神刀安全网

Textured Gradients in Pure CSS

We’re going to create a background like this in pure CSS:

Textured Gradients in Pure CSS

Of course, the simple version would be to simply create a CSS gradient (and there are tools that make creating them easy):

Textured Gradients in Pure CSS

But it just doesn’t look that great, simply because we can only create linear or radial gradients. We want more randomness, something that looks less geometric and predictable.

A common method is to choose a real-life photo and blur it. TinEye offers a free online tool that lets us search for CC Flickr images based on the colours they contain. I added some colours to my search and ended up choosing this picture by Flickr user “ whatapar ” (under the CC 2.0 license):

Textured Gradients in Pure CSS

We don’t need most of the information in this photo so let’s scale it down to a mere 8×6 pixels:

Textured Gradients in Pure CSS

TinyPNG turns this image into 326 bytes and we can use a simple online tool to turn it into a data URI so we can include it directly in our CSS:

body {     background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAGCAMAAADJ2y/JAAAAilBMVEWVsF28hjlmaLKik6tscKNqZKOZr51fZ5Rxc5GjuI9WTYJnaIBsfXBVb26IpWKMlFdlglVndlV1hlRna1Rue1E5SlH/q0uJc0rimEhxdkBXbj/LhDtahzqjgjpcczp9nTnvmzlZWTNYZS85ailmUChLXSYpdSICOSEYIiFMaB4yURAmHApOSgAVDwB+JAIrAAAALnRSTlP+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+iNdOOwAAAD1JREFUCNcFwYMBADEABLDr27ZZd//1moDJ0ItSp8e31H4QJxyTyNwC2mAnbX7iVriGmR5N+YCs4/ZW3W8BZWUEDXOg7OsAAAAASUVORK5CYII=");     background-repeat: no-repeat;     background-size: cover; } 

It would be great if that was all there’s to it. And indeed, in Chrome, it looks quite nice:

Textured Gradients in Pure CSS

But Firefox does not blur the scaled up image, at least not much:

Textured Gradients in Pure CSS

One could add a separate <div> element for the background and apply a filter: blur(10px) to it. But I’m a bit of a purist and adding extra div’s to achieve a purely visual effect is something I try to avoid.

Most modern browsers today support SVG files and the SVG specification includes a Gaussian blur filter (which, in fact, looks even better than the primitive interpolation by Chrome seen above). Let’s create an SVG file with our 8×6 image:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink" viewBox="1 1 6 4">   <image filter="url(#b)" width="8" height="6" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAGCAMAAADJ2y/JAAAAilBMVEWVsF28hjlmaLKik6tscKNqZKOZr51fZ5Rxc5GjuI9WTYJnaIBsfXBVb26IpWKMlFdlglVndlV1hlRna1Rue1E5SlH/q0uJc0rimEhxdkBXbj/LhDtahzqjgjpcczp9nTnvmzlZWTNYZS85ailmUChLXSYpdSICOSEYIiFMaB4yURAmHApOSgAVDwB+JAIrAAAALnRSTlP+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+iNdOOwAAAD1JREFUCNcFwYMBADEABLDr27ZZd//1moDJ0ItSp8e31H4QJxyTyNwC2mAnbX7iVriGmR5N+YCs4/ZW3W8BZWUEDXOg7OsAAAAASUVORK5CYII="/>   <filter id="b"><feGaussianBlur stdDeviation=".5" /></filter> </svg> 

This is what it looks like:

Textured Gradients in Pure CSS

You may have noticed the viewBox="1 1 6 4" which crops the SVG’s area by one pixel on each side. This is because the Gaussian filter assumes that everything outside the image is white and therefore introduces a white haze at the borders. Cropping the borders somewhat makes it disappear.

Now we turn this SVG file into a data URI once more and include it in our CSS:

body {   background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSAiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmlld0JveD0iMSAxIDYgNCI+PGltYWdlIGZpbHRlcj0idXJsKCNiKSIgd2lkdGg9IjgiIGhlaWdodD0iNiIgeGxpbms6aHJlZj0iZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFBZ0FBQUFHQ0FNQUFBREoyeS9KQUFBQWlsQk1WRVdWc0YyOGhqbG1hTEtpazZ0c2NLTnFaS09acjUxZlo1UnhjNUdqdUk5V1RZSm5hSUJzZlhCVmIyNklwV0tNbEZkbGdsVm5kbFYxaGxSbmExUnVlMUU1U2xIL3EwdUpjMHJpbUVoeGRrQlhiai9MaER0YWh6cWpnanBjY3pwOW5UbnZtemxaV1ROWVpTODVhaWxtVUNoTFhTWXBkU0lDT1NFWUlpRk1hQjR5VVJBbUhBcE9TZ0FWRHdCK0pBSXJBQUFBTG5SU1RsUCsvdjcrL3Y3Ky92NysvdjcrL3Y3Ky92NysvdjcrL3Y3Ky92NysvdjcrL3Y3Ky92NysvdjcrL3Y3Ky92NytpTmRPT3dBQUFEMUpSRUZVQ05jRndZTUJBREVBQkxEcjI3WlpkLy8xbW9ESjBJdFNwOGUzMUg0UUp4eVR5TndDMm1BbmJYN2lWcmlHbVI1TitZQ3M0L1pXM1c4QlpXVUVEWE9nN09zQUFBQUFTVVZPUks1Q1lJST0iLz48ZmlsdGVyIGlkPSJiIj48ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIuNSIgLz48L2ZpbHRlcj48L3N2Zz4=");   background-repeat: no-repeat;   background-size: cover; } 

Looks good, even in Firefox:

Textured Gradients in Pure CSS

One thing I like to do is give the background a bit of a texture. Again, using SVG here (although a PNG may work well here, too):

<svg width="3" height="3" viewBox="0 0 3 3"   xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">   <rect x="0" y="0" width="1" height="1" style="fill:rgba(0,0,0,.2)"/> </svg> 

It’s a one black, slightly transparent bit pixel at (1,1) . Once more, we data-URI it and repeat it over the gradient:

html {   background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSAiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmlld0JveD0iMSAxIDYgNCI+PGltYWdlIGZpbHRlcj0idXJsKCNiKSIgd2lkdGg9IjgiIGhlaWdodD0iNiIgeGxpbms6aHJlZj0iZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFBZ0FBQUFHQ0FNQUFBREoyeS9KQUFBQWlsQk1WRVdWc0YyOGhqbG1hTEtpazZ0c2NLTnFaS09acjUxZlo1UnhjNUdqdUk5V1RZSm5hSUJzZlhCVmIyNklwV0tNbEZkbGdsVm5kbFYxaGxSbmExUnVlMUU1U2xIL3EwdUpjMHJpbUVoeGRrQlhiai9MaER0YWh6cWpnanBjY3pwOW5UbnZtemxaV1ROWVpTODVhaWxtVUNoTFhTWXBkU0lDT1NFWUlpRk1hQjR5VVJBbUhBcE9TZ0FWRHdCK0pBSXJBQUFBTG5SU1RsUCsvdjcrL3Y3Ky92NysvdjcrL3Y3Ky92NysvdjcrL3Y3Ky92NysvdjcrL3Y3Ky92NysvdjcrL3Y3Ky92NytpTmRPT3dBQUFEMUpSRUZVQ05jRndZTUJBREVBQkxEcjI3WlpkLy8xbW9ESjBJdFNwOGUzMUg0UUp4eVR5TndDMm1BbmJYN2lWcmlHbVI1TitZQ3M0L1pXM1c4QlpXVUVEWE9nN09zQUFBQUFTVVZPUks1Q1lJST0iLz48ZmlsdGVyIGlkPSJiIj48ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIuNSIgLz48L2ZpbHRlcj48L3N2Zz4=");   background-repeat: no-repeat;   background-size: cover; }  body {   background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMyIgaGVpZ2h0PSIzIiB2aWV3Qm94PSIwIDAgMyAzIg0KICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBzdHlsZT0iZmlsbDpyZ2JhKDAsMCwwLC4yKSIvPjwvc3ZnPg==");   margin: 0; } 

Here we have the final product, achieved with 1,440 bytes of CSS (uncompressed):

Textured Gradients in Pure CSS

To see the texture better, here’s an original scale screenshot:

Textured Gradients in Pure CSS

I noticed that some browsers seem to take quite some time rendering the gradient. I assume it’s because scaling the SVG up to page size also increases the size of the Gaussian filter. So at the moment, likely until we have more GPU-based rendering of websites, there is a tradeoff to make: This solution minimizes network traffic but page render times are somewhat slow. To speed up the page render time, it’s probably better to load a gradient image.

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Textured Gradients in Pure CSS

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
分享按钮