View Single Post
Old 05-17-2020, 03:57 PM   #1
TheRealJohnAdams
Enthusiast
TheRealJohnAdams will blow your mind, man!TheRealJohnAdams will blow your mind, man!TheRealJohnAdams will blow your mind, man!TheRealJohnAdams will blow your mind, man!TheRealJohnAdams will blow your mind, man!TheRealJohnAdams will blow your mind, man!TheRealJohnAdams will blow your mind, man!TheRealJohnAdams will blow your mind, man!TheRealJohnAdams will blow your mind, man!TheRealJohnAdams will blow your mind, man!TheRealJohnAdams will blow your mind, man!
 
Posts: 42
Karma: 57668
Join Date: May 2020
Device: Kindle Oasis, Kobo Forma, Onyx Page
How to make listlike hanging indents for KFX (example code in post)

Hi all. I am making a prayer book. Many prayers have portions known as "versicle" and "response" (think call-and-response). Traditionally, they are designated with "V." and "R." to the left of the versicle or response text, like so.

I am referring to this as a "hanging indent," which may not be the correct term, because in word it is accomplished by setting a hanging indent, typing "V." or "R.", and pressing tab. I'm calling it "listlike" because we most often see it in numbered lists. For example:
  1. This item is to the right of a piece of text (in this case "1.") and has a flush left margin. This item is to the right of a piece of text (in this case "1.") and has a flush left margin. This item is to the right of a piece of text (in this case "1.") and has a flush left margin.

The trouble is that KFX does not support any of the features that I would ordinarily use to achieve this effect. I have spent a few hours with Sigil and Kindle Previewer trying to find a solution.

I've been using the following html:

Code:
<h1>Version A</h1>

  <div><p><span>V. </span>Text of Versicle. This should wrap and have a flush margin when it wraps to make everything nice and pretty and I'm really not sure why I keep typing except to make sure I have a large enough test paragraph.</p></div>


<h1>Version B</h1>

<div><span>V. </span><p>Text of Versicle. This should wrap and have a flush margin when it wraps to make everything nice and pretty and I'm really not sure why I keep typing except to make sure I have a large enough test paragraph.</p></div>


<h1>Version C</h1>

<div><span>V</span><p>Text of Versicle. This should wrap and have a flush margin when it wraps to make everything nice and pretty and I'm really not sure why I keep typing except to make sure I have a large enough test paragraph.</p></div>
Note that version A has the "V. " <span> inside the body <p>, whereas B and C have it outside. Version B and Version C differ in that Version B has "V. ", whereas C has "V" with no punctuation or spacing.

I've tried a lot of different approaches. The obvious one, using a custom list-style-type, doesn't work because KFX doesn't support the required property value.

Code:
/*Doesn't work because KFX doesn't support strings for list-style-type property.*/
p {
  display: list-item;
  list-style-type: "V. "
}
Another obvious one, which was meant to work with Version A, also fails because KFX does not support "display: inline-block". This CSS would have set up a normal hanging indent of 2em, and made the "V. " <span> 2em wide so it took up that whole indent.

Code:
span {
  width: 2em;
  display: inline-block;
}
p {
text-indent: -2em;
padding-left: 2em;
}
The least-kludgey solution is this:

Code:
div {
  margin-top: .5em;
  margin-bottom: .5em;
  position: relative;
}
span {
  display:block;
  position:relative;
  float: left;
  width: 1.25em;
}
p {
  display: block;
  position: relative;
  padding-left:2em;
  margin: 0;
}
My understanding is that on a device that handles CSS correctly, the foregoing code would achieve the desired result. It looks right in the Sigil preview. It looks almost right on Kindle, but unfortunately, this code creates a normal firstline indent with width equal to the width of the <span> (so, in this case, 1.25em). I don't understand why it would do that. I have tried forcing the <p> to ignore the <span>, using things like "position: absolute" and "position: relative," to no avail. I also tried and failed to set the <span>'s height to equal the height of the <p> element, which would give me a flush margin, to no avail. Weirdly, if I increase the padding-left property enough, for instance to "padding-left:4em," the firstline indent goes away. But 4em is a much larger left margin than I want.

After a lot of trial and error, I found a solution that works, but only with Version C.

Code:
div {
  margin-top: .5em;
  margin-bottom: .5em;
}
span {
  display:block;
  float: left;
  width: .001em;
  height: .001em;
}
p {
  text-indent:0;
  padding-left:2em;
  margin: 0;
}
If used with Version B, the "." wraps onto the next line, like so. And if the text in the <p> is only one line long, the "." that wraps will mess up the alignment of the following paragraph.

For several reasons, then, the solution I've found is not ideal. It feels very kludgey and has significant limitations compared to a more natural solution. But it is also the only solution that I have found that works on Kindle. Is there a better one?
TheRealJohnAdams is offline   Reply With Quote