13

I'd like to display some text then a dotted line then some more text on the same line on a HTML page e.g.

Name: .......................................................... (Engineer)

I want the "Name" to be left justified against the left border and "Engineer" to be right justified against the right border and then the browser to be able to fill the gap between the two with repeating dots.

I've tried a good few different ways to get this to work using CSS and HTML but can't quite get it right. I don't want to have to specify the width (actual or percentage) of each component so that the solution is re-usable with words of different lengths e.g. the same solution would work with:

Factory Location: .................................... (Not invoice address)
TylerH
  • 20,799
  • 66
  • 75
  • 101
CodeClimber
  • 4,584
  • 8
  • 46
  • 55
  • Can you show what you've tried so far? – Kyle Feb 04 '11 at 13:09
  • Revisiting this question, quite some time later, might I suggest that you consider accepting [Harry's answer](https://stackoverflow.com/a/28629080/82548) in place of my own? It's almost certainly more suitable - and far less 'hacky' than my own, given developments in CSS presentation. – David Thomas Sep 28 '18 at 23:10
  • Same question, other answers here: https://stackoverflow.com/questions/2508732/create-leading-dots-in-css – adamdport Mar 20 '19 at 19:08

6 Answers6

13

Here is a solution to display a dotted line between 2 texts on one line. It used the display: flex; property to align the dotted line and the texts on the left an right :

.wrap {
  display: flex;
}

.left {
  flex: 1;
  display: flex;
}

.left::after {
  content: '';
  border-bottom: 1px dotted;
  flex: 1;
  margin: 0 .5em;
}
<div class="wrap">
  <span class="left">Name :</span>
  <span class="right">Engineer</span>
</div>
<div class="wrap">
  <span class="left">Factory location :</span>
  <span class="right">(not invoice address)</span>
</div>

Previous answer with floats :

Output :

Responsive dotted line between text on the right and on the left

This solution floats both texts and the dotted bottom border expands to the remaining width. Here is the relevant code :

div {
  height: 1em;
}

.left,
.right {
  padding: 1px 0.5em;
  background: #fff;
  float: right;
}

.left {
  float: left;
  clear: both;
}

.dotted {
  border-bottom: 1px dotted grey;
  margin-bottom: 2px;
}
<div class="left">Name:</div>
<div class="right">Engineer</div>
<div class="dotted"></div>
<div class="left">Factory location:</div>
<div class="right">not invoice address</div>
<div class="dotted"></div>
web-tiki
  • 99,765
  • 32
  • 217
  • 249
  • @Vedmant: I think the only way to achieve this (without using images for dots) and also have an image background is to use the flexbox approach. I have added a sample as my answer but the browser support is pretty low for it. – Harry Feb 22 '15 at 04:55
13

In modern browsers, this can be achieved by using flex-box display. Flex-boxes have a flex-grow property which specifies how the free space should be distributed among the elements when their total size is smaller than the container size. Source for the explanation is cimmanon's answer here.

By assigning a flex-grow to only the element which produces the dots would mean that the entire remaining space would by default be used up by it.

The dots in the middle could either be produced using (a) radial gradients or (b) border. I prefer the radial gradients because they allow greater control in terms of the space between each dot and its size. Radial gradients have low browser support but that shouldn't be a big concern here because it is equal to the support for Flexbox (if not better).

.container {
  width: 500px;
  height: 200px;
  background: -webkit-linear-gradient(0deg, brown, chocolate);
  background: -moz-linear-gradient(0deg, brown, chocolate);
  background: linear-gradient(0deg, brown, chocolate);
  color: beige;
  padding: 10px;
}
.row {
  line-height: 2em;
  display: -webkit-flex;
  display: -moz-flex;
  display: -ms-flex;
  display: flex;
  -webkit-flex: 1;
  -moz-flex: 1;
  -ms-flex: 1;
  flex: 1;
}
.row .left {
  -webkit-order: 1;
  -moz-order: 1;
  -ms-order: 1;
  order: 1;
}
.row .right {
  -webkit-order: 3;
  -moz-order: 3;
  -ms-order: 3;
  order: 3;
}
.row .right:before {
  content: "(";
}
.row .right:after {
  content: ")";
}
.row:after {
  content: "";
  margin: 0px 4px;
  background: -webkit-radial-gradient(50% 50%, circle, beige 12%, transparent 15%);
  background: -moz-radial-gradient(50% 50%, circle, beige 12%, transparent 15%);
  background: radial-gradient(circle at 50% 50%, beige 12%, transparent 15%);
  background-size: 1em 1em;
  background-position: 0 0.5em;
  background-repeat: repeat-x;
  -webkit-flex-grow: 1;
  -moz-flex-grow: 1;
  -ms-flex-grow: 1;
  flex-grow: 1;
  -webkit-order: 2;
  -moz-order: 2;
  -ms-order: 2;
  order: 2;
}
<div class="container">
  <div class="row">
    <span class="left">Something</span>
    <span class="right">Something else</span>
  </div>
  <div class="row">
    <span class="left">Something lengthy</span>
    <span class="right">Something else lengthy</span> 
  </div>
</div>

Browser Specific Customizations:

  • IE11 does not support flex-grow property on a pseudo-element. Hence we have to introduce an extra span for the dots in between the left and right span. A sample can be found here.

  • IE10 has a different syntax for flexbox and other properties. Here is a sample for it.

  • Safari (5.1.7 and earlier on Windows) does not support flexbox on span tag and hence they need to be replaced with div tags (or display: block needs to be set). Also, Safari versions older than 6.1 do not support flex-grow property. This sample has an implementation for those versions.

Final Output:

Putting all the various pieces together, this sample works in IE10, IE11, Chrome, Opera, Firefox and Safari (in essence, all versions that support flexbox). This approach works well with image and gradient backgrounds also.

Browser Support: Flexbox | Gradients

Community
  • 1
  • 1
Harry
  • 87,580
  • 25
  • 202
  • 214
8

I'd suggest that, perhaps, a ul would be one option:

<ul>
    <li><span class="definition">Name:</span><span class="defined">Engineer</span></li>
    <li><span class="definition">Factory location:</span><span class="defined">not invoice address</span></li>
</ul>

CSS:

ul li {
    border-bottom: 2px dotted #ccc;
}

span.defined {
    float: right;
}

span.defined:before {
    content: "(";
}

span.defined:after {
    content: ")";
}

JS Fiddle demo.


Edited to correct the CSS. And the HTML. Oops.


Edited in response to @Leigh's (accurate) comment:

This isn't doing what the OP asked for? This just gives a dotted underline (FF 3.5), not dots between the two pieces of text.

I've adjusted the CSS a little to hide the dotted border under the spans:

ul li {
    border-bottom: 2px dotted #ccc;
    line-height: 2em;
    text-align: right;
    clear: both;
    margin: 0.5em 0 0 0;
}

span.definition {
    float: left;
}

span.defined:before {
    content: "(";
}

span.defined:after {
    content: ")";
}

span {
    display: inline-block;
    border: 2px solid #fff;
    padding: 0;
    margin: 0 0 -2px 0;
}

Admittedly this is only tested in Chrome 8, and Firefox 3.6, Ubuntu 10.10.

Updated JS Fiddle demo.

David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • I'd +2 if I could, very elegant solution. What's the browser support for :before and :after? – Kyle Feb 04 '11 at 13:24
  • @David Thomas I think Name was supposed to be left aligned, I guess in the css it's supposed to be span.defined instead of span.definition. Also there is a slash in the second span ` – Reiner Gerecke Feb 04 '11 at 13:29
  • @squiddy, yeah I caught that. Corrected the CSS, but forgot to correct the second `` tags. **Edited**, and thanks for the catch! =) – David Thomas Feb 04 '11 at 13:31
  • 2
    -1 This isn't doing what the OP asked for? This just gives a dotted underline (FF 3.5), not dots **between** the two pieces of text. – Leigh Feb 04 '11 at 13:43
  • 1
    @Leigh: you were absolutely right (somehow I'd missed that part of the question), anyway see the edit, and [updated demo](http://jsfiddle.net/davidThomas/cqWFx/4/) for a more refined approach that meets the requirements. – David Thomas Feb 04 '11 at 19:27
  • @David Goes to a +1, very nice. Intriguing behaviour with the -2px margin there. Firebug really helps to visualise what's going on, because I couldn't do it in my head :) In my opinion (maybe not the OPs) the line is a bit low. The only real way I found to bring it up was to decrease the line-height of the list items. – Leigh Feb 04 '11 at 20:58
  • @Leigh, yeah: it's one of those things that depends entirely upon the person who's designing it. Havng said that, I *used* `line-height: 2em` for *some* reason, but I can't remember why, now. `line-height: 1em;` does look better, though. Oh, and thank you, kindly! =) – David Thomas Feb 04 '11 at 21:23
