Designing a CSS dot leader on the top line against a intricate backdrop

I am looking to incorporate dot leaders after the first line of text using CSS so that it can be used over a texture or image background.

Expected behavior:

https://i.sstatic.net/6Jsrk.png

I have come across a few implementations of dot leaders on the internet. They all utilize one of the following techniques:

  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;
}

All these methods are demonstrated here: https://jsfiddle.net/rzmLg4yu/62/

However, each technique has its drawbacks in my particular scenario.

  1. Dot leaders appear at the last line.
  2. It does not function well over complex backgrounds, even with mix-blend-mode (uncomment bg line to see). https://i.sstatic.net/lfk1j.png
  3. There are significant white gaps due to line breaks (resize to view). Transitioning to grid layout does not solve the issue. https://i.sstatic.net/KK4vj.png

Are there any other solutions to address this problem?

Answer №1

Enhancing Technic 3 to eliminate 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 evenly space the words.


Your concern with the second technique is related to the white background color correct?
due to .bg2 {background: white;...}?
Alternatively, you could've utilized mix-blend-mode: lighten; to showcase 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.


Refining technic two without a white background:

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 utilizing a white underline instead of an entire white background to hide the dot leader. However, some blend modes may result in a white underline.


Improving technic three by breaking words when 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. This way, if your font-size is 1em, the maximum gap will be less than 1em because the browser won't be able to fit a letter in less than 1em space.

Answer №2

Enhancements for the second technique

  1. Consider utilizing the multiply value for the mix-blend-mode property. When dealing with dark text, it provides a crisper outcome even against a gradient background. Take a look at the initial demonstration for reference.

  2. The layout of the second technique can be streamlined using the ::first-line pseudo-element. While it supports only a limited set of CSS properties, this subset includes all background-related attributes. This adjustment could yield superior results compared to mix-blend-mode: darken. Compare the outcomes of the second and third demos to see the difference.

  3. Incorporating the gap property allows you to define the minimum space between the text and the price information.

Explore three demos in the provided code snippet:

  • The first demo showcases the impact of mix-blend-mode: multiply.
  • The remaining two demos illustrate the influence of mix-blend-mode: darken on two different layouts—one with an additional bg block, and the other incorporating the ::first-line pseudo-element.

View the live demos here

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>

Answer №3

Even the information found on the W3C official website can have discrepancies. Inconsistencies in how content is displayed or lack of support for certain features like non-monospace/preformatted text, lead zero padding, and varying currency widths may be observed.

To address these issues, considering using a shim or Web Component like Leader-Line could be beneficial. Experimenting with dash-animation might also help improve visibility against busy backgrounds, although it could potentially distract users who are focused on the content.

Answer №4

If you want to enhance technique 1, you can transfer the dot functionality from the text to a separate span:

<div class="item2">
  <span class="text2">
    Sample Text
  </span>
  <span class="line2"></span>
  <span class="price2">
    $50
  </span>
</div>
<div class="item2">
  <span class="text2">
    More text more text more text more text more text more text
  </span>
   <span class="line2"></span>
  <span class="price2">
    $75
  </span>
</div>
<div class="item2">
  <span class="text2">
    Additional text additional text additional text additional text
  </span>
</div>
.item2 {
  display: flex;
}
.line2 {
  flex-grow: 1;
  position: relative;
  overflow: hidden;
}
.line2::after {
  content: '';
  position: absolute;
  bottom: 0;
  border-bottom: 1px dashed black;
  width: 100%;
}
.price2 {
  align-self: flex-end;
}

This implementation functions as desired:

https://i.sstatic.net/jNuR4.png

Check out the JSFiddle example here

Answer №5

.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>Some Text Here</span>
  <span class=line1></span>
  <span class=price1>$100</span>
</div>
<div class=item1>
  <span class=text1>Different Text Shown Here for Demo</span>
   <span class=line1></span>
  <span class=price1>$100</span>
</div>
<div class=item1>
  <span class=text1>Text Example Lorem Ipsum Dolor Sit Amet</span>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can WebGL be configured to render offscreen without its canvas being directly connected to the DOM?

Searching for an answer to what I believed would be a simple question has proven to be quite challenging. My goal is to utilize WebGL for image processing and generation tasks, with the intention of working offscreen. Specifically, I aim for WebGL to rende ...

I want to display a div above an image when hovering over it

