Introduction

Chapters

Strategy Resources Structure Style Layout Composition Production Infrastructure

Appendices

E-Book Formats Explained Image Formats Explained Advanced Styling & Layout Better Photography Working with SVG Unicode and All That Troubleshooting

Supplementary

Revenue Calculator Contact
Copyright © Dodeca Technologies Ltd. 2016

Troubleshooting

Everybody who works with HTML and CSS, even seasoned experts, will encounter problems at times, where something that looks like it really should work simply does not. Resolution of such problems can come at any time; you can realise your mistake in just a few seconds, but the thornier problems that can arise with more-complex compositions can take considerably longer.

This appendix lays out the most common coding mistakes that people, especially novices, make from time to time, and offers some advice on how to diagnose the cause of trouble when nothing else has worked. A validator will trap many of the examples given below, which underscores the value of performing validation frequently and​regularly during the production process, but it is worth being aware of the problems that can occur, if only to make your validator's error report a little more enlightening. More importantly, some validators miss problems that others catch, and there are classes of problem (such as CSS selector-conflicts – see below) that no validator can detect.

Code Layout Matters

This guide makes a number of references to the importance of layout when working with code; that is, the layout of the code itself, not the effect that code has on the layout of a book's content when rendered by a user agent.

Many people wish to go nowhere near code and its creation, which is one of the motivations (laziness being the other) that lies behind the desire on the part of some for​‘something for nothing’ when it comes to e-book and web site production. Understandably, that aversion must stem in part from the fact that 99.9% of the code examples that abound on the web and in software books are laid out very poorly indeed. Such poor layout obfuscates the symbology at hand, making it much harder to understand what the code is saying.

It is unsurprising therefore that many of the uninitiated look at what is, after all, a jumbled mess, and vow to go nowhere near it. For them, it all looks just too complex, difficult and, frankly, scary. Such people have a point, as it looks like an abominable mess to the enlightened professional too.

As a demonstration, consider the following example (and note that it does help to have assimilated first the​material in the early part of Chapter Three, Structure). It is defective, but that is not apparent immediately, and while the problem and its resolution are very simple, the lack of visual structure hampers detection of the flaw. To prove this to yourself, try now to find the problem, and time yourself as you do – how long does it take you to scan the code and locate the error?

<body>
<div><p>Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo
consequat.</p><p> Duis aute irure
dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur
sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id
est laborum.</p></body>

Whether or not you found the problem, consider now the next example, which re-presents the code above but with good layout.

<body>
   <div>
      <p>
      Lorem ipsum dolor sit amet, consectetur
      adipiscing elit, sed do eiusmod tempor
      incididunt ut labore et dolore magna aliqua.
      Ut enim ad minim veniam, quis nostrud
      exercitation ullamco laboris nisi ut aliquip
      ex ea commodo consequat.
      </p>

      <p>
      Duis aute irure dolor in reprehenderit in
      voluptate velit esse cillum dolore eu fugiat
      nulla pariatur. Excepteur sint occaecat
      cupidatat non proident, sunt in culpa qui
      officia deserunt mollit anim id est laborum.
      </p>

</body>

If you understand the basic principles of HTML, the problem is now visible immediately and is self-evident; the starting <div> is missing its end </div> tag, just before the </body>, and the rigorous layout makes that error starkly obvious.

Note here that many, lauded pundits included, would put the end tags for the paragraph elements on the end of the final line of each paragraph. Some, given this, would also put the missing </div> tag on the end of that too, to yield:

<p>
Duis aute irure

...

id est laborum.</p></div>

This is foolish practice, however, because it ignores the great value of consistency. That is, if the code for a start-tag begins at, say the fourth column, any corresponding end-tag should also begin on the fourth column further down. This is because failure of that symmetry yields ready diagnosis when considering the second version of the example above.

These principles hold in CSS coding too. Consider the next two examples:

div.ChapterToC a {
line-height: 2.0;
   font-size:80%;
    white-space:nowrap;
 overflow;hidden;
text-overflow:ellipsis; border-bottom :none;
   display:block; }
div.ChapterToC a
   {
   line-height   : 2.0;
   font-size     : 80%;
   white-space   : nowrap;
   overflow      ; hidden;
   text-overflow : ellipsis;

   border-bottom : none;

   display       : block;

   }

