Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

269
Visualizações
CSS dot leaders at first line over complex background

I need to implement dot leaders after first line of text using CSS to use it over texture/image background.

Expected behaviour:

enter image description here

I saw a few implementation of dot leaders over the internet. They all use one of the techniques below:

  1. ::after dots + overflow
<div class=item1>
  <span class=text1>
    Text
  </span>
  <span class=price1>
    $100
  </span>
</div>
.item1 {
  display: flex;
}
.text1 {
  flex-grow: 1;
  position: relative;
  overflow: hidden;
}
.text1::after {
  content: '';
  position: absolute;
  bottom: 0;
  border-bottom: 1px dotted grey;
  width: 100%;
}
.price1 {
  align-self: flex-end;
}

  1. absolute dots + white background
<div class=item2>
  <span class=text2>
    <span class=bg2>
      Text
    </span>
  </span>
  <span class=price2>
    <span class=bg2>
      $100
    </span>
  </span>
</div>
.item2 {
  display: flex;
  justify-content: space-between;
  position: relative;
  mix-blend-mode: darken;
}
.item2::before {
  content: '';
  position: absolute;
  top: 1em;
  left: 0;
  right: 0;
  border-bottom: 1px grey dotted;
}
.bg2 {
  background: white;
  position: relative;
  z-index: 1;
}
  1. dumb flexbox
<div class=item3>
  <span class=text3>
    Text
  </span>
  <span class=dots3></span>
  <span class=price3>
    $100
  </span>
</div>
.item3 {
  display: flex;
  align-items: flex-start;
}
.dots3 {
  flex-grow: 1;
  border-bottom: 1px dotted grey;
  min-width: 10px;
  height: 1em;
}

They are all shown here: https://jsfiddle.net/rzmLg4yu/62/

Each of these techniques has its own pitfalls in my case.

  1. Has dot leaders at last line.
  2. Does not work over complex background, even with mix-blend-mode (uncomment bg line to see). enter image description here
  3. Has large white gaps due to line breaks (resize to see). Switching to grid is no use. enter image description here

Is there more solutions to this case?

over 4 years ago · Santiago Trujillo
5 Respostas
Responde à pergunta

0

Technic 3 can be improved to get rid of the wrapping gaps:

body {
  color: grey;
}

.width {
  width: 300px;
  padding: 5px;
  resize: horizontal;
  overflow: hidden;
  abackground: linear-gradient(45deg, yellow, black);
  background-repeat: repeat-x;
  background-size: 200px 100%;
}

.item3 {
  display: flex;
  align-items: flex-start;
}

.dots3 {
  flex-grow: 1;
  border-bottom: 1px dotted grey;
  min-width: 10px;
  height: 1em;
}

.text3 {
  padding-right: 0px;
  text-align: justify; /* <--- */
}
<div class=width>

  <div class=item3>
    <span class=text3>
        3 Text text
      </span>
    <span class=dots3></span>
    <span class=price3>
        $100
      </span>
  </div>
  <div class=item3>
    <span class=text3>3 Text text text text text text text text text text text text text text text text</span>
    <span class=dots3></span>
    <span class=price3>
        $100
      </span>
  </div>
Here text-align: justify; will space the words evenly.


I think your issue with the second technic is because of white background color right?
because of .bg2 {background: white;...}?
Otherwise, you should've used mix-blend-mode: lighten; to demonstrate the issue:

body {
  color: grey;
  padding: 20px;
}

.width {
  width: 230px;
  padding: 5px;
  resize: horizontal;
  overflow: auto;
  background: linear-gradient(90deg, yellow, black);
  background-repeat: repeat-x;
  background-size: 200px 100%;
}

div>div {
  background-color: white;
  border: 2px solid green;
}

.simpleDiv1 {
  mix-blend-mode: darken;
}

.simpleDiv2 {
  margin-top: 20px;
  mix-blend-mode: lighten;
}
<div class=width>
  <div class=simpleDiv1>darken blend. Simple text without any styles and stuff.</div>
  <div class=simpleDiv2>lighten blend. Simple text without any styles and stuff.</div>
</div>

If you use darken blend then any normal text will disappear with that background, let alone dot leaders.


Technic two without background white:

body {
  color: grey;
  padding: 20px;
}

