Placed in: Home arrow Programming arrow Webdesign arrow Pure CSS3 bokeh effect with some jQuery help
Pure CSS3 bokeh effect with some jQuery help

Bokeh - In photography, bokeh is the blur, or the aesthetic quality of the blur, in out-of-focus areas of an image, or "the way the lens renders out-of-focus points of light." (from Wikipedia). I'm pretty sure you've seen this effect before, since there are loads of wallpaper roundups and tutorials using this technique. Currently, one of my favourite wallpapers has to be this bokeh effect from -kol.

Today, I want to add another addition to the bokeh "hype", by creating a pure CSS3 bokeh effect. With some help from jQuery, we can add some randomness in colour, size and position for the effect.

Pure CSS3 bokeh effect

Still don't know what we'll be creating? Make sure to check out the demo and view the source code to learn some more.

Demo Pure CSS3 bokeh effect   Download Pure CSS3 bokeh effect

IMPORTANT NOTE:
Sadly, CSS3 and HTML5 aren't the standards (yet) these days (when will it ever be?). Since this demo is using CSS3, not all modern browsers will be able to show off the full effect. Because of this, it only works on Apples Safari and Google Chrome and the latest version of Firefox. So, for now, this is just for fun - until Microsoft comes with a CSS3 supporting Internet Explorer.

The effect looks pretty neat, doesn't it? Check out this tutorial on how you can create it yourself! For those people who use IE, I've added a little video showing the full effect.

Video: Pure CSS3 bokeh effect

This is a small video I created to show the effect to user who don't have (the latest version of) Firefox, Chrome or Safari.

If you are using a modern browser, you could check out the demo page and play with it yourself. Now let's see how to create this kind of effect.

Step 1: HTML + Basic CSS.

First, the easy steps. Since we're creating two kind of bokehs, we'll work with two HTML elements; One that will hold the plain bokeh, the other one will be the gradient bokeh.

 
<div class="bokeh" id="plain"></div>
<div class="bokeh" id="gradient"></div>

Now, we'll need to apply some CSS to the bokeh class that we can re-use on both bokehs.

 
.bokeh { width:100px; height:100px; background-color:white;
   -moz-border-radius:50px; -webkit-border-radius:50px; border: 1px solid orange; }

The border radius is 50% of the width/height of the element, making the element a full circle. This is what we got so far:

Pure CSS3 bokeh effect - 01

This is something we can work with to create the bokeh effect. Take note the orange border is added in this example; We'll need to change that later on. Let's move on to the next step!

Plain bokeh

Let's focus on the simple version of the bokeh first - the plain one. We'll be using the CSS3 rgba property for this one (just like we used it on the sweet tabbed navigation). It allows us to set the colour in RGB, and the last parameter will be the opacity (I've removed the background-color and border properties from the previous code).

 
#plain {
   border: 1px solid rgba(240, 60, 60, 0.7); background-color: rgba(240, 60, 60, 0.3);
}

Now, we've created a see-through circle with a see-through border that we can use as our bokeh!

Pure CSS3 bokeh effect - 02

Now, we need to create multiple bokehs and place them on top of each other to improve the effect.

More plain bokehs

Since we want to add more bokehs, let's make some changes to the HTML (I've removed the gradient one temporarily).

 
<div class="bokeh" id="plain1"></div>
<div class="bokeh" id="plain2"></div>
<div class="bokeh" id="plain3"></div>
<div class="bokeh" id="plain4"></div>
<div class="bokeh" id="plain5"></div>

Since we need to elements on top of other elements, we'll need to use absolute positioning. We'll also add another colour, just to see the effect better. Check out the following CSS:

 
.bokeh { width:100px; height:100px; position: absolute;
   -moz-border-radius:50px; -webkit-border-radius:50px; }
   
#plain1 {
   border: 1px solid rgba(240, 60, 60, 0.7); background-color: rgba(240, 60, 60, 0.3);
   top:50px; left:50px;
}
#plain2 {
   border: 1px solid rgba(250, 250, 0, 0.7); background-color: rgba(250, 250, 0, 0.3);
   top:77px; left:34px;
}
#plain3 {
   border: 1px solid rgba(240, 60, 60, 0.7); background-color: rgba(240, 60, 60, 0.3);
   top:150px; left:80px;
}
#plain4 {
   border: 1px solid rgba(240, 60, 60, 0.7); background-color: rgba(240, 60, 60, 0.3);
   top:120px; left:200px;
}
#plain5 {
   border: 1px solid rgba(250, 250, 0, 0.7); background-color: rgba(250, 250, 0, 0.3);
   top:80px; left:140px;
}

