Skip to content
master
Go to file
Code

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
src
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

pet

Version Badge Build Status License

Pseudo-element templating

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.

Install

Download the CJS, ESM, UMD versions or install via NPM:

npm install @ryanmorr/pet

Usage

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 '@ryanmorr/pet';

Signify an element as a pet element by adding the "pet" attribute. Then define its template within the content property of the ::before pseudo-element:

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

Generates:

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

If you experience FOUC, try adding the following to your CSS to ensure the pseudo-element templates are not displayed as plain text:

[pet]::before {
    display: none !important;
}

Interpolation

Interpolation is achieved through data attributes set on the pet element and mustache-style double curly braces serving as delimiters for tokens within the template. The token found between the delimiters reference the data attribute using the same name conversion as the element.dataset property in JavaScript. For example, an attribute of data-foo-bar-baz-qux would be referenced as {{fooBarBazQux}} within a template.

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

Generates:

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

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}}" />';
}

License

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

You can’t perform that action at this time.