What is a nice way to do leading dots in a table of contents with CSS?
Example:
Link.............Chapter 1 Link.............Chapter 2 Link.............Chapter 3 What is a nice way to do leading dots in a table of contents with CSS?
Example:
Link.............Chapter 1 Link.............Chapter 2 Link.............Chapter 3 taken from catchmyfame:
"How is this done? Basically field label is wrapped in a div which has a small image of a dot applied repeatedly in the x direction as a background. This alone would cause the dots to flow under the text so to nullify that effect, the text itself is then wrapped in a span where the background color is set to match the color of the background of the containing element. Here is the CSS:
.dots { background: url('dot.gif') repeat-x bottom; } .field { background-color: #FFFFFF; } To apply this to the example form, you would just use it as:
<td> <div class="dots"> <span class="field">LastName</span> </div> </td> image for the dot
This is the best CSS-only solution I have found for this issue of dot leaders:
http://www.w3.org/Style/Examples/007/leaders.en.html
HTML
<ul class="leaders"> <li><span>Salmon Ravioli</span> <span>7.95</span></li> <li><span>Fried Calamari</span> <span>8.95</span></li> <li><span>Almond Prawn Cocktail</span> <span>7.95</span></li> <li><span>Bruschetta</span> <span>5.25</span></li> <li><span>Margherita Pizza</span> <span>10.95</span></li> </ul> CSS2/CSS3
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: 0.33em; background: white } ul.leaders span + span { float: right; padding-left: 0.33em; background: white } 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.
I used an arbitrary 80 dots, which is enough to fill about 38em, hence the maximum width on the list.
It is possible to combine the classic technique of "leaders" described by the w3c Thanks to @nootrope with the joy of flexbox.
Demo: http://jsfiddle.net/tbm62z6L/2/
.article { display: flex; } .article .item, .article .price { flex: 1 0 auto; } .article .dots { flex: 0 1 auto; } .dots::before { display: block; white-space: nowrap; overflow: hidden; text-overflow: clip; content: ". . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . " } <div class="article"> <span class="item">sandwichtoaster</span> <span class="dots"></span> <span class="price">$35</span> </div> This is a very flexible way to display leading dots, using the current font and no need to use images.
I mashed-up a couple examples to create what I think is a pretty good solution. Doesn't rely on background color to hide the leader dots. Works on IE8 too.
http://jsfiddle.net/westy808/g0d8x8c5/1/
<ul class="leaders"> <li><span>Item</span><span>12.234</span></li> <li><span>Another Item</span><span>1,000.25</span></li> </ul> ul.leaders li { clear: both; } ul.leaders li span:first-child { float: left; padding: 0 .4em 0 0; margin: 0; } ul.leaders li span + span { float: right; padding: 0 0 0 .4em; margin: 0; } ul.leaders li:after { content: ""; display: block; overflow: hidden; height: 1em; border-bottom: 1px dotted; } Building up on @Nico O‘s answer, there is no need for the un-semantic .dots element.
.toc li { display: flex; } .toc li .title { order: 1; } .toc li .chapter { order: 3; } .toc li::after { content: ""; border-bottom: 1px dotted; flex-grow: 1; order: 2; } <ul class="toc"> <li> <span class="title">Foo</span> <span class="chapter">Chapter 1</span> </li> <li> <span class="title">Bar</span> <span class="chapter">Chapter 2</span> </li> </ul> We take advantage of the fact that we can order the children of our flex container however we want, and the fact that a pseudo element behaves like a child of where it was defined. The key is the flex-grow rule. a flex-grow of 1 while all other siblings have the default 0 will grow to the remaining space even though it has no content.
This will work until the .title and .chapter elements together fill all the space. Then the ::after pseudo element will have a width of 0 and the dotted border wont be displayed, even though the .title and .chapter will wrap their content. So if you're sure that won't happen, and your viewers use modern browsers this might be the optimal solution.
Many this css hack's don't work with transtarent background or to difficult. You can use modern flex and background-gradient for dotted (it's look more polished, then table dotted). Like this:
.contacts-row { display: flex; width: 500px; } .dots { display: block; background: radial-gradient(circle, rgba(0,0,0,.62) 1px, transparent 1px) repeat-x; background-size: 20px 28px; flex-grow: 10; } <div class="contacts-row"> <b>E-mail: </b> <span class="dots"></span> <span class="text">test@email</span> </div> <div class="contacts-row"> <b>Phone: </b> <span class="dots"></span> <span class="text">test-phone</span> </div> Acutally the W3C has a working draft describing the functionality you are looking for
http://www.w3.org/TR/css3-gcpm/#leaders
Even back in 2005 A List Apart published an article for it. (http://www.alistapart.com/articles/boom) Unfortunately It doesn't seem to work for me and I haven't found much more. But maybe it's worth keeping it in mind that one day in the near future will be possible with CSS only :)
Here is my approach, using element with dotted border-style instead of image or content, make it flex and put it between "Link" and "Chapter".
.toc { width: 500px; } .row { flex-direction: row; display: flex; } .flex-dots { border-top-style: dotted; border-top-width: 1px; max-height: 1px; margin-top: 0.5em; } .flex-dots-vcenter { flex-direction: row; display: flex; } [flex] { flex: 1; } <div class="toc"> <div class="row"> <span class="field1">Link 1</span> <div class="flex-dots-vcenter" flex><span class="flex-dots" flex></span></div> <span class="field2">Chapter 1</span> </div> <div class="row"> <span class="field1">Link 20</span> <div class="flex-dots-vcenter" flex><span class="flex-dots" flex></span></div> <span class="field2">Chapter 20</span> </div> <div class="row"> <span class="field1">Link 300</span> <div class="flex-dots-vcenter" flex><span class="flex-dots" flex></span></div> <span class="field2">Chapter 300</span> </div> </div> .dots { display: inline-block; width: 325px; white-space: nowrap; overflow: hidden !important; text-overflow: ellipsis; }
.dot { display: inline-block; width: 185px; white-space: nowrap; overflow: hidden !important; text-overflow: ellipsis; } I'm late to the party but we recently had to do this at work and I ended up using a module like this:
http://codepen.io/ryanve/pen/rrBpJq
.dot-leader { position: relative; overflow: hidden; /* clip the dots */ } .dot-leader__left { position: relative; display: inline-block; } .dot-leader__left::after { color: gray; content: ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ."; font-weight: normal; display: inline-block; position: absolute; white-space: nowrap; margin-left: 5px; /* space left of dots */ } .dot-leader__right { background: white; /* cover the dots */ display: inline-block; position: absolute; right: 0; padding-left: 5px; /* space right of dots */ } with markup that uses li.dot-leader
<ul class="is-no-padding"> <li class="dot-leader"> <span class="dot-leader__left">Pizza</span> <span class="dot-leader__right">$100</span> </li> </ul> or dl.dot-leader
<dl class="dot-leader"> <dt class="dot-leader__left">Pizza</dt> <dd class="dot-leader__right">$100</dd> </dl> Dot leaders can be be done without spans or classes. Here's a responsive solution for HTML tables, modified to center the dot leader vertically:
http://codepen.io/Paulie-D/pen/bpMyBQ
table { width: 90%; margin:100px auto; table-layout:fixed; border-collapse: collapse; } td { padding:1em 0 0 0; vertical-align:bottom; } td span{ background-color:#fff; } td:first-child { text-align: left; font-weight: 700; overflow: hidden; position: relative; } td:first-child::after { content: ''; position: absolute; bottom: .4em; width:1500px; height:0px ; margin-left: 1em; border-bottom:2px dotted grey; } td:last-child { text-align:right; width:3em; } None of the other solutions worked for me. Here is my solution which:
Leader Dots: http://jsfiddle.net/g0d8x8c5/127/
HTML
<div class="main"> <p>Example # 1</p> <div class="container"> <div class="row"> <span>$150</span><span class="dots"></span><span>remaining credit</span> </div> <div class="row"> <span class="spacer"></span><span>30</span><span class="dots"></span><span>remaining days</span> </div> </div> <p>Example # 2</p> <div class="container"> <div class="row"> <span>Food Item #1</span><span class="dots"></span><span>$12.95</span> </div> <div class="row"> <span>Food Item #22</span><span class="dots"></span><span>$7.95</span> </div> </div> </div> CSS
.main { /* to prove it respects width of outer containers */ width: 320px; } .row { display: flex; } .dots { /* shorthand - flex: 1 1 auto */ flex-grow: 1; flex-shrink: 1; flex-basis: auto; display: block; white-space: nowrap; overflow: hidden; text-overflow: clip; } .dots:before { content: ". . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . "; } .row span:first-child, .row span:last-child { /* shorthand - flex: 0 0 auto */ flex-grow: 0; flex-shrink: 0; flex-basis: auto; } .row span:first-child { padding-right: 0.33em; } .row span:last-child { padding-left: 0.33em; } .spacer {visibility: hidden} .spacer:before {content: "$"}