This will give us the following result:

Pure CSS3 bokeh effect - 03

Looks pretty neat, doesn't it? Using only this, we could fill up an entire page with several bokeh circles!

The gradient bokeh

CSS3 also allows us to create gradients (in Firefox supported by v3.6). Let's use this fact for our advantage and create a gradient bokeh. Consider the following CSS:

 
#gradient {
   border : 1px solid rgba(240, 60, 60, 0.7);
   background: -moz-radial-gradient( rgba(240, 60, 60, 0.1), rgba(240, 60, 60, 0.4));
}

The -moz-radial-gradient allows us to set a from and a to colour. By once again using some RGBA, we can create the see-through effect here too. This piece of code will result in the following effect:

Pure CSS3 bokeh effect - 04

But there is just one catch here: This code now only works in Firefox (because of the -moz prefix). We can't simply add another background property (supporting the -webkit prefix), since the other one will be overwritten. How can we make this work in Safari/Chrome too?

I found a nifty little workaround to make this work in -webkit browsers too. Simply apply the correct gradient syntax (which is different in webkit than the moz) to the background-image property and you're ready to go.

So, when using the following code, we can make gradients work on both Firefox and webkit browsers:

 
#gradient {
   border : 1px solid rgba(240, 60, 60, 0.7);
   background: -moz-radial-gradient( rgba(240, 60, 60, 0.1), rgba(240, 60, 60, 0.4));
   background-image: -webkit-gradient(radial, center center, 0, center center, 70.5, from(rgba(240, 60, 60, 0.1)), to(rgba(240, 60, 60, 0.4)));
}

Using the same technique as with the plain bokehs, we can change the colour and place them on top of each other. Your result may look like this:

Pure CSS3 bokeh effect - 05

Of course, you can play with the bokeh size too. But there we have it already; a full bokeh effect using pure CSS and HTML! Now let's do some jQuery to add some more spice to this example, by adding randomness in colour, size and position.

jQuery - Preperations

Of course, we could type our whole HTML and specify a different CSS class to each bokeh element to create a true bokeh effect. But it would be way more fun to create a random effect! In this stage, we'll take a look at how we can create random colours, size and place the bokeh on a random position.

For the random size and random colour, I used two function from several websites. You might want to take a look at them to see how they work, since we'll call them from our own function later.

 
// Function to get a random value between two values
function randomXToY(minVal,maxVal,floatVal) {
  var randVal = minVal+(Math.random()*(maxVal-minVal));
  return typeof floatVal=='undefined'?Math.round(randVal):randVal.toFixed(floatVal);
}
 
// Function to generate a random colour in RGB
function randomColour() {
  var rint = Math.round(0xffffff * Math.random());
  return (rint >> 16) + ',' + (rint >> 8 & 255) + ',' + (rint & 255);
}

We need the first function (by roshanbh.com) to generate a random bokeh size between two values (min and max size). The second function (by develobert) is used to create a random rgb colour.

HTML and CSS reset

We'll need a quick reset for our HTML and CSS, since we're generating the CSS dynamically and modifying the DOM using jQuery. We'll work with the following HTML:

 
<div id="bokehs">
   <!-- Bokeh will get injected dynamically using jQuery -->
</div>

Combined with the following CSS, we're ready to go:

 
.bokeh { position:absolute; z-index:-1; }

We're placing each .bokeh element in a z-index of -1, to keep the title and options screen on top. All other properties that we learned in our previous steps (where we learned how to create the actual bokeh using pure CSS) will be generated by jQuery.

jQuery

