How to count the lines of a <pre> poem using css? - css

I want to display Beowulf on my webpage, the full poem. My code so far:
<head>
<title>Beowulf</title>
<style type="text/css">
body {padding: 10% 25%;}
pre {font-family: "Times New Roman"; font-size: 100%;}
</style>
</head>
<body>
<h3>Beowulf</h3><br>
<pre>Now Beowulf bode in the burg of the Scyldings,
leader beloved, and long he ruled
in fame with all folk, since his father had gone
(...)
of furious flame. Nor far was that day
when father and son-in-law stood in feud
for warfare and hatred that woke again. (...)</pre>
</body>
Now how to get every fifth line numbered? I would like to position the numbers on the extreme edge of the right side.
I would appretiate if you tried to explain this issue to me as didatically as possible. I am a friend of simplicity and I would give preference to codes that shouldn't be bigger than the Beowulf poem itself (if you get the message!), so preferably css.
If javascrpit is the only way to get there, I would kindly ask you to formulate your answer in the most didactical way you can. My programming skills are "lower-intermediate" and unfortunately I didn't find any concrete information on the web, not even at w3schools. Thank you for your answers!

CSS styles elements or pseudo-elements, not text lines. So you need to modify your HTML or use JS.
For example, you can get the text, split it into lines, and wrap each one inside a list item of an ordered list.
The, you can use a CSS counter to associate each line with its number, :nth-child to select each 5n-th line, and a pseudo-element to insert the counter. To align the numbers properly, you can use CSS tables.
var old = document.getElementById('poem'),
poem = document.createElement('ol');
poem.id = 'poem';
old.textContent.split('\n').forEach(function(line) {
var li = document.createElement('li');
li.textContent = line;
poem.appendChild(li);
});
old.parentNode.replaceChild(poem, old);
body {padding: 10% 25%;}
#poem {
font-family: "Times New Roman";
display: table;
padding: 0;
counter-reset: line;
}
#poem > li {
display: table-row;
white-space: pre;
counter-increment: line;
}
#poem > li:nth-child(5n+1):after {
content: counter(line);
display: table-cell;
text-align: right;
color: #aaa;
cursor: default;
}
<h3>Beowulf</h3><br>
<pre id="poem">Now Beowulf bode in the burg of the Scyldings,
leader beloved, and long he ruled
in fame with all folk, since his father had gone
away from the world, till awoke an heir,
haughty Healfdene, who held through life,
sage and sturdy, the Scyldings glad.
Then, one after one, there woke to him,
to the chieftain of clansmen, children four:
Heorogar, then Hrothgar, then Halga brave;
and I heard that -- was -- 's queen,
the Heathoscylfing's helpmate dear.
To Hrothgar was given such glory of war,
such honor of combat, that all his kin
obeyed him gladly till great grew his band
of youthful comrades. It came in his mind
to bid his henchmen a hall uprear,
ia master mead-house, mightier far
than ever was seen by the sons of earth,
and within it, then, to old and young
he would all allot that the Lord had sent him,
save only the land and the lives of his men.
Wide, I heard, was the work commanded,
for many a tribe this mid-earth round,
to fashion the folkstead. It fell, as he ordered,
in rapid achievement that ready it stood there,
of halls the noblest: Heorot he named it
whose message had might in many a land.
Not reckless of promise, the rings he dealt,
treasure at banquet: there towered the hall,
high, gabled wide, the hot surge waiting
of furious flame. Nor far was that day
when father and son-in-law stood in feud
for warfare and hatred that woke again. (...)</pre>

