Pseudo-element templating
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Version Badge Build Status Dependencies License File Size

A proof of concept, pet (pseudo-element templating) expands on the capabilities of pseudo-elements by adding support for HTML and data attribute interpolation within the CSS content property.


The beauty of pet is that it's a zero API library, meaning there are no functions to import, just the library itself:

import from 'pet';

Signify an element as a pet element by adding the "pet" class name. Then define its template within the ::before pseudo-element:

<div class="pet component"></div>
.component::before {
    content: '<span>Hello World</span>';


<div class="pet component">
    <span>Hello World</span>

Remember to add the following to your CSS to ensure the pseudo-element templates are not displayed as plain text:

.pet::before {
    display: none !important;


Use data attributes and ES6 template literal syntax to perform interpolation. Name conversion works the same as HTML data attributes (data-*) to/from the JavaScript element.dataset property:

<div class="pet component" data-first-name="John" data-last-name="Doe"></div>
.component::before {
    content: '<span>Hello world, my name is ${firstName} ${lastName}</span>';


<div class="pet component" data-first-name="John" data-last-name="Doe"></div>
    <span>Hello world, my name is John Doe</span>

Programmatically changing a data attribute will automatically patch the changes in the DOM in a performant manner.

When a template is initially rendered, and every time a template is patched, a custom "render" event is dispatched on the pet element:

document.querySelector('.component').addEventListener('render', (e) => {
    // React to changes

Harness the Power of CSS

Create micro templates easily for common patterns:

.phone::before {
    content: '<span><i class="icon-phone"></i> ${number}</span>';

.email::before {
    content: '<a href="mailto:${email}"><i class="icon-email"></i> ${email}</a>';

Alter a template based on class names and attributes:

.avatar::before {
    content: '<img src="default.jpg" />';

.avatar[data-src]::before {
    content: '<img src="${src}" />';


pet is CommonJS and AMD compatible with no dependencies. You can download the development or minified version, or install it in one of the following ways:

npm install ryanmorr/pet

bower install ryanmorr/pet


Open test/runner.html in your browser or test with PhantomJS by issuing the following commands:

npm install
npm install -g gulp
gulp test


This project is dedicated to the public domain as described by the Unlicense.