This is the jQuery script I came up which will be executed on load. It generates all the randomness you'll need to achieve the effect. I've added comments in the source code, so you'll understand what it's doing.

 
// Master function that paints all the bokeh effects
function repaint() {
   
   // Variables to generate the bokehs
   var numberOfBokehs = 100;
   var bokehMinSize = 50;
   var bokehMaxSize = 150;
   var orbColour = '10, 30, 70'; // Dark blue if no random colours are used
   var useRandomColours = true;
   var useGradients = false;
   
   // Generate the bokeh orbs
   for(var i = 0; i < numberOfBokehs; i++) {
      
      // Generate a random bokeh size
      var bokehSize = randomXToY(bokehMinSize, bokehMaxSize);
      
      if(useRandomColours) {
         // Generate the random bokeh colour
         var bokehColour = randomColour();
      } else {
         // Use the given RGB code
         var bokehColour = orbColour;
      }
      
      // Create the bokeh
      var bokeh = $("<div />")
         .addClass("bokeh")
         .css({
               // Use the max screen width and height to position the bokeh
               'left' : Math.floor(Math.random()* screen.width ) + 'px',
               'top' : Math.floor(Math.random()* screen.height ) + 'px',
               'width' : bokehSize + 'px',
               'height' : bokehSize + 'px',
               '-moz-border-radius' : Math.floor(bokehSize)/2 + 'px',
               '-webkit-border-radius' : Math.floor(bokehSize)/2 + 'px',
               'border' : '1px solid rgba(' + bokehColour + ', 0.7)'
            });
            
      if(useGradients){
         bokeh.css({
            // Gradients for Firefox
            'background' : '-moz-radial-gradient( contain, rgba('+ bokehColour +', 0.1), rgba(' + bokehColour + ',0.4))',
            // Freaking ugly workaround to make gradients work for Safari too, by applying it to the background-image
            'background-image' : '-webkit-gradient(radial, center center, 0, center center, 70.5, from(rgba('+ bokehColour +', 0.1)), to(rgba(' + bokehColour + ',0.4)))'
         });
      } else {
         bokeh.css({
            'background' : 'rgba(' + bokehColour + ', 0.3)'
         });
      }
   
      // Append to container
      bokeh.appendTo("#bokehs");
   }
}

That's about it! On the demo page, I've made the variables attached to the user input, so they can decide what's going to happen. You can take a look in the code by downloading the source. You can now "create" (or generate) effects like this:

Pure CSS3 bokeh effect - 06

Pure CSS3 bokeh effect - 07

Or input your own colour! Pretty awesome, isn't it?

Conclusion and Download

Next to playing with colour, size and selecting whether to use gradients or not, you could also add the functionality to (randomly) choose the opacity of each bokeh. Other than that, I think this is a pretty neat effect to see. Maybe to very useful on actual webpages, but it does show the power of CSS3 (combined with jQuery).

Demo Pure CSS3 bokeh effect   Download Pure CSS3 bokeh effect

In the final version, I've added some configuration options for the user too. What do you think of this script? There is always room for improvement, so feel free to share anything.


Tags:  bokeh css3 jquery tutorial

Interested in this topic? You might enjoy another article I've written called

Did you like this article? Subscribe to my feed or email to keep updated on new articles.

Spread the word and submit to:
Digg!Reddit!Del.icio.us!Facebook!Technorati!StumbleUpon!Newsvine!Furl!Ma.gnolia!
Comments
Add NewSearchRSS
Liam McCabe   2010-02-16 21:34:24
Gravatar image Looking good Marco :)

Perhaps you should use box-shadow to add some blurred bokeh to give the impression of depth.
Marco - Thanks   2010-02-17 06:35:46
Gravatar image Thanks for your comment Liam! I was already messing around with box shadow (or a reversed gradient) to give the "depth" effect. Sadly, I couldn't get the desired result and therefor, I left it out.

You can download the source code and might try it yourself!
Codesquid   2010-02-16 21:39:42
Gravatar image Brilliant work! I love it! The power of CSS3 and jQuery together is amazing!
Marco - True!   2010-02-17 06:38:11
Gravatar image Yup, absolutely right! As you might have seen here on Marcofolio, I've messed around with CSS3 combined with jQuery a lot :) .
Janko   2010-02-16 22:16:02
Gravatar image Looking really good, Marco, awesome idea.
Nikola Lazarevic   2010-02-16 22:20:15
Gravatar image This is super work Marco!
Design Informer - Awesome!   2010-02-17 03:48:58
Gravatar image This is cool. Way to push CSS3 and be creative with it.
Richie - Awesome!!   2010-02-17 04:46:30
Gravatar image Great!! CSS3 is definitely the future of web design. I second to Liam's suggestion on the box shadows. Infact, Bokeh means to focus on one area while the others are intentionally made out of focus.