As with the previous demonstration, this example shows two syntactically and thus semantically identical CSS definitions, but the layout in the first is the coding equivalent of a municipal rubbish tip, which makes the defect it harbours hard to locate. Conversely, the second, a paragon of good layout, throws what is a rather subtle problem into sharp relief – a semi-colon rather than a colon separates ‘overflow’ and ‘hidden’. You need only read down the columns – any fool can do that – you do not even need to know CSS to see there is an inconsistency.

These simple demonstrations show that adding formal, consistent, reasoned structure to code adds a wealth of contextual information, which assists greatly in diagnosing defects. Moreover, such valuable clarity and comprehension comes at essentially zero cost. You do not need fancy tools, yet another language, plug-ins for your browser nor a PhD in Computer Science. All it requires is some judicious and regular spacing, of which even the greenest neophyte is capable. Indeed, Chapter Six, Composition, makes the​point that formal indentation such as you see in the favourable examples here is an instance of ‘Negative Space’.

Sadly, a great many software professionals fail to see this point naturally. It seems that the majority, despite the fact that they are applied logicians, do not have a tidy mind, and so do not perceive an obvious coding shambles for what it is: visual garbage. It seems also that the majority discount the self-evident fact that, while we are capable problem solvers, we are also fallible. That is, no one can avoid making mistakes completely, which, in an endeavour that requires exactitude, can cause great problems. It follows that embracing that fact by facilitating problem resolution in anticipation of making those mistakes can only help matters. An ounce of prevention is worth a pound of cure.

Good layout comes for free but delivers priceless benefits, and so you should use exactly same layout as you see in the examples throughout this guide. This will guard against situations where your code does not do what you intend, but where the reason for the failure is unapparent simply from looking at it. Take pride in your coding – a thoughtfully laid-out piece of code can be a thing of great beauty, however strange that may sound to you; walk towards that idea, not away from it.

Despite these compelling arguments and sound advice, however, you might argue still that it is tedious and time-consuming to go through a tract of code, indenting it properly, lining things up, giving it room to breathe and exploiting symmetry, but that position is hardly credible. The putative tedium that good layout entails lies far from the very real tedium of staring at a problem for hours, being unable to see the source of the trouble, all because you were too lazy to take pride in your work. If you really do cleave to the ‘tedium’ objection, just stop arguing and lay out your code in the same fashion as the examples in this guide, as failure in this respect will leave you with no one but yourself to blame when problems gather round you.

Finally, and if, given that, you are still in fighting mood, and wish to try some absurd appeal to authority, consider the following entirely factual exchange between an entirely real tutor and an entirely real and pig-headed tutee (with an appropriate name change):

Tutor:

“Look, if you had done it like I suggested then I, never mind you, might be able to actually see what you are trying to do.”

Tutee:

“But this is the way that Big Name does it in his book.”

Tutor:

“Yes, you are right, that is exactly how Big Name does it. Now consider this: Big Name is wrong.”

Tutee:

“But Big Name is popular.”

Tutor:

“So was Hitler.”

Invalid Comments

It is possible to mess things up royally simply by emplacing invalid​comments in your code, and the following three points enumerate the issues of which you should be aware:

1.

Comment Syntax Differs. HTML comments take a different form to comments in CSS. Consider the next two examples:

<p>

/*
This comment is invalid, it
uses CSS syntax in HTML code.
*/

Lorem ipsum dolor...

</p>
p
   {
   <!--
   This comment is invalid, it
   uses HTML syntax in CSS code.
   -->

   color : FF0000;

   }

2.

Comment Syntax Matters. You must use exactly the right symbols when coding a comment. All the putative comments in the next two examples (HTML and CSS respectively) are illegal:

 !-- No chevron in leading delimiter                   -->
<--  No exclamation mark in leading delimiter          -->
<!-  Missing dash in leading delimiter                 -->
< !- Extra space in leading delimiter                  -->

<!-- No chevron in trailing delimiter                  --
<!-- Missing dash in trailing delimiter                 ->
<!-- Extra space in trailing delimiter                 -- >

     No start delimiter                                -->
<!-- No end delimiter

<!-- -- Double dash forms part of comment              -->
/    No asterisk in leading delimiter                  */
 *   No slash in leading delimiter                     */
*/   Mal-ordered slash/asterisk in leading delimiter   */