2

I don't want to take credit for this, but I found a great solution over at codingforums.com

I've made a JSFiddle out of it.

http://jsfiddle.net/DeDRE/9/

(dotted lines are done with an image: dot.gif. If you don't see any dotted lines at the time you're reading this, the host I've currently used must have taken the image offline)

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en-Latn-US">
<head>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Demo CF108909</title>
    <meta name="Author" content="Patrick Garies">
    <meta name="Created" content="2007-03-03">
    <meta name="Revised" content="2007-06-19">
    <style type="text/css">
        * { margin: 0; padding: 0; }
        html { color: black; padding: 2em; font: 16px/1.2 "Lucida Sans", "Lucida Sans Unicode", "Lucida Grande", sans-serif; }
        html, tbody th, span {  background: #f7f7ee; }
        table, caption { margin: 0 auto; } /* Application to the caption element addresses Mozilla Bug 297676. */
        table { border-collapse: collapse; }
        caption, th, td { padding: 0.1em 0; }
        caption { text-align: center; font-weight: bolder; }
        thead { display: none; }
        tbody tr { background: url("http://www.myresult.co/images/dot.gif") 0 78% repeat-x; }
        tbody th, td + td { text-align: right; }
        tbody th { padding-right: 0.4em; font-weight: normal; }
        td + td { padding-left: 0.4em; }
        cite { font-style: normal; }
        span { padding: 0 0.2em; white-space: pre; }
    </style>

</head>
<body>

    <table>
        <caption><cite>Dragonseye</cite> Table of Contents</caption>
        <col>
        <col>
        <col>
        <thead>
            <tr>
                <th scope="col" abbr="Chapter">Chapter Number</th>
                <th scope="col" abbr="Title">Chapter Title</th>
                <th scope="col" abbr="Page">Initial Page Number</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <th scope="row"></th>
                <td><span>Prologue</span></td>
                <td><span>1</span></td>
            </tr>
            <tr>
                <th scope="row">1</th>
                <td><span>Early Autumn at Fort’s Gather</span></td>
                <td><span>4</span></td>
            </tr>
            <tr>
                <th scope="row">2</th>
                <td><span>Gather at Fort</span></td>
                <td><span>49</span></td>
            </tr>
            <tr>
                <th scope="row">3</th>
                <td><span>Late Fall at Telgar Weyr</span></td>
                <td><span>64</span></td>
            </tr>
            <tr>
                <th scope="row">4</th>
                <td><span>Telgar Weyr and the College</span></td>
                <td><span>87</span></td>
            </tr>
            <tr>
                <th scope="row">5</th>
                <td><span>Weyrling Barracks and Bitra Hold</span></td>
                <td><span>104</span></td>
            </tr>
            <tr>
                <th scope="row">6</th>
                <td><span>Telgar Weyr, Fort Hold</span></td>
                <td><span>138</span></td>
            </tr>
            <tr>
                <th scope="row">7</th>
                <td><span>Fort Hold</span></td>
                <td><span>162</span></td>
            </tr>
            <tr>
                <th scope="row">8</th>
                <td><span>Telgar Weyr</span></td>
                <td><span>183</span></td>
            </tr>
            <tr>
                <th scope="row">9</th>
                <td><span>Fort Hold and Bitran Borders, Early Winter</span></td>
                <td><span>197</span></td>
            </tr>
            <tr>
                <th scope="row">10</th>
                <td><span>High Reaches, Boll, Ista Weyrs; High Reaches Weyr, Fort, and Telgar Holds</span></td>
                <td><span>217</span></td>
            </tr>
            <tr>
                <th scope="row">11</th>
                <td><span>The Trials at Telgar and Benden Weyrs</span></td>
                <td><span>238</span></td>
            </tr>
            <tr>
                <th scope="row">12</th>
                <td><span>High Reaches and Fort Holds</span></td>
                <td><span>261</span></td>
            </tr>
            <tr>
                <th scope="row">13</th>
                <td><span>Bitra Hold and Telgar Weyr</span></td>
                <td><span>278</span></td>
            </tr>
            <tr>
                <th scope="row">14</th>
                <td><span>Turn’s End at Fort Hold and Telgar Weyr</span></td>
                <td><span>300</span></td>
            </tr>
            <tr>
                <th scope="row">15</th>
                <td><span>New Year 258 After Landing; College, Benden Hold, Telgar Weyr</span></td>
                <td><span>327</span></td>
            </tr>
            <tr>
                <th scope="row">16</th>
                <td><span>Cathay, Telgar Weyr, Bitra Hold, Telgar</span></td>
                <td><span>348</span></td>
            </tr>
            <tr>
                <th scope="row">17</th>
                <td><span>Threadfall</span></td>
                <td><span>379</span></td>
            </tr>
        </tbody>
    </table>

</body>
</html>

Original source - http://www.codingforums.com/showpost.php?p=578354&postcount=4

Pepijn Olivier
  • 927
  • 1
  • 18
  • 32
  • @Mark : maybe because having the contents restricted to table cells would break the flow of the dots at the same spot, instead of just before the right-justified text... Maybe it isn't much of an issue for the page numbers in a TOC (though the glitch is still visible), but imagine the original example: "(Engineer)" on one row, and "(Not invoice address)" on another. – C.B. Oct 11 '13 at 16:02
  • Actually, i should've tested before i expressed my idea of what could be the issue. While the specific point i raised is not valid, this solution will force the table to be wide enough to have all cell contents fit within a single line. Might not be very useful. Also, this won't work if the background needs to be set someplace else, will it? – C.B. Oct 11 '13 at 16:14
  • I don't see the dots in the fiddle. – Anushree Acharjee Sep 14 '15 at 10:31
  • @AnushreeAcharjee I updated the fiddle with a new dot image – Pepijn Olivier Sep 14 '15 at 13:28
1

My solution is use postion:relative; and position:absolute;

html

<div class="row">.............................................................................................................................<span class="left">Name:</span><span class="right">(Engineer)</span></div>
<div class="row">.............................................................................................................................<span class="left">Factory Location:</span><span class="right">(Not invoice address)</span></div>

css

.row {width:500px;position:relative;}
.left {position:absolute;left:0;background:white;}
.right {position:absolute;right:0;background:white;}

Example: http://jsfiddle.net/PyCnT/

The row has position:relative; and a fixed width. Any span children will will have position:absolute; and using left:0 & right:0 the span moved in the correct place. Adding a background:white override the dots that are in the background of the span.

Sotiris
  • 38,986
  • 11
  • 53
  • 85
0
<p class="dotbg"><span>Left</span><span class="right">Right</span></p>
<p class="dotbg"><span>Some text</span><span class="right">some bad text</span></p>

.dotbg{
    line-height: 12px;
    background: url('https://i.stack.imgur.com/L8CQg.png') bottom repeat-x;    
    width: 250px; /* this is only for showcase */
    margin: 0 auto 1.5em auto; /* this is only for showcase */

}
    .dotbg span{
        padding: 0 5px; 
        background: #fff;
    }
    .dotbg .right{
        float: right;
    }

Preview: http://jsfiddle.net/E7cyB/1/

Idered
  • 2,065
  • 1
  • 18
  • 20