.width {
  width: 230px;
  padding: 5px;
  resize: horizontal;
  overflow: hidden;
  abackground: linear-gradient(90deg, yellow, black);
  background-repeat: repeat-x;
  background-size: 200px 100%;
}

.item2 {
  display: flex;
  justify-content: space-between;
  position: relative;
  mix-blend-mode: darken;
  text-decoration-line: underline;
  text-decoration-style: solid;
  text-decoration-color: white;
  text-decoration-thickness: 2px;
}

.item2::before {
  content: '\00a0';
  height: calc(1em - 0.5px);
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  border-bottom: 1px dotted gray;
  z-index: -1;
}
<div class=width>

  <div class=item2>
    <span class=text2>
        2 Text text
      </span>
    <span class=price2>
        $100
      </span>
  </div>
  <div class=item2>
    <span class=text2>
        2 Text text text text text text text text text text text text text text text text
      </span>
    <span class=price2>
        $100
      </span>
  </div>
</div>

Here I'm using white underline, instead of whole white background, to hide dotleader. But you'll get white underline while using some blend modes.


Technic three can be improved if we are willing to break words while wrapping:

body {
  color: grey;
}

.width {
  width: 300px;
  padding: 5px;
  resize: horizontal;
  overflow: hidden;
  abackground: linear-gradient(45deg, yellow, black);
  background-repeat: repeat-x;
  background-size: 200px 100%;
}

.item3 {
  display: flex;
  align-items: flex-start;
}

.dots3 {
  flex-grow: 1;
  border-bottom: 1px dotted grey;
  min-width: 10px;
  height: 1em;
}

.text3 {
  padding-right: 0px;
  word-break: break-all;
}
<div class=width>

  <div class=item3>
    <span class=text3>
        3 Text text
      </span>
    <span class=dots3></span>
    <span class=price3>
        $100
      </span>
  </div>
  <div class=item3>
    <span class=text3>3 Text text text text text text text text text text text text text text text text</span>
    <span class=dots3></span>
    <span class=price3>
        $100
      </span>
  </div>

Here instead of wrapping on word boundaries, I'm wrapping on letter boundaries using word-break: break-all. If your font-size is 1em, then this way the maximum gap will be less than 1em, because browser won't be able to fit a letter less than 1em space.

over 4 years ago · Santiago Trujillo Relatório

0

Even the W3C official source has some disparity. You may see inconsistent rendering or poor support for invented features (such as non-monospace/preformatted, lead zero padding, varied currency widths).

Using a shim or Web Component such as Leader-Line would be advisable. I would recommend you experiment with dash-animation to increase visibility on busy backgrounds (at the expense of annoying someone with a busy leader).

over 4 years ago · Santiago Trujillo Relatório

0

Three improvements for the second technique

  1. I suggest using the value multiply for the mix-blend-mode property. In the case of dark text, it gives a sharper result even on a gradient background. Look the first demo.

  2. We can simplify layout of the second technique with a help of the ::first-line pseudo-element. It can be used with "only a small subset of CSS properties", but this subset contains all background-related properties.
    I think this also gives a better result against mix-blend-mode: darken. Compare the second and third demo.

  3. And the gap property helps to set the minimum gap between the text and the price.

There are three demos in the snippet below:

  • First one shows mix-blend-mode: multiply in action.
  • The other two compare the effect of mix-blend-mode: darken on two layouts - with an extra bg block and with the ::first-line pseudo-element.

https://codepen.io/glebkema/pen/NWapXPQ?editors=1100

body {
  color: grey;
}

.width {
  width: 300px;
  padding: 5px;
  resize: horizontal;
  overflow: hidden;
  background: linear-gradient(45deg, yellow, black);
  background-repeat: repeat-x;
  background-size: 200px 100%;
}

.item2 {
  display: flex;
  justify-content: space-between;
  position: relative;
  mix-blend-mode: darken;
  gap: 10px;                 /* 3) */
}

.multiply .item2 {
  mix-blend-mode: multiply;  /* 1) */
}

.item2::before {
  content: '';
  position: absolute;
  top: 1em;
  left: 0;
  right: 0;
  border-bottom: 1px grey dotted;
}

.bg2 {
  background: white;
  position: relative;
  z-index: 1;
}


.price4,
.text4 {
  z-index: 1;
}