Awesome work, btw. Love to see more. Thanks Marco!!
Marco - Thanks!   2010-02-17 05:40:57
Gravatar image @Janko, @Nikola, @Design Informer, @Richie
Thanks for all the kind words, really appreciate it!
Kawsar Ali - Awesome   2010-02-17 06:48:35
Gravatar image Looks really great. Very cool idea. Well done Marco.
teerapuch   2010-02-17 07:35:59
Gravatar image CSS3 is cool Good for it
Atasözleri - Atasözleri   2010-02-17 09:38:47
Gravatar image Thank you, very nice sharing.
javo - Wow   2010-02-18 20:25:29
Gravatar image woooow, excelente, muy buen trabajo, me sorprendiste.
Iva - Awesome   2010-02-19 12:54:41
Gravatar image Awesome! I can already see where I would apply it. :D Your ideas are so innovative that they make me duck under the table in shame.

In THAT browser, it comes up with a JS error, just thought I'd point it out in case it's actually fixable.
Marco - Great!   2010-02-19 17:48:25
Gravatar image Thanks for that huge compliment Iva - really appreciate it! With "that" browser, you mean IE? I haven't tested it there, since I knew it wouldn't work there...
shira - ...until Microsoft comes with a CSS3 supporting In   2010-02-20 21:23:13
Gravatar image hahah.... haaaa....haaaa :woohoo: you're joking... - Why don't people just start boycotting IE and putting up buttons NOT designed for IE-Dinosaur.
shoaib hussain   2010-02-22 09:39:05
Gravatar image yeah man ,I m sure some of these days m gonna have a nightmare-with IE gobbling up my lil web designing skills.
John Pitchers - It's good... but   2010-02-22 15:06:16
Gravatar image It's a neat effect in a new browser.

Everyones spruking html5 this, css3 that, @fontface, blah blah, blah. But, relistically, it will be years before we can use these features consistently in live production sites when a large proportion of our customers are using browsers that won't support this. It's just not viable.

Good demo though.
9swords - Styler   2010-02-23 23:57:02
Gravatar image This is very creative and really awesome!
Lava360 - Nice pOst   2010-02-25 16:24:44
Gravatar image :cheer: Nice post... looking forward to see more
Mehedi Hasan - Awesome !!!!   2010-02-27 07:53:49
Gravatar image Really a nice post ... Thanks for sharing ... I will share this in my language to our country people :)

Thanks
Mehedi Hasan
Web Designer and Developer
Aux - Very sad this is not a CSS3 demo   2010-03-02 15:37:33
Gravatar image Idea is beautiful, but where is CSS3/HTML5? You are using proprietary attributes NOT compatible with both recommendations, so CSS3/HTML5 compliant browsers like Opera (and IE9 in future) are not able to show the effect.
Jason - Nice but..   2010-03-17 00:02:27
Gravatar image Really cool, loving using code to create art but what's with the outline? Set the colour to transparent for a far more believable effect.
Soldiers3lite - Developer (Coder)   2010-03-17 22:15:03
Gravatar image I like it somehow but I don't know how could I really use it for my website, but really great effect, good job ;)

btw if you see the stats about browser usage, the top dog is Firefox ;) followed by IE which now sucks compared to firefox 3.6
sivaranjan   2010-05-24 21:28:08
Gravatar image Your website is incredibly beautiful and useful. I have taken liberty to add this article to my CSS aggregator site. I hope you wont mind that.
Nikhil Verma - Another bokeh effect   2010-06-02 15:10:33
Gravatar image Hey !

I created a bokeh effect using CSS3 as well, never saw your website before that :-) It's quite similar to your's but I don't use the gradient rather than that I use the box shadow.

http://nikhil-verma.com/demos/5_bokeh/