.vpbutton {padding:4px;background-color:#EFEFEF;} .userbox img{padding:8px;background-color:#EFEFEF;} .userbox img:hover{opacity:.2;} <div class="userbox"> <img src='img.png' style='height:120px;width:120px;border:1p ...

How to center align a Bootstrap 4 Navbar using CSS

Having trouble center-aligning your Bootstrap 4 navbar in your Angular code base? You're not alone. I too wanted to reduce the gaps between menu items when transitioning from one to another. Below you'll find snippets of my HTML, TS, and CSS: M ...

Padding provides varying padding for the top and bottom sections

html { font-size : 10px; } body { text-align : center; color : #9da8c1; font-family : sans-serif; background : #013f81; } h1 { font-size: 4rem; } #img-div { background : #2a5590; width : 600px; margin : 0 auto; pad ...

What is the best method for closing the open portion of an accordion menu?

I'm experimenting with creating a collapsible accordion feature, but I'm facing a challenge in figuring out how to close the currently open accordion pane. The accordion functions smoothly when expanding sections, but I'm stuck on how to col ...

Problem with fixed element on mobile due to viewport width

I am experiencing an issue with the fixed element's width. Here is a code snippet for reference: https://codepen.io/highfield/pen/PKpXGG <body> <nav class="navbar"> <div style="position:absolute; left:20px; top:12px"> & ...

Is there a way to enclose a mention within a unique span tag after highlighting it? Similar to how tags are implemented on platforms such

Currently utilizing an AngularJS plugin called ment.io for incorporating mentions. However, I am having difficulty figuring out how to customize the appearance of the selected mention. For example, in Stackoverflow: https://i.sstatic.net/bZrkh.png Or i ...

Turn off the extra space inserted by DataTables

Help needed with centering table header text. <table class="table table-bordered table-hover center-all" id="dataTable"> <thead> <tr> <th scope="col" style="text-align: center">Nam ...

What is the best way to assign attributes to multiple HTML elements using an array?

Seeking assistance to hide various sections in my HTML file upon button click, with the exception of one specific section. Encountered an error message: Uncaught TypeError: arr[i].setAttribute is not a function Here's a snippet of my code: const hide ...

modify rectangular section in drupal rather than numerical block

Currently, I am attempting to modify blocks within my Drupal 7.x website using the Zen base theme. While I have been successful in adjusting the CSS styles of the blocks based on their numbers in the block.css file, I find this method quite confusing. Is ...

Display the importance of utilizing Bootstrap 4's range input feature

Is there a way to display the value of a range input in Bootstrap without using Javascript? I found this tutorial but it doesn't show how to do it: https://getbootstrap.com/docs/4.1/components/forms/#range-inputs <div class="container"> < ...

Move images horizontally next to the height of an element

I am attempting to increase the top attribute in relation to the element it is currently adjacent to. The element should only scroll directly next to the other element and cease when it surpasses the height of that element. My Goal: I want the image to re ...

Looking for way to trigger a MP3 player to play songs simply by clicking on them using an <a> tag?

I created a selection of songs in my <a> tags and I am looking to implement a universal mp3 player that will play the selected song without needing to refresh the page or open it in a new tab. I want the song to play directly on the player when click ...

Is there a way for me to set a different color for the background below the svg and a separate color above the svg? I am hoping to achieve this unique design effect

I am looking to create a distinctive background design with different colors above and below an svg image. I have set a background image for the body element and will be using a grid layout with a transparent background color above it. My challenge is fin ...

Ensure that the data prop in Vue is always updated whenever there is a change in

In my Vue.js project, I am creating a data property called w to store the clientWidth of a specific element in my HTML. In the mounted hook, I am initializing it like this: data() { return { w: 0, }; }, mounted() { this.w = this.$refs.timelineProgres ...

Action buttons on material cards extend beyond the boundaries of the card content on both the left and right sides

Check out this Angular 10.2 Material sample where the action buttons on the right and left extend beyond the card-content: https://i.sstatic.net/Btxy1.png The "Create account" button's right edge should align with the right edge of the fields, and t ...

Ensure that the content inside the centrally aligned div is also aligned at the

Looking for a way to center a box on a website I'm designing? Instead of aligning it based on existing centering, use the following HTML / CSS code to ensure that the white box is perfectly centered on the page. .loading { position: fixed; z-in ...

Collapsing or expanding the Material UI accordion may lead to flickering on the page

import React from "react"; import { makeStyles } from "@material-ui/core/styles"; import Accordion from "@material-ui/core/Accordion"; import AccordionDetails from "@material-ui/core/AccordionDetails"; import Accordi ...

Find the final element that does not include a particular class

Looking for the best way to identify the last item in a list without a specific class? Learn how to write code that can check for the absence of a class name. $('ul li:last') $('ul li:not(.special)') ...

Tips for synchronizing text field and formula field content on MathQuill 0.10

I am currently working on creating a WYSIWYGish input element for my formula, along with a LaTeX input element. <span id="editable-math" class="mathquill-editable"></span> The goal is to make these two elements work synchronously. Here's ...