.price4,
.text4::first-line {         /* 2) */
  background: white;
}
<h4><code>mix-blend-mode: multiply;</code></h4>
<div class="width multiply">
    <div class=item2>
        <span class=text2>
            <span class=bg2>
                2 Text text
            </span>
        </span>
        <span class=price2>
            <span class=bg2>
                $100
            </span>
        </span>
    </div>
    <div class=item2>
        <span class=text2>
            <span class=bg2>
                2 Text text text text text text text text text text text text text text text text text
            </span>
        </span>
        <span class=price2>
            <span class=bg2>
                $100
            </span>
        </span>
    </div>

    <br />

    <div class=item2>
        <span class=text4>
            4 Text text
        </span>
        <span class=price4>
            $100
        </span>
    </div>
    <div class=item2>
        <span class=text4>
            4 Text text text text text text text text text text text text text text text text text
        </span>
        <span class=price4>
            $100
        </span>
    </div>
</div>

<h4><code>mix-blend-mode: darken;</code> (2nd method before 4th)</h4>
<div class="width">
    <div class=item2>
        <span class=text2>
            <span class=bg2>
                2 Text text
            </span>
        </span>
        <span class=price2>
            <span class=bg2>
                $100
            </span>
        </span>
    </div>
    <div class=item2>
        <span class=text2>
            <span class=bg2>
                2 Text text text text text text text text text text text text text text text text text
            </span>
        </span>
        <span class=price2>
            <span class=bg2>
                $100
            </span>
        </span>
    </div>

    <br />

    <div class=item2>
        <span class=text4>
            4 Text text
        </span>
        <span class=price4>
            $100
        </span>
    </div>
    <div class=item2>
        <span class=text4>
            4 Text text text text text text text text text text text text text text text text text
        </span>
        <span class=price4>
            $100
        </span>
    </div>
</div>

<h4><code>mix-blend-mode: darken;</code> (4th method before 2nd)</h4>
<div class="width">
    <div class=item2>
        <span class=text4>
            4 Text text
        </span>
        <span class=price4>
            $100
        </span>
    </div>
    <div class=item2>
        <span class=text4>
            4 Text text text text text text text text text text text text text text text text text
        </span>
        <span class=price4>
            $100
        </span>
    </div>

    <br />

    <div class=item2>
        <span class=text2>
            <span class=bg2>
                2 Text text
            </span>
        </span>
        <span class=price2>
            <span class=bg2>
                $100
            </span>
        </span>
    </div>
    <div class=item2>
        <span class=text2>
            <span class=bg2>
                2 Text text text text text text text text text text text text text text text text text
            </span>
        </span>
        <span class=price2>
            <span class=bg2>
                $100
            </span>
        </span>
    </div>
</div>

over 4 years ago · Santiago Trujillo Relatório

0

You can modify technique 1 to move the dot functionality from the text to another span:

<div class=item1>
  <span class=text1>
    Text
  </span>
  <span class=line1></span>
  <span class=price1>
    $100
  </span>
</div>
<div class=item1>
  <span class=text1>
    Text text text text text text text text text text text text
  </span>
   <span class=line1></span>
  <span class=price1>
    $100
  </span>
</div>
<div class=item1>
  <span class=text1>
    Text text text text text text text text text text text text
  </span>
</div>
.item1 {
  display: flex;
}
.line1 {
  flex-grow: 1;
  position: relative;
  overflow: hidden;
}
.line1::after {
  content: '';
  position: absolute;
  bottom: 0;
  border-bottom: 1px dotted grey;
  width: 100%;
}
.price1 {
  align-self: flex-end;
}

This works as intended:

This is the output

And a JSFiddle

over 4 years ago · Santiago Trujillo Relatório

0

.item1 {
  display: flex;
  font-size:32px;
  color:#808080;
}
.line1 {
  flex-grow: 1;
  position: relative;
  overflow: hidden;
}
.line1::after {
  content: '';
  position: absolute;
  bottom: 0;
  border-bottom: 1px dotted #808080;
  width: 100%;
}
.price1 {
  align-self: flex-end;
}
<div class=item1>
  <span class=text1>Text text</span>
  <span class=line1></span>
  <span class=price1>$100</span>
</div>
<div class=item1>
  <span class=text1>Text text text text text text text text text</span>
   <span class=line1></span>
  <span class=price1>$100</span>
</div>
<div class=item1>
  <span class=text1>Text text text text text text text</span>
</div>

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda