Improving the CSS only modal

In my orig­i­nal post I explained how to cre­ate a CSS only modal pop-up using :tar­get, pseudo-elements and pointer events. This had a num­ber of caveats, any browser that didn’t sup­port pointer events would see a non-clickable page and the forward/back con­trols would nav­i­gate through dia­logues, which is usu­ally unde­sir­able. Of course it was only an experiment.

The site’s design has been updated and the com­ment form reverted to a sim­pler, non-modal one. The orig­i­nal can still be seen in the video below.

All ref­er­ences to the :tar­get pseudo-selector have been removed, instead an “active” class is tog­gled using JavaScript. The CSS modal still uses an opac­ity tran­si­tion but pointer events are gone. The default is now display:none with an inter­me­di­ate state that ren­ders the modal as display:block (remem­ber it still begins at opac­ity: 0).

The flow is:

  • Add an inter­me­di­ate class to trig­ger the modal ele­ments above every­thing, with opac­ity 0.
  • Add an active class to trig­ger ani­ma­tion and tran­si­tion to full opacity.
  • On close, remove active class, add min­imise class to trig­ger min­imise ani­ma­tion and tran­si­tion to opac­ity 0.
  • Remove inter­me­di­ate class.

Onclick han­dlers are added to the “post com­ment” links to add classes and to the close link to remove them. When opened a han­dler is added to the body to lis­ten for the ESC key, which closes the modal. The first input in the modal is focused on open.

I took the oppor­tu­nity to play with some HTML5 fea­tures. The com­ment form now uses place­holder attrib­utes, and if sup­ported, labels are hid­den. The fea­ture detec­tion is delight­fully simple:

supportPlaceholder: function() {
	  var i = document.createElement('input');
	  return 'placeholder' in i;
}()

See Dive into HTML5 for more.

The close link text which has an :after pseudo-element (i.e. the X) is no longer hid­den, instead it becomes the can­cel link and is essen­tial for browsers that can’t com­pre­hend gen­er­ated content.

In webkit you’ll see the modal bounce in and min­imise out (smoothly in Safari and iOS). In Fire­fox you’ll get an opac­ity tran­si­tion and in IE the modal will just appear or dis­ap­pear. In IE8 and below the page is not greyed out due to lack of rgba sup­port. I’m fine with this. This is still a bit of a trial to see how peo­ple actu­ally use the modal and what prob­lems it might throw up.

Fire­fox 10 has much improved ani­ma­tion per­for­mance. Exper­i­ment updated to be full featured.

In con­clu­sion, with JavaScript much of the mechan­i­cal new CSS can be dropped and with a slightly more com­pli­cated class tog­gle sys­tem we achieve cross browser sup­port, with­out sac­ri­fic­ing that lovely hard­ware accel­er­ated CSS animation.

Still want that ani­ma­tion cross browser? I rec­om­mend look­ing into Faruk Ateş’s Run­loop jQuery plu­gin which gives you keyframed ani­ma­tions in any browser.

In other news, I’ve tidied up the com­ments lay­out a lit­tle and added a short books cat­e­gory with a selec­tion of books I highly recommend.

Paul Hayes

Paul Hayes is a developer at Last.fm. You should follow him on Twitter, where he talks about UX, HTML, CSS and JavaScript, amongst other cool stuff.