Expanding Images using HTML5’s contenteditable tabindex

Avatar of Chris Coyier
Chris Coyier on (Updated on )

DigitalOcean provides cloud products for every stage of your journey. Get started with $200 in free credit!

HTML5 has a new attribute, contenteditable, which can be applied to any element which allows it to be edited directly in the browser window. Think of text input with a predefined value, but it can literally be any element. Form elements like text inputs support the :focus pseudo class, which allow us to style those elements when they are clicked upon or otherwise navigated to. Giving an element the contenteditable attribute means it also now supports the :focus pseudo class, which opens up some interesting possibilities!

We’ll exploit this little trick to make an expanding image (like a lightbox without the overlay) right within some content.

UPDATE: Even better, you can give attributes a tabindex attribute, like you would a form element, which allow allows :focus without the editability. This article has been updated to go that route instead.

HTML5 Markup

HTML5 has nice elements for including captioned images.

<section class="image-gallery">

      <img src="images/img-1.jpg" alt="jump, matey" />


We just give the figure element tabindex, so that it can be in focus.

<figure tabindex=1>

Give each subsequent figure a tabindex value one higher and the images will be able to be tabbed through nicely from the keyboard!

The Images

The images will be “full size”.

This means they will be scaled down for regular display on the page, and scaled up when we do our magical CSS expanding. Potentially a waste of bandwidth for the browsers that don’t support this. The tradeoff is your call.


Normal display:

figure { 
  width: 120px; 
  float: left; 
  margin: 0 20px 0 0; 
  background: white;
  border: 10px solid white; 
  -webkit-box-shadow: 0 3px 10px #ccc; 
  -moz-box-shadow: 0 3px 10px #ccc;
  -webkit-transform: rotate(5deg); 
  -moz-transform: rotate(5deg);
  -webkit-transition: all 0.7s ease; 
  -moz-transition: all 1s ease;
  position: relative;

figcaption { 
  text-align: center; 
  display: block; 
  font-size: 12px; 
  font-style: italic; 

figure img { 
  width: 100%; /* Scale down */

The :focus part of this isn’t CSS3, the but shadows, transforms, and transitions are. The hover state will rotate the image a bit, and the :focus style (when the image is clicked on), will expand it, rotate it again, and make sure it’s on top with z-index.

figure:hover {
  -webkit-transform: rotate(-1deg); -moz-transform: rotate(1deg);
  -webkit-box-shadow: 0 3px 10px #666; -moz-box-shadow: 0 3px 10px #666;

figure:focus {
  outline: none;
  -webkit-transform: rotate(-3deg) scale(2.5); -moz-transform: rotate(-3deg) scale(2.5);
   -webkit-box-shadow: 0 3px 10px #666; -moz-box-shadow: 0 3px 10px #666;
  z-index: 9999;

Browser Compatibility

The HTML5 contenteditable attribute is supported in Firefox 3.6+, Safari 4+, Chrome, and Opera (10.6 only tested). Note that the attribute will cascade down to all child elements. In our demo, having the image and figure caption be editable doesn’t make much sense, so we can turn it off individually on them.

<figure contenteditable="true">
  <img src="images/img-1.jpg" alt="jump, matey" contenteditable="false" />
  <figcaption contenteditable="false">Jump!</figcaption>

If you forget to turn off the editablity of the images, Firefox can look a bit funky giving you resize handles for images. Update: another reason to use tabindex instead.

Opera respects the child elements not being editable, but still runs the spellchecker on them and will red-underline words it finds misspelled which can be a bit weird.

Our demo also relies upon transforms to “work” though, which are only supported in current WebKit browsers and Firefox 4+. Firefox 3.6 supports the transform but not the transition.

The fallback is that the images just don’t expand though, which is of course no big deal.

Demo & Download

View Demo   Download Files


  • If you are looking for a pure CSS lightbox, including the overlay, check out Stu Nicholls version.
  • If you need your lightbox to be fully cross browser compatible, use JavaScript like the Colorbox plugin for jQuery.


Big thanks to Adrian Sinclair who contacted me about this idea and helped with everything.