From 02d16e24a1cebb84788d11bd70c4710deb5be86e Mon Sep 17 00:00:00 2001 From: Stephen Shaw Date: Wed, 10 Jan 2018 21:11:25 -0600 Subject: [PATCH] Switch to spans and outer spaces --- README.md | 141 ++++++++++++++++++++++++++++++++++++++++++++++- index.js | 7 ++- package.json | 2 +- splitting.js | 7 ++- splitting.min.js | 2 +- 5 files changed, 152 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index dba455b..1c14d5e 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,143 @@ _CSS Vars for split words and chars!_ -Splitting is a JavaScript microlibrary (less than 1kb) to split a DOM element's words and characters into elements. The word and character elements are populated with CSS vars to assist with CSS transitions and animations that were previously not feasible with CSS. +Splitting is a JavaScript microlibrary (1.2kb min, 0.6kb gzipped) to split a DOM element's words and characters into elements. The word and character elements are populated with CSS vars to assist with transitions and animations that were previously not feasible with CSS. + +## Installation + +Add Splitting to an existing project with [npm](https://npmjs.org) using `npm install -s splitting` or use [unpkg](https://unpkg.com) with `` for easy embedding on platforms like [Codepen](https://codepen.io). + +## Methods + +All methods can accept a selector, element, or a NodeList/Array of elements. The parent/targetted element will receive a `splitting` class. + +### Splitting.words + +Divide an element's `innerText` into words. + +Parent element receives a `--total-words` CSS var containing the total number of words. Each word is wrapped in an `` element with a `--word-index` containing the word's position, and a `data-word` attribute containing the actual word. + +#### Example + +```js +Splitting.wordss("[data-splitting-words]"); +``` + +_Input:_ + +```html +

Splitting words!

+``` + +_Output:_ + +```html +

+ Splitting + words! +

+``` + +### Splitting.chars + +Divide an element's `innerText` into words and characters. `Splitting.words` is called on the element first to prevent characters from wrapping to the next line unnecessarily, then each word is divided into characters. + +Parent element receives a `--total-char` CSS var containing the total number of characters. Each character is wrapped in an `` element with a `--char-index` containing the characters's position, and a `data-char` attribute containing the actual character. + +#### Example + +```js +Splitting.chars("[data-splitting-chars]"); +``` + +_Input:_ + +```html +

SPLITTING!

+``` + +_Output:_ + +```html +

+ + S + P + L + I + T + T + I + N + G + ! + +

+``` + +### Splitting.children + +Apply CSS var indexes to an element's children. + +#### Example + +```js +Splitting.children(".list", ".list-item", "item"); +``` + +_Input:_ + +```html +
    +
  • 1
  • +
  • 2
  • +
  • 3
  • +
+``` + +_Output:_ + +```html +
    +
  • 1
  • +
  • 2
  • +
  • 3
  • +
