2013-03-24 1:26, tlvp wrote:
> In dramatic dialogue like the following, I'd like all the *lines* to share
> one left margin and all the *characters' names* to share that vertical as a
> common right margin:
[...]
>
> I can see achieving that on a web page by using a table -- one row per
> 'speech', with each row having two cells: the left one with align attribute
> set = "right", the right one with align attribute set = "left".
Right. This is the most robust way. The second row does not really need
the align attribute, since align="left" is the default (unless you set
dir="rtl", which you won't, for English text). It's also the way that
will most probably get flamed by "modern" "web designers". It’s simple
and works on all browsers, but their dogmas include “thou shalt not use
<table>” or, in some sects, “thou shalt not use <table> for layout”
(where “for layout” probably covers almost anything but statistical
tables and relatives).
But if you don’t need to care about flames, then there’s just a minor
problem: it’s a bit dull to have so many class attributes. For some
broken browsers, adding
<col align="right">
<col>
right after the <table> tag would take care of the alignment. The
problem with this is that by HTML specs, it should not work, and in
practice it does not work in modern browsers. This has a complicated
background, so let’s skip to the solution:
> How would one use CSS to achieve a similar end? CSS details most welcome.
Using a <table> element as outlined but without class attributes, you
can handle the alignment with a simple style sheet:
<style>
td:first-child { text-align: right; }
</style>
You can use this in conjunction with the <col> tags, to cover both
modern and old browsers.
If you do need to care about flames, or if you need to avoid <table> for
other reasons, then you can write e.g.
<div class="dialog">
<p><span class="person">Iago:</span> <span class="text">My noble Lord —
</span></p>
[…]
</div>
with CSS like
<style>
.dialog { display: table; }
.dialog p { display: table-row; margin: 0; }
.dialog .person, .dialog .text { display: table-cell; }
.dialog .person { text-align: right; }
</style>
(You could dispense with the class attributes, except for
class="dialog", by using selectors like
.dialog > p > span:first-child
at the cost of losing the formatting in some old borders that don't grok
such “advanced” CSS.)
This has the problem that old versions of IE (and some other rather old
browsers) do not support display: table and friends. In this case, the
text would still be readable, though without the desired formatting.
Other options include using markup as above but with different styling
(which works on all CSS-enabled browsers) like
<style>
.dialog p { margin: 0; }
.dialog .person { width: 4em; float: left; text-align: right; }
.dialog .text { display: block; margin-left: 4.2em; }
</style>
The main issue with this is that you need to make a guess on the width
of the first “column”. Since this is not table formatting, you cannot
just let the browser decide how wide a column needs to be. But in a
simple case, where the names can be expected to be relatively short,
this is probably tolerable.
A few days ago I would have said that this is pointlessly complicated as
compared with <table>. But now I have been struggling with some non-WWW
use of HTML where I would need to display a <table> as more or less
linearized, i.e. to do the opposite of simulating HTML <table> in CSS.
While rather straighforward in principle, it seems to be problematic in
practice due to limitations in e.g. epub-related software. Using <span>
and <div> in markup might actually be more practical... but I’d had to
do that for some content that is really tabular in nature. (A dialog
isn’t; it *can* be described and marked up as a table, but it is not
*inherently* tabular, I would say.)
--
Yucca,
http://www.cs.tut.fi/~jkorpela/