/*   No asterisk in trailing delimiter                 */
/*   No slash in trailing delimiter                    *
/*   Mal-ordered slash/asterisk in trailing delimiter  /*

     No start delimiter                                */
/*   No end delimiter

3.

No Nesting. You cannot nest comments in HTML and CSS, as the next two examples show:

<!--

   <!--
   Invalid, you cannot nest one
   HTML comment within another
   -->

-->        
/*

   /*
   Invalid, you cannot nest one
   CSS comment within another
   */

*/             

The problems that nested comments engender can be rather hard to diagnose initially, so always beware of comments that you have nested inadvertently.

Case Sensitivity

Another common source of trouble is failure to observe case sensitivity. HTML is not case sensitive, which is to say that <P> is the equivalent of <p> in that they both signify the start tag for a paragraph element. However, there was considerable debate some years ago over the convention that developers should follow with tags in HTML – should we all adopt lower-case or upper-case tag and attribute names?

Right or wrong (probably wrong, because all-uppercase keywords gives clear and valuable contrast between mark-up and content), the consensus came down on the lower-case side of the debate, so, even though case is immaterial to user agents, it is better to follow established convention, and use only lower-case tag and attribute names. This will not resolve syntactic problems directly, but deviation from convention will create a degree of impedance for you when comparing your upper-case HTML with other people's lower-case code. It will also create impedance if you need to show your code to someone else in an attempt to overcome some impasse, so do make things a little easier for yourself and others (potentially) by using lower-case throughout when coding HTML symbols.

In contrast to HTML, however, CSS is case sensitive. That is, you must use only lower-case letters when coding CSS keywords, and any variance here will cause the user agent to ignore a given expression. So, if you are a novice, faced with a seemingly intractable defect, go through all your CSS code first, checking for upper-case keywords.

Note that you should also observe case sensitivity in any filenames that you specify in your HTML and CSS. If, for example, an image's filename is ‘MyImage.png’ you must never cite ‘myimage.png’ (or any other variant) in HTML-attribute values and relevant CSS property values. It is true that this will make no difference on Windows machines because the Windows file system is case insensitive, but despite this, and even if e-readers do not enforce case sensitivity, you should always observe it yourself, as making that decision precludes the issue from ever being a source of trouble thereafter.

Case sensistivity can also be a problem with links. The underlying reason for this is that the Windows file-system (the drives and directories stuff) is not case sensitive, and this means that the following are equivalent when the file in question comes from a Windows machine:

<a href = "SomeChapter.htm"></a>
<a href = "Somechapter.htm"></a>

That is, a click on either of the links will take you to the file in question (assuming it exists), irrespective of whether the ‘Chapter’ component possesses a capital or lower-case ‘C’. However, validators are case sensitive, and so, when you validate an EPUB that contains such code, the validator will tell you that one of the link targets does not exist.

This can cause sublime frustration when you find yourself staring at the listing of your book contents in Sigil or Calibre, being unable to fathom the error because you can see clearly that a file called ‘SomeChapter.htm’ (or ‘Somechapter.htm’) really is present. It follows that a welcome addition to the various validators that are available would be a mechanism that, on detection of a broken link, would check for a target that is the same except for capitalisation differences. That mechanism could then emit the following entirely helpful message:

A link pointing to 'Somechapter.htm' exists where there is no file by that name. However, a file called 'SomeChapter.htm' does exist, should the link in question point to that instead?

Statement Malformation

Another very common source of trouble is statement and expression malformation – misspelling a keyword; omitting a mandatory bracket; mixing single and double quotes when coding values as strings of characters; examples abound.

Remember that, in HTML, a tag must start with a ‘less-than’ symbol (‘chevron’ or ‘angle bracket’), it must contain at least one alphabetic character, and it must end with a greater-than symbol. Moreover, an element in HTML consists of a start tag, an end tag, and any content that those tags enclose. Alternatively, an element can be ‘self closing’ (a so-called ‘empty’ element), in that it consists of just a start tag, but that tag must carry a trailing slash.

For example, the following are all malformed elements:

 p> ... </p>   Start tag is missing the leading chevron
<p  ... </p>   Start tag is missing the trailing chevron
<>  ... </p>   Start tag is missing the element name
    ... </p>   Start tag is missing

<p> ...  <p>   End tag is missing the leading slash
<p> ...  /p>   End tag is missing the leading bracket
<p> ...  </p   End tag is missing the trailing slash
<p> ...  <>    End tag is missing the element name
<p> ...  <//p> End tag has two slashes