+``` + +## Styles + +### Recommended Styles + +Many CSS properties, like `transform`, will not work on `display: inline` elements, so applying `display: inline-block` will keep your words and characters looking the same, while giving you the most flexibility in transitions and animations. + +```css +.splitting .word, +.splitting .char { + display: inline-block; +} +``` + +### Pseudo Elements + +You may have noticed that `Splitting.words` and `Splitting.chars` apply `data-word` and `data-char` attributes, respectively. + +This allows for great flexibility in your CSS by using Psuedo elements with `content: attr(data-char)`. + +```css +.splitting .char { + position: relative; +} + +/* Populate the psuedo elements with the character to allow for expanded effects */ +.splitting .char:before, +.splitting .char:after { + content: attr(data-char); + position: absolute; + top: 0; + left: 0; + display: none; + transition: inherit; + user-select: none; +} +``` diff --git a/index.js b/index.js index f7bfc42..e5f1abd 100644 --- a/index.js +++ b/index.js @@ -72,11 +72,14 @@ function split(el, key, splitBy, space) { el.innerHTML = ""; return text.split(splitBy).map(function(split, i) { - var splitEl = document.createElement("i"); + var splitEl = document.createElement("span"); splitEl.className = key; splitEl.setAttribute("data-" + key, split); - splitEl.innerText = (space && i > 0 ? " " : "") + split; + splitEl.innerText = split; el.appendChild(splitEl); + if (space) { + splitEl.insertAdjacentText("beforebegin", " "); + } return splitEl; }); } diff --git a/package.json b/package.json index d22ebe0..cc627b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "splitting", - "version": "0.9.2", + "version": "0.9.3", "description": "Microlibrary to split a DOM element's words & chars into elements populated with CSS vars.", "main": "index.js", diff --git a/splitting.js b/splitting.js index 4f3a366..a049500 100644 --- a/splitting.js +++ b/splitting.js @@ -66,11 +66,14 @@ function split(el, key, splitBy, space) { el.innerHTML = ""; return text.split(splitBy).map(function(split, i) { - var splitEl = document.createElement("i"); + var splitEl = document.createElement("span"); splitEl.className = key; splitEl.setAttribute("data-" + key, split); - splitEl.innerText = (space && i > 0 ? " " : "") + split; + splitEl.innerText = split; el.appendChild(splitEl); + if (space) { + splitEl.insertAdjacentText("beforebegin", " "); + } return splitEl; }); } diff --git a/splitting.min.js b/splitting.min.js index db4be64..0ffa056 100644 --- a/splitting.min.js +++ b/splitting.min.js @@ -1 +1 @@ -!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):t.Splitting=n()}(this,function(){"use strict";function t(t){return n(t).map(function(t,n){return t._splitting||(t._splitting={el:t},t.className+=" splitting"),t._splitting})}function n(t,n){return Array.prototype.slice.call(t.nodeName?[t]:t[0].nodeName?t:(n||document).querySelectorAll(t),0)}function e(t,n,e){return e&&(t[n+"s"]=e,t.el.style.setProperty("--total-"+n+"s",e.length),e.map(function(t,e){t.style.setProperty("--"+n+"-index",e)})),t}function r(t,n,e,r){var i=t.innerText;return t.innerHTML="",i.split(e).map(function(e,i){var o=document.createElement("i");return o.className=n,o.setAttribute("data-"+n,e),o.innerText=(r&&i>0?" ":"")+e,t.appendChild(o),o})}return t.$=n,t.index=e,t.split=r,t.children=function(r,i,o){return t(r).map(function(t){return e(t,o,n(i,t.el))})},t.words=function(n){return t(n).map(function(t,n){return t.words?t:e(t,"word",r(t.el,"word",/\s+/,!0))})},t.chars=function(n){return t.words(n).map(function(t){return t.chars?t:e(t,"char",t.words.reduce(function(t,n,e){return t.concat(r(n,"char",""))},[]))})},t}); \ No newline at end of file +!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):n.Splitting=t()}(this,function(){"use strict";function n(n){return t(n).map(function(n,t){return n._splitting||(n._splitting={el:n},n.className+=" splitting"),n._splitting})}function t(n,t){return Array.prototype.slice.call(n.nodeName?[n]:n[0].nodeName?n:(t||document).querySelectorAll(n),0)}function e(n,t,e){return e&&(n[t+"s"]=e,n.el.style.setProperty("--total-"+t+"s",e.length),e.map(function(n,e){n.style.setProperty("--"+t+"-index",e)})),n}function r(n,t,e,r){var i=n.innerText;return n.innerHTML="",i.split(e).map(function(e,i){var o=document.createElement("span");return o.className=t,o.setAttribute("data-"+t,e),o.innerText=e,n.appendChild(o),r&&o.insertAdjacentText("beforebegin"," "),o})}return n.$=t,n.index=e,n.split=r,n.children=function(r,i,o){return n(r).map(function(n){return e(n,o,t(i,n.el))})},n.words=function(t){return n(t).map(function(n,t){return n.words?n:e(n,"word",r(n.el,"word",/\s+/,!0))})},n.chars=function(t){return n.words(t).map(function(n){return n.chars?n:e(n,"char",n.words.reduce(function(n,t,e){return n.concat(r(t,"char",""))},[]))})},n}); \ No newline at end of file