Skip to content

Instantly share code, notes, and snippets.

@cferdinandi
Last active January 24, 2025 19:44
Show Gist options
  • Save cferdinandi/7e1f790a0aff23f2d4068258ee5f6175 to your computer and use it in GitHub Desktop.
Save cferdinandi/7e1f790a0aff23f2d4068258ee5f6175 to your computer and use it in GitHub Desktop.
Watch the tutorial for this source code at https://www.youtube.com/watch?v=TnQ0ooEMRqc
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Lettering.js Examples</title>
<meta name="description" content="A jQuery Plugin that allows you to style each individual letter and more.">
<meta name="author" content="Dave Rupert">
<meta name="viewport" content="width=device-width; initial-scale=1.0">
<link rel="stylesheet" href="style.css" type="text/css" media="screen"></link>
<style type="text/css" media="screen">
.demo {
padding: 50px;
border:1px solid #ccc;
font-weight:bold;
color: red;
background:#d0d0d0;
font-size:20px;
line-height:1.5;
text-align:center;
}
.demo h1 { font-size:72px; text-transform:uppercase; margin-bottom:0px;}
.char2,
#demo2 .word2,
.line2 { color: orange; }
.char3,
.word3,
.line3 { color: yellow; }
.char4,
.line4 { color: blue; }
.char5 { color: green; }
.char6 { color: indigo; }
.char7 { color: violet; }
</style>
</head>
<body>
<div id="container">
<header>
<h1 id="thebrand">Lettering.JS</h1>
<p>The following are some hokey examples of how you can implement LETTERING.JS.
</header>
<article id="main">
<section id='lettering-demo'>
<h2>Letters</h2>
<div id="demo1" class="demo">
<h1>Rainbow</h1>
</div>
</section>
<section id='words-demo'>
<h2>Words</h2>
<div id="demo2" class="demo">
<h1>Hi, Multi Color</h1>
</div>
</section>
<section id='lines-demo'>
<h2>Lines</h2>
<div id="demo3" class="demo">
<p>This is an amazing<br/> Revolution in Typography. <br/> The possibilities are endless: <br/> Coloring, Vertical spacing, and Kerning.</p>
</div>
</section>
</article>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="jquery.lettering.js"></script>
<script>
$(document).ready(function() {
$("#demo1 h1").lettering();
$("#demo2 h1").lettering('words');
$("#demo3 p").lettering('lines');
});
</script>
<footer>
<p>&copy;2010 Dave Rupert <a href="http://daverupert.com">http://daverupert.com</a>
</footer>
</div>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Lettering.js Examples</title>
<meta name="description" content="A jQuery Plugin that allows you to style each individual letter and more.">
<meta name="author" content="Dave Rupert">
<meta name="viewport" content="width=device-width; initial-scale=1.0">
<link rel="stylesheet" href="style.css" type="text/css" media="screen"></link>
<style type="text/css" media="screen">
.demo {
padding: 50px;
border:1px solid #ccc;
font-weight:bold;
color: red;
background:#d0d0d0;
font-size:20px;
line-height:1.5;
text-align:center;
}
.demo h1 { font-size:72px; text-transform:uppercase; margin-bottom:0px;}
.char2,
#demo2 .word2,
.line2 { color: orange; }
.char3,
.word3,
.line3 { color: yellow; }
.char4,
.line4 { color: blue; }
.char5 { color: green; }
.char6 { color: indigo; }
.char7 { color: violet; }
</style>
</head>
<body>
<div id="container">
<header>
<h1 id="thebrand">Lettering.JS</h1>
<p>The following are some hokey examples of how you can implement LETTERING.JS.
</header>
<article id="main">
<section id='lettering-demo'>
<h2>Letters</h2>
<div id="demo1" class="demo">
<h1>Rainbow</h1>
</div>
</section>
<section id='words-demo'>
<div id="demo2" class="demo">
<h1>Hi, Multi Color</h1>
</div>
</section>
<section id='lines-demo'>
<h2>Lines</h2>
<div id="demo3" class="demo">
<p>This is an amazing<br/> Revolution in Typography. <br/> The possibilities are endless: <br/> Coloring, Vertical spacing, and Kerning.</p>
</div>
</section>
</article>
<script src="vanilla.lettering.js"></script>
<script>
new Lettering('#demo1 h1');
new Lettering('#demo2 h1', 'words');
new Lettering('#demo3 p', 'lines');
</script>
<footer>
<p>&copy;2010 Dave Rupert <a href="http://daverupert.com">http://daverupert.com</a>
</footer>
</div>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Lettering.js Examples</title>
<meta name="description" content="A jQuery Plugin that allows you to style each individual letter and more.">
<meta name="author" content="Dave Rupert">
<meta name="viewport" content="width=device-width; initial-scale=1.0">
<link rel="stylesheet" href="style.css" type="text/css" media="screen"></link>
<style type="text/css" media="screen">
.demo {
padding: 50px;
border:1px solid #ccc;
font-weight:bold;
color: red;
background:#d0d0d0;
font-size:20px;
line-height:1.5;
text-align:center;
}
.demo h1 { font-size:72px; text-transform:uppercase; margin-bottom:0px;}
.char2,
#demo2 .word2,
.line2 { color: orange; }
.char3,
.word3,
.line3 { color: yellow; }
.char4,
.line4 { color: blue; }
.char5 { color: green; }
.char6 { color: indigo; }
.char7 { color: violet; }
</style>
</head>
<body>
<div id="container">
<header>
<h1 id="thebrand">Lettering.JS</h1>
<p>The following are some hokey examples of how you can implement LETTERING.JS.
</header>
<article id="main">
<section id='lettering-demo'>
<h2>Letters</h2>
<div id="demo1" class="demo">
<h1><wc-lettering>Rainbow</wc-lettering></h1>
</div>
</section>
<section id='words-demo'>
<h2>Words</h2>
<div id="demo2" class="demo">
<h1><wc-lettering method="words">Hi, Multi Color</wc-lettering></h1>
</div>
</section>
<section id='lines-demo'>
<h2>Lines</h2>
<div id="demo3" class="demo">
<p><wc-lettering method="lines">This is an amazing<br/> Revolution in Typography. <br/> The possibilities are endless: <br/> Coloring, Vertical spacing, and Kerning.</wc-lettering></p>
</div>
</section>
</article>
<script src="wc.lettering.js"></script>
<footer>
<p>&copy;2010 Dave Rupert <a href="http://daverupert.com">http://daverupert.com</a>
</footer>
</div>
</body>
</html>
/*global jQuery */
/*!
* Lettering.JS 0.7.0
*
* Copyright 2010, Dave Rupert http://daverupert.com
* Released under the WTFPL license
* http://sam.zoy.org/wtfpl/
*
* Thanks to Paul Irish - http://paulirish.com - for the feedback.
*
* Date: Mon Sep 20 17:14:00 2010 -0600
*/
(function($){
function injector(t, splitter, klass, after) {
var text = t.text()
, a = text.split(splitter)
, inject = '';
if (a.length) {
$(a).each(function(i, item) {
inject += '<span class="'+klass+(i+1)+'" aria-hidden="true">'+item+'</span>'+after;
});
t.attr('aria-label',text)
.empty()
.append(inject)
}
}
var methods = {
init : function() {
return this.each(function() {
injector($(this), '', 'char', '');
});
},
words : function() {
return this.each(function() {
injector($(this), ' ', 'word', ' ');
});
},
lines : function() {
return this.each(function() {
var r = "eefec303079ad17405c889e092e105b0";
// Because it's hard to split a <br/> tag consistently across browsers,
// (*ahem* IE *ahem*), we replace all <br/> instances with an md5 hash
// (of the word "split"). If you're trying to use this plugin on that
// md5 hash string, it will fail because you're being ridiculous.
injector($(this).children("br").replaceWith(r).end(), r, 'line', '');
});
}
};
$.fn.lettering = function( method ) {
// Method calling logic
if ( method && methods[method] ) {
return methods[ method ].apply( this, [].slice.call( arguments, 1 ));
} else if ( method === 'letters' || ! method ) {
return methods.init.apply( this, [].slice.call( arguments, 0 ) ); // always pass an array
}
$.error( 'Method ' + method + ' does not exist on jQuery.lettering' );
return this;
};
})(jQuery);
html, body, div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
abbr, address, cite, code,
del, dfn, em, img, ins, kbd, q, samp,
small, strong, sub, sup, var,
b, i,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure,
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
margin:0;
padding:0;
border:0;
outline:0;
font-size:100%;
vertical-align:baseline;
background:transparent;
}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display:block;
}
nav ul { list-style:none; }
blockquote, q { quotes:none; }
blockquote:before, blockquote:after,
q:before, q:after { content:''; content:none; }
a { margin:0; padding:0; font-size:100%; vertical-align:baseline; background:transparent; }
ins { background-color:#ff9; color:#000; text-decoration:none; }
mark { background-color:#ff9; color:#000; font-style:italic; font-weight:bold; }
del { text-decoration: line-through; }
abbr[title], dfn[title] { border-bottom:1px dotted; cursor:help; }
/* tables still need cellspacing="0" in the markup */
table { border-collapse:collapse; border-spacing:0; }
hr { display:block; height:1px; border:0; border-top:1px solid #ccc; margin:1em 0; padding:0; }
input, select { vertical-align:middle; }
/* END RESET CSS */
body { font:13px/1.231 sans-serif; *font-size:small; } /* hack retained to preserve specificity */
select, input, textarea, button { font:99% sans-serif; }
pre, code, kbd, samp { font-family: monospace, sans-serif; }
body, select, input, textarea {
color: #444;
}
h1,h2,h3,h4,h5,h6 { font-weight: bold; }
html { overflow-y: scroll; }
a:hover, a:active { outline: none; }
a, a:active, a:visited { color: #607890; }
a:hover { color: #036; }
ul, ol { margin-left: 1.8em; }
ol { list-style-type: decimal; }
small { font-size: 85%; }
strong, th { font-weight: bold; }
td, td img { vertical-align: top; }
sub { vertical-align: sub; font-size: smaller; }
sup { vertical-align: super; font-size: smaller; }
pre {
padding: 15px;
white-space: pre; /* CSS2 */
white-space: pre-wrap; /* CSS 2.1 */
white-space: pre-line; /* CSS 3 (and 2.1 as well, actually) */
word-wrap: break-word; /* IE */
}
textarea { overflow: auto; }
.ie6 legend, .ie7 legend { margin-left: -7px; }
input[type="radio"] { vertical-align: text-bottom; }
input[type="checkbox"] { vertical-align: bottom; }
.ie7 input[type="checkbox"] { vertical-align: baseline; }
.ie6 input { vertical-align: text-bottom; }
label, input[type=button], input[type=submit], button { cursor: pointer; }
button, input, select, textarea { margin: 0; }
input:valid, textarea:valid { }
input:invalid, textarea:invalid {
border-radius: 1px;
-moz-box-shadow: 0px 0px 5px red;
-webkit-box-shadow: 0px 0px 5px red;
box-shadow: 0px 0px 5px red;
}
.no-boxshadow input:invalid,
.no-boxshadow textarea:invalid { background-color: #f0dddd; }
::-moz-selection{ background: #FF5E99; color:#fff; text-shadow: none; }
::selection { background:#FF5E99; color:#fff; text-shadow: none; }
a:link { -webkit-tap-highlight-color: #FF5E99; }
button { width: auto; overflow: visible; }
.ie7 img { -ms-interpolation-mode: bicubic; }
.hidden { display: none; visibility: hidden; }
.visuallyhidden { position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px); }
.invisible { visibility: hidden; }
.clearfix:after { content: "\0020"; display: block; height: 0; clear: both; visibility: hidden; }
.clearfix { zoom: 1; }
body { background:#baddad;}
#container {
width: 800px;
margin:50px auto 200px;
padding:50px;
background:#fff;
}
pre {
display:block;
border:1px solid #ccc;
background:#f8f8f8;
margin-bottom:2em;
}
h1, h2, h3, h4 { }
h1 { font-size: 48px; text-transform:uppercase; margin-bottom: 0em; }
h2 { font-size: 28px; margin-bottom: 0.5em; }
h3 { font-size: 34px; margin-bottom: 0.5em; }
h4 { margin-bottom: 0.5em; }
section { margin-bottom: 4em; }
p { margin-bottom:1.5em;}
@media print {
* { background: transparent !important; color: #444 !important; text-shadow: none !important; }
a, a:visited { color: #444 !important; text-decoration: underline; }
a:after { content: " (" attr(href) ")"; }
abbr:after { content: " (" attr(title) ")"; }
.ir a:after { content: ""; } /* Don't show links for images */
pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
thead { display: table-header-group; } /* css-discuss.incutio.com/wiki/Printing_Tables */
tr, img { page-break-inside: avoid; }
@page { margin: 0.5cm; }
p, h2, h3 { orphans: 3; widows: 3; }
h2, h3{ page-break-after: avoid; }
}
class Lettering {
/**
* Create the constructor object
* @param {Number} start The starting amount
*/
constructor (selector, method = 'letters') {
// Define our properties
this.elem = document.querySelector(selector);
// Make sure there's an element to modify
if (!this.elem) {
console.warn('Lettering.js: Element not found');
return;
}
// Make sure method is supported
if (!this[method]) {
console.warn('Lettering.js: Method not supported');
return;
}
// Run the method
this[method]();
}
/**
* Split on letters
*/
letters () {
this.injector(this.elem, '', 'char', '');
}
/**
* Split on words
*/
words () {
this.injector(this.elem, ' ', 'word', ' ');
}
/**
* Split on lines
*/
lines () {
let r = 'eefec303079ad17405c889e092e105b0';
this.elem.querySelectorAll('br').forEach(function (br) {
br.replaceWith(r);
});
this.injector(this.elem, r, 'line', '');
}
/**
* Inject span elements around letters
* @param {Element} elem The element we're modifying text in
* @param {String} splitter Character(s) to split on
* @param {String} klass Class name to use for each character
* @param {String} after Character(s) to add after each letter
*/
injector(elem, splitter, klass, after) {
let text = elem.textContent;
let arr = text.split(splitter);
if (arr.length) {
elem.setAttribute('aria-label', text);
elem.innerHTML = arr.map(function(item, i) {
return '<span class="'+klass+(i+1)+'" aria-hidden="true">'+item+'</span>'+after;
}).join('');
}
}
}
customElements.define('wc-lettering', class extends HTMLElement {
/**
* The class constructor object
*/
constructor () {
// Gives element access to the parent class properties
super();
// Define our method
let method = this.getAttribute('method') || 'letters';
// Make sure method is supported
if (!this[method]) {
console.warn('Lettering.js: Method not supported');
return;
}
// Run the method
this[method]();
}
/**
* Split on letters
*/
letters () {
this.injector(this, '', 'char', '');
}
/**
* Split on words
*/
words () {
this.injector(this, ' ', 'word', ' ');
}
/**
* Split on lines
*/
lines () {
let r = 'eefec303079ad17405c889e092e105b0';
this.querySelectorAll('br').forEach(function (br) {
br.replaceWith(r);
});
this.injector(this, r, 'line', '');
}
/**
* Inject span elements around letters
* @param {Element} elem The element we're modifying text in
* @param {String} splitter Character(s) to split on
* @param {String} klass Class name to use for each character
* @param {String} after Character(s) to add after each letter
*/
injector(elem, splitter, klass, after) {
let text = elem.textContent;
let arr = text.split(splitter);
if (arr.length) {
elem.setAttribute('aria-label', text);
elem.innerHTML = arr.map(function(item, i) {
return '<span class="'+klass+(i+1)+'" aria-hidden="true">'+item+'</span>'+after;
}).join('');
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment