When considering a solution for the issue at hand, it seems that the unconventional method discussed in this related question might be the only CSS-based approach available.
However, if exploring JavaScript as an alternative, here is a potential workaround I came up with:
The concept involves overlaying your text-containing element and the canvas
element. The actual text content remains within your element for selection purposes (since selecting canvas text isn't feasible), but is set to full transparency using rgba(0,0,0,0)
. This ensures visibility in older browsers like IE8 which lack RGBa
and canvas
support.
The idea is to replicate the text from your element onto the canvas using the same font attributes. Each letter drawn on the canvas aligns precisely with its counterpart in the visible text element.
Note that the canvas
does not accommodate multi-line text naturally. Accordingly, you'll need to segment the text into words and add them gradually, monitoring the line width continuously. If the line exceeds the max allowable width (extracted by analyzing the text element's computed width), write it onto the canvas sans the last word, reset the line with this leftover word, and shift the y-coordinate for next line placement accordingly.
Justification of the text poses a challenge in this scenario. Achievable, yet more intricate, involving detailed calculation of step widths for writing word by word instead of line by line.
Keep in mind that resizing the text container obliges clearing and redrawing the canvas post each adjustment.
Here's the sample code:
HTML:
<article>
<h1>Interacting Spiral Galaxies NGC 2207/ IC 2163</h1>
<em class='timestamp'>February 4, 2004 09:00 AM</em>
<section class='article-content' id='art-cntnt'>
<canvas id='c' class='c'></canvas>In the direction of <!--and so on-->
</section>
</article>
CSS:
html {
background: url(moving.jpg) 0 0;
background-size: 200%;
font: 100%/1.3 Verdana, sans-serif;
animation: ani 4s infinite linear;
}
article {
width: 50em; /* customize as needed ;) */
padding: .5em;
margin: 0 auto;
}
.article-content {
position: relative;
color: rgba(0,0,0,0);
/* append slash to verify overlap *
color: rgba(255,0,0,.5);/**/
}
.c {
position: absolute;
z-index: -1;
top: 0; left: 0;
}
@keyframes ani { to { background-position: 100% 0; } }
JavaScript:
var wrapText = function(ctxt, s, x, y, maxWidth, lineHeight) {
var words = s.split(' '), line = '',
testLine, metrics, testWidth, alpha = 1,
step = .8*maxWidth/ctxt.measureText(s).width;
for(var n = 0; n < words.length; n++) {
testLine = line + words[n] + ' ';
metrics = ctxt.measureText(testLine);
testWidth = metrics.width;
if(testWidth > maxWidth) {
ctxt.fillStyle = 'rgba(0,0,0,'+alpha+')';
alpha -= step;
ctxt.fillText(line, x, y);
line = words[n] + ' ';
y += lineHeight;
}
else line = testLine;
}
ctxt.fillStyle = 'rgba(0,0,0,'+alpha+')';
alpha -= step;
ctxt.fillText(line, x, y);
return y + lineHeight;
}
window.onload = function() {
var c = document.getElementById('c'),
ac = document.getElementById('art-cntnt'),
/* utilize currentStyle for IE9 */
styles = window.getComputedStyle(ac),
ctxt = c.getContext('2d'),
w = parseInt(styles.width.split('px')[0], 10),
h = parseInt(styles.height.split('px')[0], 10),
maxWidth = w,
lineHeight = parseInt(styles.lineHeight.split('px')[0], 10),
x = 0,
y = parseInt(styles.fontSize.split('px')[0], 10),
text = ac.innerHTML.split('</canvas>')[1];
c.width = w;
c.height = h;
ctxt.font = '1em Verdana, sans-serif';
wrapText(ctxt, text, x, y, maxWidth, lineHeight);
};