I am formatting a Shakespearean script in HTML. Because Shakespeare wrote in meter, it is customary to indent lines that do not begin on the first beat of the meter, like so:
p.indent { padding-left: 100pt; }
<h4>HERMIA</h4>
<p>O me!</p>
<h5>[To Helena]</h5>
<p class="indent">You juggler, you cankerblossom,</p>
<p>You thief of love! What, have you come by night</p>
<p>And stol’n my love’s heart from him?</p>
<h4>HELENA</h4>
<p class="indent">Fine, i’ faith.</p>
<p>Have you no modesty, no maiden shame,</p>
<p>No touch of bashfulness? What, will you tear</p>
<p>Impatient answers from my gentle tongue?</p>
<p>Fie, fie, you counterfeit, you puppet, you!</p>
HERMIA
O me!
[To Helena]
You juggler, you cankerblossom,
You thief of love! What, have you come by night
And stol’n my love’s heart from him?HELENA
Fine, i’ faith.
Have you no modesty, no maiden shame,
No touch of bashfulness? What, will you tear
Impatient answers from my gentle tongue?
Fie, fie, you counterfeit, you puppet, you!
However, rather than indent by a fixed amount, it would be ideal to indent to the width of the prior line. That would produce an appearance closer to this:
HERMIA
O me!
[To Helena]
You juggler, you cankerblossom,
You thief of love! What, have you come by night
And stol’n my love’s heart from him?HELENA
Fine, i’ faith.
Have you no modesty, no maiden shame,
No touch of bashfulness? What, will you tear
Impatient answers from my gentle tongue?
Fie, fie, you counterfeit, you puppet, you!
In the desired solution, the amount of left-padding of each p.indent
element should bes equal to the width of the most recent prior p
element (which in general is not the most recent prior element, as h4
or h5
elements may intervene).
I assume I can’t do this in pure CSS, but I’ve been surprised about that before. If not, then simple JS?
2
Answers
At first, I thought I could just read the length of the words in the heading / but that’s not really the same if it’s uppercase or lowercase, and it isn’t a winning approach.
Are you sure you want to hand put those ‘.indent’ classes? What about just anything after a heading? The first paragraph after any heading? Either way the tools you’d use would be the same.
For each .indent paragraph, identify the nearest preceding sibling that is a heading ( to ) You can use .previousSibling https://developer.mozilla.org/en-US/docs/Web/API/Element/previousElementSibling — then to get the width of the actual font/text in the heading – you kinda need a span or some sub element that isn’t a block-level element (not full-width) / so, you can either put that in there when rendered – or add it with JS. Then you can check those with getBoundingClientRect() https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect — and then you can check that width and use that to set the indent of it’s sibling paragraph. I think that’s about as simple as you’re going to get. Alternatively, you could grab all the elements, and go down and use nextSibling and get the first paragraph after headings.
I doubt this is achievable with css alone.
Javascript to determine indents
It’s fairly straight forward to apply an indent. IE setting a
padding-left
value.(though this does not play nicely with line-breaks inside of
<p>
tags, if line-breaks are expected, you would prepend the line with the required amount of
s to apply the offset)To find the amount to pad, we need to know what the pairs of
<p>
tags are. Once we have all pairs collected we can figure out the position of last character and use that to indent the next line. (in case of line-breaks inside<p>
you might need the translate that position to an increment of
s)