Is this what you wanted? http://jsfiddle.net/g1xh9tjj/7/
JS:
$(function() {
var text = $('pre').text(),
textLines = text.split(/\n/g),
index = 1,
occurance = 5,
paragraphNumber = occurance,
output = '<div>1</div>';
textLines.forEach(function(entry, arrayIndex) {
if (arrayIndex > 0) {
output += '<br />';
}
if (index === occurance) {
output += '<div>'+paragraphNumber+'</div>'+entry;
index = 1;
paragraphNumber += occurance;
return;
} else {
output += entry;
}
index++;
});
$('pre').html(output);
});
CSS:
pre {
width: 400px;
}
pre div {
float: right;
}
Result will be:
1Now Beowulf bode in the burg of the Scyldings,
leader beloved, and long he ruled
in fame with all folk, since his father had gone
away from the world, till awoke an heir,
5haughty Healfdene, who held through life,
sage and sturdy, the Scyldings glad.
Then, one after one, there woke to him,
to the chieftain of clansmen, children four:
Heorogar, then Hrothgar, then Halga brave;
10and I heard that -- was -- 's queen,
the Heathoscylfing's helpmate dear.
To Hrothgar was given such glory of war,
such honor of combat, that all his kin
obeyed him gladly till great grew his band
15of youthful comrades. It came in his mind
to bid his henchmen a hall uprear,
ia master mead-house, mightier far
than ever was seen by the sons of earth,
and within it, then, to old and young
20he would all allot that the Lord had sent him,
save only the land and the lives of his men.
Wide, I heard, was the work commanded,
for many a tribe this mid-earth round,
to fashion the folkstead. It fell, as he ordered,
25in rapid achievement that ready it stood there,
of halls the noblest: Heorot he named it
whose message had might in many a land.
Not reckless of promise, the rings he dealt,
treasure at banquet: there towered the hall,
30high, gabled wide, the hot surge waiting
of furious flame. Nor far was that day
when father and son-in-law stood in feud
for warfare and hatred that woke again. (...)

There is no clean CSS solution, just approximate and a bit awkward hack for finite length text. Itʼs flaw is clearly visible: no automatic counter, just positioned generated content with static text:
body {padding: 10% 25%;}
pre {font-family: "Times New Roman"; font-size: 100%;}
div {
margin-left: -2em;
padding-left: 2em; /* …create space for numbers */
overflow: hidden; /* …and prevent them from leaking */
}
pre {
position: relative;
}
pre:before {
content: '\a\a\a\a 5\a\a\a\a 10\a\a\a\a 15\a\a\a\a 20'; /* and so on */
position: absolute;
top: 0;
left: -2em;
width: 2em;
text-align: right;
color: gold;
}
<div>
<pre>Now Beowulf bode in the burg of the Scyldings,
leader beloved, and long he ruled
in fame with all folk, since his father had gone
away from the world, till awoke an heir,
haughty Healfdene, who held through life,
sage and sturdy, the Scyldings glad.
Then, one after one, there woke to him,
to the chieftain of clansmen, children four:
Heorogar, then Hrothgar, then Halga brave;
and I heard that -- was -- 's queen,
the Heathoscylfing's helpmate dear.
To Hrothgar was given such glory of war,
such honor of combat, that all his kin
obeyed him gladly till great grew his band
of youthful comrades. It came in his mind (…)</pre></div>
I have put numbers left, because I overlooked sentence about "extreme edge of the right side" first.

Related

How can I change text for 60 days through scripting?

