JSFiddle - React, Tailwind, and code Playground
HTML
<div><a href="#" id="fontUp" style="margin-right:10px">Font +</a><a href="#" id="fontDown">Font -</a></div>
<div id="column">
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. <img src="http://www.tomtom.com/lib/img/voices/Yoda.png" title="yoda" alt="yoda"/>It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<p>The change of name from <img src="http://www.avatarblast.com/avatars/cool/yoda.jpg" title="yoda" alt="yoda"/> LiveScript to JavaScript roughly coincided with Netscape adding support for Java technology in its Netscape Navigator web browser. The final choice of name caused confusion, giving the impression that the language was a spin-off of the Java programming language, and the choice has been characterized by many as a marketing ploy by Netscape to give JavaScript the cachet of what was then the hot new web-programming language. It has also been claimed that the language's name is the result of a co-marketing deal between Netscape and Sun, in exchange for Netscape bundling Sun's Java runtime with their then-dominant browser. Vivamus scelerisque ipsum ut justo. Pellentesque et ligula eu massa sagittis rutrum. In urna nibh, eleifend vel, suscipit ut, sagittis id, nunc.</p>
<p>Nam ut sapien sed pede pulvinar rutrum. Nunc eu elit sed augue aliquet tincidunt. Morbi rutrum. Vestibulum dui turpis, lobortis quis, euismod sed, consectetuer sit amet, nunc. Nam mi. Fusce at nisl eu tortor bibendum eleifend. Sed ac metus. Phasellus nec elit. Morbi tortor nulla,...
CSS
div#column {
-webkit-column-count:3;
-webkit-column-width:100px;
height:850px;
}
p {
margin:0;
clear:left;
font-size:15px;
text-align:justify;
}
img {
float:left;
-webkit-column-span:all; /* does not do what we want :-( */
}
JavaScript
var fontSize = 15;
// cannot store img.position().top or .left here because it is
// before the browser has re-flowed the columns, therefore the
// positions will be incorrect
var imageTops = new Array;
var imageLefts = new Array;
$('#fontUp').click(function() {
reflow(1);
});
$('#fontDown').click(function() {
reflow(-1);
});
function reflow(fontSizeStep) {
storeImagePositions();
var fontLimitReached = changeFont(fontSizeStep);
if (!fontLimitReached) {
moveImages();
}
return false;
}
function changeFont(step) {
fontSize += step;
var fontSizeLimitReached = true;
if (fontSize > 30) {
fontSize = 30;
} else if (fontSize < 15) {
fontSize = 15;
} else {
fontSizeLimitReached = false;
}
if (!fontSizeLimitReached) {
$('p').css({fontSize: fontSize + 'px'});
}
return fontSizeLimitReached;
}
// initialize store of img top and left positions
function storeImagePositions() {
if (imageTops.length == 0) { // only do it once
$('img').each(function() {
var imgPosition = $(this).position();
imageTops.push(imgPosition.top);
imageLefts.push(imgPosition.left);
});
}
}
function moveImages() {
// bye bye images
var images = $('img').detach();
// clear any existing marginTop added on the images
images.each(function() {
$(this).css('marginTop', 0);
});
// spanify paragraphs
$('#column > p').each(function() {
$(this).html('<span>' + $(this).html().replace(/\s\s+/g).replace(/(\s)/g,'</span>$1<span>') + '</span>');
});
var imageIndex = 0;
// iterate words, working out where we can move the img to in the flow and if
// we find a match, increment the index so that as we continue the each()
// the next image is evaluated for replacement
$('#column > p span').each(function() {
var wordPosition = $(this).position();
var wordLeft =...