How to use contenteditable attribute

What does contenteditable attribute do?

According to Mozilla Developer Network:

The contenteditable global attribute is an enumerated attribute indicating if the element should be editable by the user. If so, the browser modifies its widget to allow editing.

Let's examine those two lines. The first interesting thing is global attribute which means that the attribute can be placed on any HTML element even on those that are not part of HTML5 spec. Many of the examples are using div, but you could use your custom elements.

Enumerated attribute, in this case, means that there are two valid states: true (or empty string) or false.

If so, the browser modifies its widget to allow editing.

The last line indicates that the browser does all the hard work. Therefore, no or minimal amount of effort JavaScript will be added to the developer.

More about global attributes can be found (again) from MDN.


See the Pen QwBrEY by Tatu Tamminen (@ttamminen) on CodePen.

That was ..unimpressive. What's the point?

Contenteditable can be used for example:

  • to create editable data views
  • WYSIWYG editors (such as Perch CMS)

We have been using contenteditable attribute for admin views of the data tables. Regular users get the same visualisation, but HTML is missing the attribute.

Let's see what kind of customizations can be done using CSS.

Using CSS to target contenteditable

To target elements that have contenteditable attribute


Or to explicitly tell the state


Specific elements with contenteditable attribute set + active pseudo-class.


Example: small icons to indicate row is editable

See the Pen CSS Table Layout by Tatu Tamminen (@ttamminen) on CodePen.

If you hover on the fields, you'll get small pen to indicate it's editable. The icon disappears (even if you hover on it) when you active the field by clicking it.

The first step is to reserve space for the icon. Otherwise you get nasty pumping effect when the dimensions change.

// target elements that have contenteditable attribute 
// and use :after pseudo-selector on it
[contenteditable]:after {
    width: 8px;
    height: 8px;

    // place the icon on the same line with text
    display: inline-block;

    // creates new element
    content: ' ';

Next we need to show the icon on hover.

// target elements that have contenteditable attribute  
// and are on hover state. Create element after it.
[contenteditable]:hover:after {
    content: url( {{ place your icon or data URI here }} );

And hide it when the field has focused.

[contenteditable]:focus:after {
    width: 0;
    content: '';

Note: The table used in this demo is done by Luke Peters (original pen)

More reading

The WHATWG Blog - The Road to HTML 5: contentEditable

CodePen - Placeholder support for contentEditable elements, without JavaScript