I'm kind of new at programming so bear with me because this is probably easy to solve but I just don't really have much practise.
I've been working on an automatic "daily tip" system, with tips each day for the first 3 months (60 days).
Basically a code that changes text every day for 60 days. After the 60 days, the idea I had was for the code to to reset and go back to the first tip, on the first day.
However, I can't seem to find a way to make the code place a different text when it gets back to sunday (0). It displays the first text again, instead of the second text I had planned.
I have no idea how to make it and have been stuck for 3 days thinking about this. I heard about these forums and decided to give it a go.
I don't know if I was clear, but if not, the idea is basically to:
if - Week1, sunday(0): Tecna: Need any guidance with our website? Visit the forums! They're the most practical way to get help from people just like you, as well as from the minimods! Plus, you get virtual coins for each message you post!
if - Week 2, sunday(0): Tecna: According to cyberpsychology, the nickname and avatar you chose and represent yourself with on the web can tell others a lot about you. So, choose carefully!
If you guys could find a way to make this work, I'd be very, very grateful! I have been browsing different topics related to this, but none attempted a text change if the week ends, resetting after 7 days. I want it to reset after 60.
function Horoscopo() {
var data = new Date();
var dia = data.getDay()
var mes = data.getMonth()
var diames = data.getDate()
// Weekly Tips
if (dia == 0) {
$("strong.tip").html("<span class='formalFont'>Why do you hear the sea in a seashell? Abandoned by the mollusks and other undersea animals, shells can be put up against your ear. The ambient noise around the shell will resonate inside the shell, creating a sound similar to crashing waves!</span>");
}
if (dia == 1) {
$("strong.tip").html("<span class='formalFont'>Need any guidance with our website? Visit the forums! They're the most practical way to get help from people just like you, as well as from the minimods! Plus, you get virtual coins for each message you post!</span>");
}
if (dia == 2) {
$("strong.tip").html("<span class='formalFont'>The forums are the best hangout spots to spend time with friends! Endless chats, tons of games, contests, stories... there's just so much fun! I don't even know where to begin!</span>");
}
if (dia == 3) {
$("strong.tip").html("<span class='formalFont'>Put your feet in the spotlight! I have two choices for you: round toe boots from the 60s, with a low heel or wedge -- or heels wrapped in soft legwarmers!</span>");
}
if (dia == 4) {
$("strong.tip").html("<span class='formalFont'>Vain Pirates? Not exactly! Pirates wore earrings because they believed piercing the ear could improve eyesight. It also helped them be recognized after death!</span>");
}
if (dia == 5) {
$("strong.tip").html("<span class='formalFont'>What's the largest city in the world? It's Tokyo, the capital of Japan with a staggering 35.7 million people! Second is New York, followed by Sao Paulo and Seoul!</span>");
}
if (dia == 6) {
$("strong.tip").html("<span class='formalFont'>The plants need plenty of water this season! Whatever you do, don't water them when the sun is high in the sky, that causes the leaves to burn! The ideal time is around sunset.</span>");
}
</script>
<body onload="Horoscopo();">
<div style="width:200px; float:left; padding-bottom:10px;">
<div style="padding-bottom:0px;">
<div style="background:url(../medias/images/Horoscope/totd_stella.png); width:207px; height:auto; background-repeat:no-repeat; background-color:#78cce4;">
<table style="border: 0px; cellpadding: 0px; cellspacing: 0px">
<tbody>
<tr>
<td>
<div class="menuBlackFont" style="text-align: left; color:#FFFFFF; padding-top: 5px; padding-left: 10px; padding-bottom: 120px;">
<span>Tip of the Day</span>
</div>
<div style="background:url(../medias/images/Horoscope/speech_bubble_top.png); width:200px; height:33px;">
</div>
<div style="background:url(../medias/images/Horoscope/speech_bubble_center.png);
width:200px; background-repeat:repeat-y;">
<div style="padding-left:15px; padding-right:15px;">
<strong class="tip"><span class="formalFont"></span></strong>
</div>
</div>
<div style="background:url(../medias/images/Horoscope/speech_bubble_bottom.png); width:200px; height:25px;"></div>
</td>
</tr>
</tbody>
</table>
</div>
<p></p>
</div>

What is the use of parent selector (&) alone as a selector? Is it bad practice to use such selectors?

After reading tutorial after tutorial regarding Less (LessCSS), I was just wondering how this & operator is supposed to be used. I know it's referring the parent element like:
div {
&.fullheight {
height: 100%;
}
}
// turns into
div.fullheight {
height: 100%;
}
But I often saw this:
div {
span {
& {
padding: 1em;
margin: 1em;
}
}
}
// turns into
div span {
padding: 1em;
margin: 1em;
}
Like when using ONLY the & operator inside of a class, it represents pretty much the parent element, but is doing this bad practise since you can have the same result when you would type like this:
div {
span {
padding: 1em;
margin: 1em;
}
}
Both work, so is it bad/good practise or are each of them maybe used in different situations?
For extra clarity, below is the link to an answer where I first saw that you can write & only in a class without anything else.
LESSCSS - use calculation and return value - First post by ScottS, fourth solution in his post.
Generally writing something like below would be considered as bad practice because the & there is just redundant and does no value add at all. It just outputs the entire parent selector div span.
div {
span {
& {
padding: 1em;
margin: 1em;
}
}
}
So, you should avoid writing such selectors which use only the & (parent selector).
The other example to which you have linked is an interesting case which I would term as an educated hack to get around the variable scoping and lazy loading concepts in Less.
Assume that the same code was written without the parent selectors (like below).
#unit:em;
#basevalue:1;
#val: 1;
#setUnit: unit(#basevalue*#val, #unit);
.someAwesomeClass {
#val: .2;
padding: #setUnit;
#val: .1;
margin: #setUnit;
}
Here the #val variable is declared twice within the same block. Since Less does lazy loading of the variables, they need not be declared before being used (and) if the same variable is declared twice or more within the same scope, the last declaration would win.
When defining a variable twice, the last definition of the variable is used, searching from the current scope upwards. This is similar to CSS itself where the last property inside a definition is used to determine the value.
So, the compiled CSS output would have the value as 0.1em for both padding and margin whereas the expectation is for padding to be 0.2em and for margin to be 0.1em.
To overcome this, the author of that answer has introduced two namespaces (with no name) and has thus restricted the scoping issue. The variable defined within each nested block becomes local to that block only and so will be considered as two separate variables.
#unit:em;
#basevalue:1;
#val: 1;
#setUnit: unit(#basevalue*#val, #unit);
.someAwesomeClass {
&{
#val: .2; /* this declaration applies only within this nest */
padding: #setUnit;
}
&{
#val: .1; /* this declaration applies only within this nest */
margin: #setUnit;
}
}
As indicated by the author of that answer (in the first line), it was a workaround because there was no way to create a true function with Less.
But starting with Less v2, we can define our own custom functions in Less and use them as described in this answer by Bass Jobsen. The ability to write such custom functions should eliminate the need to write such hacks.
You can also refer to the comment by seven-phases-max in the same thread for a solution without the need for such hacks.
Bottomline is that usage of & alone as a selector is a bad practice. The solution in the linked answer was a hack which was useful in earlier versions of Less. It is still useful but there are alternate options and so & alone as a selector should be used only in extremely rare circumstances where none of the other option work.

Getting speechmarks to follow the quote

I'm trying to get speechmarks to appear at the start and end of a quote.
Here's a link to the code (without images):
http://jsfiddle.net/tomperkins/cGDUc/
You can see the grey blocks (I've replaced the speechmark images with grey blocks in this case) I have at the start and end of the quote. The trouble is the closing quote sits on the right hand side.
I'd like the closing speechmark (or grey block) to sit straight after the quote. In this example it would come straight after '...expectation'
All help and tips appreciated!
Thanks in advance,
Tom Perkins
HTML
<h2>On all levels they exceed our expectation</h2>
CSS
h2:before {
content: "“";
}
h2:after {
content: "”";
}
Alternately, you can use images:
h2:before {
content: url(imgsrc);
}
h2:after {
content: url(imgsrc);
}
Highly simplified example: http://jsfiddle.net/cGDUc/14/

Is it okay to hide (display: none;) the definition term (<dt>) in a definition list (<dl>)?

So I have a list of menu items and I'm trying to figure out if I should use spans with class attributes or definition lists for the characteristics of each item. Here are the two options I am considering:
Option 1)
// HAML Markup
%article.menu-item
%span.name
Cereal
%span.price
4.00
%span.description
We carry Cap'n Crunch, Frooty Loops and Count Chocula. Milk included.
// Styling
article.menu-item {
.price:before { content: "$"; }
}
Option 2)
// HAML Markup
%article.menu-item
%dl
%dt
Item
%dd
Cereal
%dt
Price
%dd
4.00
%dt
Description
%dd
We carry Cap'n Crunch, Frooty Loops and Count Chocula. Milk included.
// Styling
article.menu-item {
.price:before { content: "$"; }
dt { display: none; }
}
I'm currently using option 1, but for some reason option two appears to me to be semantically richer since it defines the product. Which option should I go with and why?
If you're going to go with the second you shouldn't use display: none;. You'd be better off positioning the text off screen so screen readers can still get at it.
dt {
position: absolute;
left: -9999px;
top: -9999px;
}
I say go with the semantically richer code (2) and hide the dt. maybe be more specific about which dts you're hiding: article.menu-item.dt {display: none }. it will make the text more readable, and avoid span and div soup in your code.

