Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use CSS (and JavaScript?) to create a blurred, "frosted" background?

I'm trying to create an iOS 7 style frosted look with HTML5, CSS3 and JavaScript which can work on webkit browsers.

Technically, given the following HTML:

<style>   #partial-overlay {     width: 100%;     height: 20px;     background: rgba(255, 255, 255, .2); /* TODO frost */     position: fixed;     top: 0;     left: 0;   } </style> <div id="main-view">   <div style="width: 50px; height: 50px; background: #f00"></div>   To my left is a red box<br>   Now there is just text<br>   Text that goes on for a few pixels <br>   or even more </div> <div id="partial-overlay">   Here is some content </div> 

I'd like to apply something like a -webkit-filter: blur(5px) to the first 20px horizontally of #main-view.

If the CSS was modified to be #partial-overlay { width: 20px; height: 100%; ...} then I'd need to apply the -webkit-filter: blur(5px) to the first 20px vertically.

The obvious solution is to use javascript to make a clone of the #main-view, set overflow: hidden and then change the width/height as appropriate but that seems to me hard to generalize to more complex pages/CSS structures.

Is there a better way to achieve this with minimal performance hit and maximal generalizability?

EDIT: Here is an example of what I'm trying to achieve: Mockup

like image 737
Aaron Yodaiken Avatar asked Jun 13 '13 16:06

Aaron Yodaiken


People also ask

How do I blur the background using CSS?

You have to blur the whole element in order to blur the background. So if you want to blur only the background, it has to be its own element. Show activity on this post. The following is a simple solution for modern browsers in pure CSS with a 'before' pseudo element, like the solution from Matthew Wilcoxson.

Can we blur image with CSS?

The blur() CSS function applies a Gaussian blur to the input image. Its result is a <filter-function> .

How do you blur something in CSS?

The first way of creating a blurred text is making your text transparent and applying shadow to it. The shadow will make the text appear blurred. Use a <div> with an id "blur". Then, set the color property to its “transparent” value and define the text-shadow property to give a shadow to the text.


1 Answers

Thanks for the inspiration... It led me to this canvas plugin which does the trick

New and Improved: -webkit- and Firefox Working Example, now re-sizable/fluid.

JS

$(document).ready(function () {     frost = function () {         var w = $('#main-view').width();         html2canvas(document.body, {             onrendered: function (canvas) {                 document.body.appendChild(canvas);                 $('canvas').wrap('<div id="contain" />');             },             width: w,             height: 30         });         $('canvas, #partial-overlay, #cover').hide();         $('#cover').fadeIn('slow', function () {             $('#partial-overlay').fadeIn('slow');         });     };      $('body').append('<div id="cover"></div><svg id="svg-image-blur"><filter id="blur-effect-1"><feGaussianBlur stdDeviation="2"/></filter></svg>');      $('#main-view').click(function () {         frost();         $('#partial-overlay').addClass('vis');         $(window).resize(function () {             $('canvas, #partial-overlay, #cover').hide();         });          function onResize() {             if ($('#partial-overlay').hasClass('vis')) {                 frost();             }         }         var timer;         $(window).bind('resize', function () {             timer && clearTimeout(timer);             timer = setTimeout(onResize, 50);         });      });      $('#partial-overlay').click(function () {         $('#partial-overlay').removeClass('vis');         $('canvas, #partial-overlay, #cover').hide();     }); }); 

CSS

#main-view {     width:75%;     height:50%;     box-sizing: border-box;     margin:8px; } #partial-overlay {     display:none;     width: 100%;     height: 20px;     position: absolute;     top: 0;     left: 0;     z-index:99;     background: rgba(255, 255, 255, 0.2);     cursor:pointer; } canvas {     position: absolute;     top: 0;     left: 0;     -webkit-filter:blur(5px);     filter: url(#blur-effect-1); } #cover {     display:none;     height:19px;     width:100%;     background:#fff;     top:0;     left:0;     position:absolute; } #contain {     height:20px;     width:100%;     overflow:hidden;     position:absolute;     top:0;     left:0; } svg {     height:0;     width:0; } 

HTML

<div id="main-view">     <div style="width: 10%; height: 20%; background: #f00; float: left"></div>To my left is a red box     <br>Now there is just text     <br>Text that goes on for a few pixels     <br>or even more</div> <div id="partial-overlay">Here is some content</div> 

I put it in a click function, because I figured it would be the most likely use case. It will work just as well on document ready.

Although the canvas representation wont be pixel perfect, I don't think it will really matter in most cases because its being blurred.

Update: As requested this is now re-sizable. I also moved the cover div into the JS and added an svg fall back for Firefox. The resizing requires the canvas to be redrawn on each re-size, so I set it up to hide the canvas, overlay, etc while you're resizing and then replace it when the re-size stops.

like image 107
apaul Avatar answered Sep 20 '22 16:09

apaul