If there are two layouts for the same data should I try to find a semantic layout that fits both or just pick one to be semantic and the other stylistic only? Any ideas would be appreciated since at the moment, I'm doing neither.
I'm trying to put some sacred texts online with the ability to have them styled various ways. There are two main styles: paragraph form and verse form. Verse form is easy. Paragraph form is giving me a headache since it conflicts with verse form and, seemingly, itself. In paragraph form the verse numbers and chapter numbers can be toggled on and off, so loading a new page when choosing between the two forms is not ideal. Going the non-semantic route is easy. Fixing it is confusing me though. I'd like to keep this as valid HTML if possible.
Here's what I have so far:
<article>
<h2>Book</h2>
<div>
<h3>Chapter 1</h3>
<span class="verse-num">1 </span>Lorem ipsum dolor sit amet, duo ei
aliquam tincidunt, ut eos electram elaboraret, no nec falli omnesque.
<span class="verse-num">2 </span>Eu cum nisl alia aeterno. Mediocrem
eloquentiam ad mel, no idque moderatius mei, sed legere inciderint
no. Et nec brute essent sententiae.
</div>
<div>
<span class="verse-num">3 </span>Sea ea omnes explicari repudiare, et
eam graeco alterum eruditi, vim consulatu referrentur ad. Id eros
nostrud mei, nibh adipisci has eu. Ei pri ipsum primis accommodare.
<span class="verse-num">4 </span>Ignota copiosae theophrastus ne qui,
te suas essent molestiae nam. Tacimates patrioque quo ad.
</div>
<div>
<span class="verse-num">5 </span>Nusquam appareat comprehensam has in.
Qui melius labitur persequeris cu, no brute elitr libris eum.
<h3>Chapter 2</h3>
<span class="verse-num">1 </span>Voluptaria reformidans at sed, mollis
ullamcorper sea id. Usu cu oblique voluptaria definitiones, dicant
corpora iudicabit his an.
</div>
<div>
<span class="verse-num">2 </span>Cum at illum facete corrumpit, aeque
repudiare ad vim, cu has inimicus iudicabit. Qui eu interesset
eloquentiam. Est ei nisl atqui, amet intellegat ea per. Integre
adolescens id has, adhuc tibique corrumpit ut quo. Facer
assum singulis eu per, et mea vulputate necessitatibus.
<span class="verse-num">3 </span>Ut ius facer tamquam erroribus, duo ei
atqui dicunt liberavisse.
</div>
<div>
Quo mundi offendit adolescens ut, nisl illum vis an. Ne vis luptatum
legendos, docendi vulputate omittantur usu eu. At mea luptatum
iracundia, ridens laoreet contentiones an pro, eu diam partem inciderint
mea. <span class="verse-num">4 </span>Veri sanctus mel te, no vero
etiam iudicabit vis, cu dicat explicari reformidans vix.
</div>
<div>
<h3>Chapter 3</h3>
<span class="verse-num">1 </span>Pri homero comprehensam ex, ad nemore
suscipit appetere mel. Ex simul albucius vel. No est hinc graeco
nominavi. <span class="verse-num">2 </span>Erat fabulas ex qui. Eu vis
nonumy omnium scaevola, audiam elaboraret eos in.
</div>
</article>
I'd like to get rid of the div's, but have no idea what to make them. I'd like to keep this as valid HTML if possible. I can't use p tags since occasionally an h3 tag is enclosed in one. I can't use sections because not all sections have an h3 tag.
I'm open to completely redoing the HTML (and css), but would like to avoid JavaScript as I don't believe it fits. Any ideas would be appreciated.
For clarity: Should I ignore semantics (use what I have), try to make one of them semantic and ignore the other, or make both of them semantically valid? If the either of the later two, how?
/* Paragraph Mode styling = makes a div act like a <p> tag */
div {
-webkit-margin-before: 1rem;
-webkit-margin-after: 1rem;
-webkit-margin-start: 0px;
-webkit-margin-end: 0px;
-moz-margin-start: 0px;
-moz-margin-end: 0px;
margin-bottom: 1rem;
margin-top: 1rem;
}
/* simple toggle styling */
label {
text-decoration: underline;
}
input[type=checkbox]:checked + label {
color: blue;
}
/* chapter styling */
input[type=checkbox]#verses:not(:checked) ~ article h3 {
display: inline;
font-size: 1rem;
font-weight: normal;
}
input[type=checkbox]#verses:not(:checked) ~ article h3:before {
content: "[";
}
input[type=checkbox]#verses:not(:checked) ~ article h3:after {
content: "]";
}
/* main toggle changes - makes things disappear */
input[type=checkbox]#verses:checked ~ #super-label,
input[type=checkbox]#verses:checked ~ #super,
input[type=checkbox]#verses:checked ~ #chapters-label,
input[type=checkbox]#verses:checked ~ #chapters,
input[type=checkbox]#chapters:not(:checked) ~ article h3,
span.verse-num {
display: none;
}
/* more chapter styling - not grouped above due to precedence issues that I'm to lazy to fix at the moment */
input[type=checkbox]#verses:checked ~ article h3 {
display: block;
margin-bottom: 0;
}
/* Verse Mode styling - make spans simulate <p> tags */
input[type=checkbox]#verses:checked ~ article span.verse-num:before {
content: '\A';
white-space: pre;
display: block;
}
input[type=checkbox]#verses:checked ~ article span.verse-num:after {
content: '';
display: inline-block;
width: .5rem;
}
/* Paragraph Mode styling - not grouped above due to precedence issues that I'm to lazy to fix at the moment */
input[type=checkbox]#verses:checked ~ article div,
input[type=checkbox]#verses:checked ~ article span.verse-num,
input[type=checkbox]#super:checked ~ article span.verse-num {
display: inline;
}
input[type=checkbox]#super:checked ~ article span.verse-num {
font-size: .83rem;
vertical-align: super;
}
/* Verse Mode styling - not grouped above due to precedence issues that I'm to lazy to fix at the moment */
input[type=checkbox]#verses:checked ~ article span.verse-num {
font-size: 1rem;
vertical-align: baseline;
}
<input type="checkbox" id="verses">
<label for="verses">Toggle Verses</label>
<input type="checkbox" id="chapters">
<label for="chapters" id="chapters-label">Toggle Chapters</label>
<input type="checkbox" id="super">
<label for="super" id="super-label">Verse numbers as superscript</label>
<article>
<h2>Book</h2>
<div>
<h3>Chapter 1</h3>
<span class="verse-num">1 </span>Lorem ipsum dolor sit amet, duo ei aliquam tincidunt, ut eos electram elaboraret, no nec falli omnesque. <span class="verse-num">2 </span>Eu cum nisl alia aeterno. Mediocrem eloquentiam ad mel, no idque moderatius mei,
sed legere inciderint no. Et nec brute essent sententiae.</div>
<div><span class="verse-num">3 </span>Sea ea omnes explicari repudiare, et eam graeco alterum eruditi, vim consulatu referrentur ad. Id eros nostrud mei, nibh adipisci has eu. Ei pri ipsum primis accommodare. <span class="verse-num">4 </span>Ignota copiosae
theophrastus ne qui, te suas essent molestiae nam. Tacimates patrioque quo ad.</div>
<div><span class="verse-num">5 </span>Nusquam appareat comprehensam has in. Qui melius labitur persequeris cu, no brute elitr libris eum.
<h3>Chapter 2</h3>
<span class="verse-num">1 </span>Voluptaria reformidans at sed, mollis ullamcorper sea id. Usu cu oblique voluptaria definitiones, dicant corpora iudicabit his an.</div>
<div><span class="verse-num">2 </span>Cum at illum facete corrumpit, aeque repudiare ad vim, cu has inimicus iudicabit. Qui eu interesset eloquentiam. Est ei nisl atqui, amet intellegat ea per. Integre adolescens id has, adhuc tibique corrumpit ut quo. Facer
assum singulis eu per, et mea vulputate necessitatibus. <span class="verse-num">3 </span>Ut ius facer tamquam erroribus, duo ei atqui dicunt liberavisse.</div>
<div>Quo mundi offendit adolescens ut, nisl illum vis an. Ne vis luptatum legendos, docendi vulputate omittantur usu eu. At mea luptatum iracundia, ridens laoreet contentiones an pro, eu diam partem inciderint mea. <span class="verse-num">4 </span>Veri sanctus
mel te, no vero etiam iudicabit vis, cu dicat explicari reformidans vix.</div>
<div>
<h3>Chapter 3</h3>
<span class="verse-num">1 </span>Pri homero comprehensam ex, ad nemore suscipit appetere mel. Ex simul albucius vel. No est hinc graeco nominavi. <span class="verse-num">2 </span>Erat fabulas ex qui. Eu vis nonumy omnium scaevola, audiam elaboraret
eos in.
</div>
</article>
Passing your non-semantic snippet to the W3 HTML Validator reveals that it is valid HTML, apart from the missing title
tag, which is not your doing.
As for semantic validity, this is a really opinion-based question, but I'll try to explain the reason behind my opinions.
I never even really started bothering with semantics, because there are just way too many things that can only be achieved by some ugly workaround, most of which somehow involve abusing tables (e.g. making an element fill whatever parent it is placed in, or vertically centering multi-line text in a div).
I usually try to build my HTML so that is just makes sense, but quite often that is not possible for some bits.
And for some things there is simply no concept, like draggable blocks. For example, if you click the "flag" link under a post here on SO, you get sort of a popup. That popup is a div
, at least at the time of writing.
Now, is div
the correct element? On the W3 documentation, there are two lines in "definition & usage":
The
<div>
tag defines a division or a section in an HTML document.
According to this, it should be used in the same manner as <p>
, but for block elements where <p>
is for text.
The
<div>
tag is used to group block-elements to format them with CSS.
According to this, it can be used pretty much everywhere, as long as it contains some block elements.
The same goes for the <span>
tag, only for inline elements.
So if you want, you can replace the div
s you don't like with span
s, but that is hardly what you want, right?
I think with your example it is impossible to get it semantically valid other than having a couple of pre-formatted hidden divs of which you only show one at a time. I believe this is impossible because you are trying to use the same elements for multiple purposes. Once you have a flowing text, and once you have an ordered list of verses, and that with the same elements?
Syntactically? - No problem. Semantically? - No chance.
I would just go with what you have, but if you really want to get it semantically valid too, then I believe you either have to create one hidden div for each display state, and when options are changed, show the corresponding div, or (as doveyg suggested) store your text in JavaScript in some form and create the displayed elements on the fly.