<br>           Self-closing element, trailing slash missing

Similarly, and given that an attribute forms part of the start tag for an element, malformation of elements can occur because of malformed attributes. That is, the following are all incorrect:

<img src  =  Images/MyImage.png'/> Missing leading quote
<img src  = 'Images/MyImage.png/>  Missing end quote
<img src  = 'Images/MyImage.png"/> Leading single-quote, trailing double-quote

<div> ... </div class = "Section">    Attribute in end tag

Remember also that you must observe element-nesting rules fully. That is, improper nesting is also a form of element malformation, and can thus be a source of trouble. As a demonstration, the tags in the following example are well-formed, but the nesting is entirely incorrect:

<p>
Lorem ipsum dolor sit amet, <b>consectetur
adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
<p>
</b>

Here the code states that a <b> element starts mid-way through a piece of content, but its closing tag comes after the closing tag for the paragraph element in which it is supposed to be nested.

Malformation can also occur in CSS, and none of the definitions in the following example are legal:

p    { color       : #FF0000;         Missing end brace
p      color       : #FF0000;      }  Missing start brace

p    { color         #FF0000;      }  Missing colon
p    { color       ; #FF0000;      }  Semi-colon between keyword and value

p    [ color       : #FF0000;      ]  Square rather than curly brackets
p    ( color       : #FF0000;      )  Round rather than curly brackets

p    { color       : #FF000O;      }  Capital 'O' instead of zero

p    { font-family :  sans serif;  }  No quotes around value
p    { font-family : 'sans serif;  }  Missing trailing quote
p    { font-family :  sans serif'; }  Missing leading quote
p    { font-family : "sans serif'; }  Mixed single and double quotes

p    { width       : 80 %;         }  Space between value and percent symbol

p
div  { ...                         }  Missing comma

p,
div, { ...                         }  Illegal second comma

p
   {
   color  : #FF0000                   Missing semi-colon (invalidates margin rule)
   margin : 10%;
   }

p
   {
   background-image : url ('...');    Space between 'url' and leading parenthesis
   }

The inventiveness that some novices exhibit with such syntax when doing it incorrectly can be genuinely surprising – the ingenuity of the human mind when getting the wrong end of the coding stick is apparently boundless. Indeed, even when told subsequently and repeatedly to ‘code it as you see it in the example’ some people will still insist on using, for example, an arbitrary choice of brackets, yet none of the relevant standards state:

You must use brackets to delimit things, but it is up to you as to which type you use (square, rounded, curly or angle), because, hey, it's computers, and they know what you mean.

That is, when the CSS standard states that definitions are delimited by braces then it is braces all the way, whether you like it or not. Some people rail against this, seeing it as insufferably pedantic precision, realising not that such exactitude is friend not foe, as it means that you know exactly where you stand with a given construction.

Another area where malformation can bite is that of entity references. As Chapter Three, Structure, shows, you can use numbers to indicate characters that do not exist on your keyboard, and the following lists the problems that can arise (where the​codepoint cited corresponds to an en dash):

  #8211;  Missing ampersand
  &8211;  Missing hash
   8211;  Missing ampersand and hash
& #8211;  Space between ampersand and hash
&# 8211;  Space between hash and codepoint
 &#8211   Missing semi-colon
 &#8211 ; Space between codepoint and trailing semi-colon

Content-Model Transgression

In HTML, the set of elements that may be children of another element type is called that element's ‘content model’, and the HTML standard prescribes the content model for each element type precisely. It follows that a problem area into which it is easy to wander concerns placing an element within another where the standard does not allow it.

Usually, web browsers are very forgiving when a given page transgresses the rules, but that does not mean that such defects are immaterial. As noted in Chapter Two, Resources, some retailers​demand that all books submitted for sale be completely valid. If your deliverable is not valid those retailers will reject it, but it may also cause problems with the CSS that you apply to your content. That is, the CSS definitions you apply may not work as you expect.

Happily, a validator will catch content-model transgressions, such as the one given in the following example, where an unordered list is nested within a paragraph element, which the standard proscribes:

<p>
   <ul>
      <li>List Item</li>
   </ul>
</p>

Unhappily, however, this introduces a new problem in that, rather than emitting a genuinely useful error notification like:

List element nested illegally within a paragraph element.

…or suchlike, it is likely to say:

No p element in scope but a p end tag seen.

This kind of thing is frustrating for the uninitiated and the professional alike, as not only does it fail to identify the real problem, it misleads you into thinking that something that is quite unrelated (and correct) is amiss.

Experienced developers become utterly inured to this phenomenon, as they learn after a while to treat the wording of an error message with a degree of scepticism. The same holds therefore for you, in that you should always search your code at and above the point indicated by a validator, while keeping the apparent meaning of the error message you received at arm's length.

If you do find yourself falling foul of content-model problems, try to avoid complex nesting structures (with the exception of tables, which will be unnecessary for the majority of all e-books). That is, try to keep to a relatively ‘flat’ structure with your HTML, and avoid deep element hierarchies.

Illegal Expressions

You cannot invent your own tags and attribute names in HTML. More accurately, you can, but no user agent will recognise them, and a common problem here is simply misspelling a keyword. For example:

<para>...</para>                        There is no 'para' element in HTML
<img srce = 'Images/MyImage.png'/>   <img> elements do not allow 'srce' attributes
para { color  : #FF0000; }              No such element in HTML as 'para'
p    { colour : #FF0000; }              No such keyword as 'colour' in CSS

Resource Problems

When including images and external CSS files in your HTML, the resource in question must exist, and you must identify it correctly too. That is, if you are having problems with such resources (say, an image that fails to appear where it should), check first to ensure that the name of the file in question is stated correctly within the code in question, then check that the path is correct too (the bit that tells the user agent where to find the resource).

For example, assume that you have an image called ‘MyImage.png’ that resides in a sibling sub-directory to the one in which the HTML files reside. In other words, given the directory structure depicted in the graphic here, assume that a given HTML file exists in Text, and that the image resides in Images, and then consider the elements expressed in the next example (which would reside in the HTML), all of which fail to locate the image file:

<img src =         'MyImage.png'/> Implies the image resides in
                                   the Text directory

<img src =  'Images/MyImage.png'/> Implies the image resides in
                                   a sub-directory of Text

<img src = '/Images/MyImage.png'/> Implies the image resides in
                                   a sub-directory of the root directory

In fact, the correct identifier is ‘../Images/MyImage.png’, as this says in effect:

Starting from the parent directory of this file's directory [the two dots], dip down [the first slash] into the Images directory where you will find MyImage.png.

Confusing Inconsistencies

Sadly, HTML was ill thought through in its inception, and thus a few silly inconsistencies remain with us. Given this, and if you have run into difficulties, check the following list against your code.

1.

To emplace chapter-specific CSS definitions in a given piece of HTML, use the <style> element, but to import an external stylesheet file, we use a <link> element. Do not use the one when you mean the other.

2.

You must use ‘src’ in <img> elements to indicate the location of a given image file, whereas you must use ‘href’ in <link> and <a> elements to refer to external files. To compound the schizophrenia, you should use the attribute ‘data’ to identify the resource when using an <object> element.

3.

The element that links to another chapter or location within a given chapter is an anchor or <a> element, not a <link>, which it should be and which is blindingly obvious to even the neophyte.

The fact is that, in an ideal world, a <link> element would represent the concept of a user-visible link to something else, and a ‘url’ attribute would identify the target.

Selector Conflicts

It is possible to apply two or more different CSS definitions to the same HTML element using different selectors. This can be a source of exquisite confusion, as it can be difficult sometimes to see why a given definition is not affecting the rendering of a given element in the way that you expect. Consider the following example:

p           { text-indent : 1em; }
*.FirstPara { text-indent : 2em; }
#Para_1     { text-indent : 3em; }

Here, three separate definitions define three different degrees of indentation for the first line of a paragraph. The first applies to all paragraphs, the second applies to all paragraphs that possess a class attribute value of ‘FirstPara’ (if any exist), and the third applies to the one paragraph in a given HTML file that possesses an id attribute-value of ‘Para_1’ (if it exists).

If you apply the same style property with a different value to the same element, one rule must prevail over the other, and so in the following situation:

<p class = 'FirstPara' id = 'Para_1'> ... </p>

…the user agent will apply a set of ranking rules in order to resolve the conflict. In this case, an element's class attribute (if it exists) takes precedence over the element's type, and its id (if it exists) trumps both class and element-type. This means that the paragraph in the code fragment above will have a first-line indent of three ems, and this weighting system is called ‘the cascade’ and is the​meaning of the ‘C’ in ‘CSS’.

Note that other, more-subtle types of conflict than this example can arise when using descendant selectors (which Appendix​C, Advanced Styling & Layout explores), and another point of conflict lies between external stylesheet files and CSS code that appears in the <head> element of a given chapter file. That is, intra-chapter definitions carry more weight than imported definitions, so do be careful if you start getting adventurous, as no validator will trap a selector conflict for you.

To reprise a point that Chapter Four, Style,​makes, note also that the !important directive will veto whatever the cascading rules say about a given selector conflict, and will force application of the rule in question.

Thankfully, however, problems that stem from selector conflicts are unlikely to arise in any CSS that you create for your book. Such conflicts are relatively rare in web site development, where the CSS employed is usually far more complex than in e-books, and so the simpler selectors that the majority of e-books employ are even less likely to cause trouble.

However, if you do run into difficulties, it will be likely that you have taken an unnecessarily complex approach with your styling and layout. This means that the conflict is likely to disappear if you re-factor your CSS-related code so that it does the same thing with simpler expressions (a generally applicable point that is reiterated below); and do note here that tracing the cause of such conflict is one point where the debugging facilities in modern web browsers prove truly invaluable.

This underscores once again the value of taking the three-stage approach to producing your book (as​advocated in Chapter One), where you write the book in a word processor, and then develop and test the HTML/CSS version using a text editor and a browser before importing it into an EPUB editor such as Calibre or Sigil.

Incorrect Reference Material

One particularly galling source of difficulty is incorrect or inaccurate documentation and reference materials. That is, on encountering a problem, you can spend an entire afternoon searching for the definitive word on a given feature, but find only conflicting assertions on different web sites that leave you none the wiser. It is true that the Internet delivered to anyone with a computer and a network link the ability to publish arbitrary material, but that came at the cost of a critical factor – curation.

An important example here, which Chapter Three, Structure​notes, is that Amazon's documentation states currently that the KF8 file format supports the <object> and <embed> HTML elements. In principle, these allow the embedding of audio and video content within a book, and the incorporation of SVG and other image types (as an alternative to using an <img> element). In fact, neither of these elements work. Moreover, Amazon's documentation states that you should use the src attribute to stipulate the identity of the resource in question when using <object> elements, yet the correct attribute is ‘data’.

The only solution here is to do as much research as you can; to maintain a critical eye; to try to balance one assertion against another, and to experiment with as many permutations of a given technique, approach or piece of syntax until you finally burrow down to the truth.

Buggy Implementations

Sometimes your problem lies not in your code but in a defective implementation of the software that sits between your content and the human reader, and these situations can be most dispiriting. Indeed, this guide notes a number of bugs that Kindles exhibit (some EPUB e-reader applications have their problems too), including the:

Pre-element-wraparound bug
Float bug
Overflow/border-radius bug
Page-specific embedded fonts bug

If you do hit a particularly odd or stubborn problem, and you are sure that your understanding is correct (always double-check), the important issue is to determine whether the problem really does stem from a buggy implementation. To do this, you should try the code in question on an equivalent that supports the same functionality.

For example, if you cannot get something to work when developing your book's formatting using a web browser initially (as this guide advises), and you suspect a bug in the browser itself (something that is very rare), try the same code in another browser. Note that this means, for example, Firefox and/or Opera instead of Chrome, rather than an instance of, say, Chrome running on a different machine.

Note too that this underscores the rationale behind production-stage​Nine, Test in E-Readers (note plural, not singular), that Chapter Seven details. You need to ensure that your e-book stands a good chance of appearing as it should to all people, irrespective of the devices they use, because virtually all non-trivial software systems harbour defects, and the nature of such defects varies from system to system.

A final point in this section, on a problem that does not relate to software defects as such, but which presents a serious obstacle, is that Amazon's Look Inside viewer does not support SVG images or custom typefaces (as​mentioned in Chapter Three, Structure). To compound this, it does not honour CSS rules, which means that the first ten percent of a book that is available via the Look Inside feature will not be subject to the styling and layout rules that the book defines. These deficiencies could cause that first ten percent to look decidedly sub-standard, which could be a serious disincentive to potential purchasers.

Chapter Three gives (less than desirable) fixes for the SVG and custom fonts problem, but, sadly, there is no fix for the CSS problem, aside from putting a prominent notice in the marketing blurb and/or the book's introduction that warns potential customers that they should download the sample to preview the work rather than use the Look Inside feature.

Techniques

Beyond the specific issues covered above, you can employ a number of generally applicable techniques when you run into a seemingly impenetrable problem.

1.

Validate. As advised at numerous points in this text, pass your code though a validator; better still, pass it through different validators in case one of them is more sensitive and/or informative than the others.

2.

Resolve in the Small. Try getting the effect you seek in the tiniest sample of a chapter first, and scale things up to include the entire chapter or book only when you have surmounted the obstacle. For example, if you have a large chapter possessing a wealth of different semantic and stylistic constructions, try commenting-out everything except that part of the chapter that refuses to play ball.

Similarly, you can try commenting-out all the CSS that does/should not apply to the content in question (that is, prepend and append the code with a start- and end-comment symbol respectively). If the problem does not go away, you will have localised it nevertheless to the active section of code alone, which will give you the best chance of reasoning your way out of the pit.

However, if it does go away, you have a clear indication that the problem lies not where you thought, but in one of the inactive, commented-out sections. Alternatively, it shows that there is some kind of conflict or interaction between the active section and one or more of the deactivated sections. Whatever happens, minimising things always yields information-grist for the defect-resolution mill.

3.

Re-Factor. If your implementation for a given effect fails to work, try, if possible, to re-factor that implementation. That is, if you can think of an alternative way that differs significantly from the way that does not work, try changing your code such that it implements that other approach.

4.

Pursue Simplicity. Always try to do things in as efficient and simple a fashion as possible. In general, complexity lies at the heart of many HTML-/CSS-related woes, as pointed out elsewhere in this text, and so you should avoid exotic constructions and refrain wherever you can from being adventurous.

5.

Think Laterally. Take note of the resolution to the overflow/border-radius bug that Appendix C​covers. The solution is to apply one rule to a div that acts as an invisible container, and to apply the other rule to a child of that div. Separating things in that way avoids the conflict that manifests as unreadable text, so, when in difficulty with your own obstacles, always bear in mind the value of a little lateral thinking.

6.

Craft your Search Terms. When searching the Internet for hints, tips and solutions, try varying your search terms. That is, try using synonyms for the terms that have delivered little of value so far, and try employing a little lateral thinking in your choice of terms. Remember also that search engines will accept multiple-word terms that are wrapped in quotes, thus allowing you to search for a mix of a phrase and a set of individual words too.

Remember too that prefixing a term with a minus sign will tell the search engine to omit results containing that term, which enhances your ability to zero-in on a potential fix. You should also bear in mind that search engines, like any computation system, cannot ‘know what you mean’; they are simply tools that can return the highest-quality results only when you provide them with the highest quality input.

Some closing thoughts: you may find that resolution of an e-book production problem just comes in its own time, where, after a day of unalloyed frustration, the solution occurs to you unbidden on waking the next morning. Alternatively, you can be distracted by some other task (cooking dinner for example), whereupon the solution hits you out of the blue. Indeed, this is where you can capitalise on the ‘holiday effect’​mentioned in Chapter Two, where pushing hard at a problem, and then taking a proper break allows your mind to digest matters in the background, thus yielding the solution almost magically at a later point. Psychologists call this digestion phase ‘incubation’.

Ultimately, and to give you some moral support when you are really stuck, it is true that the challenges we face when wrestling with these complex technologies are, from time to time, utterly maddening, as ignorance of some trick, quirk or principle can incur hours or even days of grinding frustration. Indeed, you might wonder how anybody could ever deal with such impediments routinely, as professional software developers do (for example), without just giving up, and you would have a point.

Sadly, however, the gritty truth proffers little consolation: you just have to be exceptionally persistent, treat it as a marathon not a sprint, and know when to step back and try another approach. On occasion, it is time even to say ‘To Hell with it’, and go get a beer in the hope that enlightenment, with her love of being fashionably late, will grace you with her presence subsequently.

Yes, it can be terribly frustrating, but persistence always sees some form of resolution eventually, so just keep trying, come what may. If you are in difficulty currently, and have read this guide entirely up to this point, you are far closer than you think to success.

End of Book