Speed of CSS

This is just a question to help me understand CSS rendering better.
Lets say we have a million lines of this.
<div class="first">
<div class="second">
<span class="third">Hello World</span>
</div>
</div>
Which would be the fastest way to change the font of Hello World to red?
.third { color: red; }
div.third { color: red; }
div.second div.third { color: red; }
div.first div.second div.third { color: red; }
Also, what if there was at tag in the middle that had a unique id of "foo". Which one of the CSS methods above would be the fastest.
I know why these methods are used etc, im just trying to grasp better the rendering technique of the browsers and i have no idea how to make a test that times it.
UPDATE:
Nice answer Gumbo.
From the looks of it then it would be quicker in a regular site to do the full definition of a tag. Since it finds the parents and narrows the search for every parent found.
That could be bad in the sense you'd have a pretty large CSS file though.
Two things to remember:
This is going to depend on the CSS parser /rendering engine: i.e. it varies from browser to browser.
CSS is really, really, really fast anyway, even at it's slowest the human watching shouldn't notice
In general the simplest things are the fastest (as Gumbo nicely illustrates), but because we're already in such a fast environment don't think that you should sacrifice clarity and appropriate scoping (low specificity is like making everything public sort of). Just avoid * wherever you can :)
According to the Mozilla Developer Center, the most efficient selector for this case would be simply .third
In fact, they state there, explicitly, "Don't qualify Class Rules with tag names". In general, for greatest efficiency, use the simplest selector that matches. That's why .third beats span.third beats .second span.third, etc.
I can't tell what Gumbo's conclusion is meant to be, but Ólafur appears to be drawing the conclusion from it that using more stuff in the selector makes the CSS parsing more efficient, when, in fact, it's just the opposite (assuming other CSS parsing engines work similarly to Mozilla's.)
You have to understand how the selectors are being processed:
.third: get every element and check for a class name third,
div.third: get every DIV element and check for a class name third,
div.second div.third: get every DIV element, check for a class name second, run through these and find every decendant DIV element and check for a class name third,
div.first div.second div.third: get every DIV element, check for a class name first, run through these and find every decendant DIV element, check for a class name second, run through these and finally check for a class name third.
Edit   I have to admit, that the procedure above would be the naive approach and is not generally efficient. In fact, there are implementations that go from bottom to top instead from top to bottom:
div.first div.second div.third: get every DIV element, check for a class name third, get the first DIV ancestor that has a class name second, get the first DIV ancestor that has a class name first.
I would say this depends on the browser. Nothing beats an experiment, in this case a simple JavaScript would probably do.
Update: I meant to do something like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>CSS Speed Test</title>
<style type="text/css">
.first { color: red; }
</style>
<script type="text/javascript">
window.onload = function()
{
var container = document.getElementById("container");
var totalTime = 0;
var passes = 100;
for (var p=1; p<=passes; p++)
{
var startTime = new Date();
for (var i=0; i<1000; i++)
{
var outerDiv = document.createElement("div");
var innerDiv = document.createElement("div");
var span = document.createElement("span");
outerDiv.className = "first";
innerDiv.className = "second";
span.appendChild(document.createTextNode("Hello, world!"));
outerDiv.appendChild(innerDiv);
innerDiv.appendChild(span);
container.appendChild(outerDiv);
}
var endTime = new Date();
totalTime += (endTime - startTime);
}
alert("Average time: " + totalTime/passes);
}
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
…but the time differences caused by different selectors appear to be too small to measure, just as annakata said.

Resources