Blog

HTML Text align (Dot Leaders)

Dot leaders

Typographers call “dot leaders” the rows of dots that connect columns in a table, such as this:

Dots are the most common, but you can use other symbols, such as dashes, or a solid line with an arrow. They help to visually connect items across a gap of variable size.

CSS should soon acquire real leaders, which can be added after or before an element to bridge the gap to the next element. But let's look at a trick to simulate them with CSS level 2.

The method below isn't the first or the only attempt to trick CSS into displaying leaders. The first is due to Tantek Çelik. His Bella Mia menu was made, you guessed it, during dinner in a restaurant called Bella Mia, as long ago as 2000. Some other examples are by Micah Sittig and Brett Merkey.

The mark-up

The restaurant menu of the example is marked up as a list:

<ul class=leaders>  
<li><span>Salmon Ravioli</span>   
<span>7.95</span>  
<li><span>Fried Calamari</span>   
<span>8.95</span> 
<li><span>Almond Prawn Cocktail</span>   
<span>7.95</span>  
<li><span>Bruschetta</span>   
<span>5.25</span>  
<li><span>Margherita Pizza</span>
<span>10.95</span>  </ul>  

There isn't much special about the mark-up. I chose a list, because a restaurant menu is semantically a list. The two columns of the menu have to be in different elements, though. In this case they are both in SPANs.

CSS rules

We create the dot leaders with a ‘:before’ pseudo-element attached to the LI elements. The pseudo-element fills the whole width of the list item with dots and the SPANs are put on top. A white background on the SPANs hides the dots behind them and an ‘overflow: hidden’ on the UL ensures the dots do not extend outside the list:

ul.leaders {
max-width: 40em;
padding: 0;
overflow-x: hidden;
list-style: none;
}

ul.leaders li:before {
float: left;
width: 0;
white-space: nowrap;
content: 
". . . . . . . . . . . . . . . . . . . . " 
". . . . . . . . . . . . . . . . . . . . " 
". . . . . . . . . . . . . . . . . . . . " 
". . . . . . . . . . . . . . . . . . . . ";
}

ul.leaders span:first-child {
padding-right: .33em;
background: #fff;
}

ul.leaders span + span {
float: right;
padding-left: .33em;
background: #fff;
} 

I used an arbitrary 80 dots, which is enough to fill about 38em, hence the maximum width on the list. The ‘:before’ is given a width of zero, so it effectively uses no space and the other content will end up on top of the dots.

The ‘padding: 0’ and ‘list-style: none’ are there only to suppress the default style for lists: I chose to mark up the menu as a list, but I didn't want bullets before the items.

One advantage of attaching the dots to the list item, instead of to one of the SPANs, is that this way all dots nicely line up vertically. That is often a desired effect if you have several adjoining lines with dot leaders.

Variations

Here are some variations with different symbols for the leaders. The first one uses a middle dot instead of a full stop. The style rules are exactly the same, only the generated text has “·” instead of “.”:

 

A bullet symbol is like a middle dot, but bigger:

 

With a colon:

 

This leader has colored plus signs without spaces between them:

A stretching arrow

The final variation is a bit different. The leader is an arrow and the challenge is not to make the symbols line up vertically, but to put the arrowhead at the end of the gap. For that reason, the leaders are not attached to the list item, but to the element with the price. Look at the source of this page to see how it is done.

Leaders in long text

But what if the text before the dot leader is so long that it wraps over several lines? The row of dots has to be lower in that case, not behind the first line of the text, but behind the last. Without the proposed new features for CSS level 3 we cannot solve that in the general case, but we can still make it look reasonable in simple cases.

We have to assume then that the text after the leader is short enough that it won't wrap. And then we attach the dots not to the start of the text (':before') but to the end (':after'), so that they show behind the last line of the text, instead of the first. Here is how that looks:

CSS rules for wrapping text

The CSS rules are the same as before, except that we now use the selector 'ul.leaders li:after' instead of 'ul.leaders li:before'.

And there is one extra subtlety: because the dots are now logically after the last text, they will be drawn over, instead of under it. We need to force that text to be raised above the dot leader, so that the dots won't be visible where the text is. CSS has the 'z-index' property for that. It only works for positioned elements, so we need to add two declarations. The full rules are:

ul.leaders {
    max-width: 40em;
    padding: 0;
    overflow-x: hidden;
    list-style: none;
}

ul.leaders li:after {
    float: left;
    width: 0;
    white-space: nowrap;
    content: 
". . . . . . . . . . . . . . . . . . . . " 
". . . . . . . . . . . . . . . . . . . . " 
". . . . . . . . . . . . . . . . . . . . " 
". . . . . . . . . . . . . . . . . . . . ";
}

ul.leaders span:first-child {
    padding-right: .33em;
    background: #fff;
}

ul.leaders span + span {
    float: right;
    padding-left: .33em;
    background: #fff;
    emposition: relative;
    /ememz-index: 1;
} 

Leaders in level 3

The leaders feature in level 3 of CSS is still in development (as of March 2011), but eventually it will make the above examples much easier to write.

The first example simplifies to:

ul.leaders {
    padding: 0;
    list-style: none;
}

ul.leaders span:first-child:after {
    content: leader(dotted);
}

And that will automatically push the second SPAN to the end of the line, so there is no need to make it float.

‘Dotted’ is a predefined keyword. But any symbols can be put in quotes, e.g., ‘leader("· ")’ for the pair middle dot + space. Here are the examples again, but using the proposed level 3 features. They are unlikely to work yet. (As of November 2014, only Prince and PDFReactor are known to have experimental support.)

The arrow leader is made from the “horizontal line extension” character (\23AF) and an arrow (\2192). They don't line up in all fonts, but they do in the Symbol font. However, there may be a gap just before the arrowhead, because the current draft doesn't yet explain how to align the leader to the right. (We used a hack here: some negative letter-spacing to help close the gap, but it may not be enough.)

 

 

Best answer from stackoverflow.com

 

  • Place 2 span (as table-cell) inside a LI set as table
  • Trick the last span to width: 1%;
  • Add the desired dashes or dots or even a background-image to the first span's :after pseudo element
body{background:orange;}    /* No other backgrounds are used */

ul.leaders {
  padding:        0;
}
ul.leaders li {
  display:        table;
}
ul.leaders li span {
  display:        table-cell;
}
ul.leaders li span:first-child { /* TITLE */
  position:       relative;
  overflow:       hidden;       /* Don't go underneath the price */
}
ul.leaders li span:first-child:after { /* DASHES */
  content:        "";
  position:       absolute;
  bottom:         0.5em;        /* Set as you want */       
  margin-left:    0.5em;        /* Keep same for the next span's left padding */
  width:          100%;
  border-bottom:  1px dashed #000;
}
ul.leaders li span + span {     /* PRICE */
  text-align:     right;
  width:          1%;           /* Trick it */
  vertical-align: bottom;       /* Keep Price text bottom-aligned */
  padding-left:   0.5em;
  /* white-space: nowrap;       /* Uncomment if needed */
}

 

<ul class=leaders>
<li>
<span>Salmon Ravioli</span>
<span>7.95</span>
</li>
<li>
<span>Pan seared Ahi with avocado, soy, ginger and lime</span>
<span>8.95</span>
</li>
<li>
<span>Almond Prawn Cocktail</span>
<span>7.95</span>
</li>
<li>
<span>Bruschetta</span>
<span>45.25</span>
</li>
<li>
<span>Margherita Pizza</span>
<span>108.95</span>
</li>
</ul>

 

Featured videos

Commercials
Big Screens & Billboards

Follow me

Blog

Operating systems, code secrets and lots of everything...