Check it out ! :-) I loved yours !
how to tweak - Nice   2010-06-28 17:56:00
Gravatar image wow the one you mentioned looks so nice but I will prefer the one Marco talked bout in this post as it is well explained. :woohoo:
Aron Duby   2010-07-13 05:42:25
Gravatar image Love the tutorial. I was playing around with it in FireBug to be mouse responsive. Can get pretty intensive, but fun if anyone wants to play with it. I added the bind/unbind and rX and rY to be a random number from mouse click +/- min size. Not to useful on its own since it has to be used with the demo at this point, but I figured if it was worth the few minutes playing with it in firebug might be worth posting it here.

Code:

$('html').bind('mousedown',function(e){
repaintOnClick(e.pageX,e.pageY);
$(this).bind('mousemove',function(e){
repaintOnClick(e.pageX,e.pageY);
});
});
$('html').bind('mouseup',function(e){
$(this).unbind('mousemove');
})

function repaintOnClick(pageX,pageY) {

// Retrieve all user submitted data
//var numberOfBokehs = Math.floor((6 - 2)*Math.random()) + (3);
var numberOfBokehs = 3;
var bokehMinSize = parseInt($("#orbMin";).val());
var bokehMaxSize = parseInt($("#orbMax";).val());
var orbColour = $("#orbColour";).val();

// Check if we need to create random colours
var useRandomColours = false;
if ( $("#orbRandom";).is(":checked";) ) {
useRandomColours = true;
}

// Check if we need to create gradients
var useGradients = false;
if ( $("#orbGradient";).is(":checked";) ) {
useGradients = true;
}

// Generate the bokeh orbs
for(var i = 0; i < numberOfBokehs; i++) {

// Generate a random bokeh size
var bokehSize = randomXToY(bokehMinSize, bokehMaxSize);

if(useRandomColours) {
// Generate the random bokeh colour
var bokehColour = randomColour();
} else {
// Use the given RGB code
var bokehColour = orbColour;
}

// random position with +/- min size of click
rX = Math.floor(((pageX + bokehMinSize) - (pageX - bokehMinSize))*Math.random()) + ((pageX - bokehMinSize) + 1);
rY = Math.floor(((pageY + bokehMinSize) - (pageY - bokehMinSize))*Math.random()) + ((pageY - bokehMinSize) + 1);

// Create the bokeh
var bokeh = $("";)
.addClass("bokeh";)
.css({
'left' : rX, //Math.floor(Math.random()* screen.width ) + 'px',
'top' : rY, //Math.floor(Math.random()* screen.height ) + 'px',
'width' : bokehSize + 'px',
'height' : bokehSize + 'px',
'-moz-border-radius' : Math.floor(bokehSize)/2 + 'px',
'-webkit-border-radius' : Math.floor(bokehSize)/2 + 'px',
'border' : '1px solid rgba(' + bokehColour + ', 0.7)'
}).fadeIn('fast');

if(useGradients){
bokeh.css({
// Gradients for Firefox
'background' : '-moz-radial-gradient( contain, rgba('+ bokehColour +', 0.1), rgba(' + bokehColour + ',0.4))',
// Freaking ugly workaround to make gradients work for Safari too, by applying it to the background-image
'background-image' : '-webkit-gradient(radial, center center, 0, center center, 70.5, from(rgba('+ bokehColour +', 0.1)), to(rgba(' + bokehColour + ',0.4)))'
});
} else {
bokeh.css({
'background' : 'rgba(' + bokehColour + ', 0.3)'
});
}

// Append to container
bokeh.appendTo("#bokehs";);
}
}
Cane - plugin   2010-07-14 06:50:51
Gravatar image Hi, Marko!
If you not against, I have issued your script as a plug-in and have applied it at my [url href="http://cane.0fees.net"]site[/url]. And I wish to place it in repository jQuery.
Eariyorum - Thanx   2010-08-27 00:27:49
Gravatar image Looking really good, Marco, awesome idea.
Read more...
Name:
Email:
  Gravatar enabled.
Website:
Title:
UBBCode:
[b] [i] [u] [url] [quote] [code] [img] 
 
 
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch:
:(:shock::X:side::):P:unsure::woohoo::huh::whistle:;):s
:!::?::idea::arrow:
 
Security Image
Please input the anti-spam code that you can read in the image.
Unsubscribe from e-mail notifications.
 
< Prev   Next >
Subscribe

If 5407 people are reading this site every day, why don't you?