What is the best way to ensure that the background of wrapped text extends precisely to the pixel distance of the text?

Having a simple issue that I believed could easily be solved with modern CSS, but I'm now confused. I was aiming to have the background of a text parent span precisely across the width of its longest text line, evenly spreading on the sides, different from how the span element behaves.

Block elements naturally occupy 100% width, and inline-block would have been fine if not for the auto-wrapping mechanism of text, which sizes the bounding box to 100% as it wraps to the line below for the first time.

I simulated the desired effect, but these workarounds seem somewhat messy. I'm looking for a simpler, native solution.

Fiddle + simulation: https://jsfiddle.net/sxmkonLp/20/

Standard block element text

<div class="container normal">
  <h1 class="fill">Gonna wrap my text around</h1>
</div>

Parent element display: "inline-block" (slightly closer)

<div class="container">
  <h1 class="fill inl-blk">Gonna wrap my text around</h1>
</div>

Text inside "span" element (closer to what I need, but not evenly spread on the sides, varies based on each line's length)

<div class="container">
  <h1>
    <span>Gonna wrap my text around</span>
  </h1>
</div>

Desired result (emulating text breaks with br and classes)

<div class="container text-span">
  <h1 class="fill2 inl-blk">Gonna<br class="sm4"> wrap<br class="sm3"> my<br class="sm2 sm4"> text<br class="sm1 sm3 sm4"> around</h1>
</div> 

CSS for the markup

html, body {
  text-align: center;
  margin: 0;
  padding: 0;
}

.container {
  padding: 10px;
  width: auto;
  background: orange;
  margin: 10px;
}

.container span {
  background: lightgreen;
  padding: 5px;
}

.inl-blk {
  display: inline-block;
}

.fill {
  background: yellow;
}
.fill2 {
  background: blueviolet;
  color: white;
}

.sm1,.sm2,.sm3,.sm4 {display: none;}

@media screen and (max-width: 470px) {
  .sm2 {display: none;}
  .sm3 {display: none;}
  .sm4 {display: none;}
  .sm1 {display: block;}
}
@media screen and (max-width: 350px) {
  .sm1 {display: none;}
  .sm3 {display: none;}
  .sm4 {display: none;}
  .sm2 {display: block;}
}
@media screen and (max-width: 295px) {
  .sm1 {display: none;}
  .sm2 {display: none;}
  .sm4 {display: none;}
  .sm3 {display: block;}
}
@media screen and (max-width: 242px) {
  .sm1 {display: none;}
  .sm2 {display: none;}
  .sm3 {display: none;}
  .sm4 {display: block;}
}

In the last example (purple box), you can see that the background occupies the exact space of the text boundary. The challenge is achieving this while the text automatically wraps to the line below.

I recently stumbled upon some interesting CSS properties like "box-decoration-break: clone;" which makes a span's content resemble separate block lines, yet still extends across varying line lengths, rendering it unsuitable for my current requirements. It would be fantastic to have a CSS property specifically for that.

Answer №1

Here is a simple JavaScript solution I came up with for this issue. Over time, most websites accumulate a significant amount of JavaScript, making this solution quite manageable. All we require is the "ResizeSensor" from the fantastic "css-element-queries" package.

First, we create a basic container that contains a title with an h1 tag and a div with the class "title-bg" that serves as a virtual responsive background for the title. This div takes the exact width of the text within the h1 tag, which has its display set to inline.

<div class="container">
  <div class="title">
    <h1>Should I learn Scratch before programming?</h1>
    <div class="title-bg"></div>
  </div>
</div>

Below is the CSS code. Note that the ".title-bg" class is positioned absolutely and requires a "transform-50%" solution to stay centered. Additionally, setting z-index: 1 for the h1 tag is necessary for visibility.

.container {
  max-width: 800px;
  min-height: 320px;
  padding: 20px;
  background: #ccc;
  margin: auto;
  text-align: center;
}

.title {
  overflow: hidden;
}

.title h1 {
  display: inline;
  position: relative;
  z-index: 1;
}

.title-bg {
  background: teal;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

For the JavaScript part, we simply need to set the ResizeSensor to listen for events. In my experience, directly applying it to the h1 element (with display set to inline) did not work, so I attached it to the title div instead. The remaining steps involved retrieving values from h1.offsetWidth, which correspond to the text length. And there you have it, a ready and functional solution!

let title = document.querySelector('.title')
let h1 = document.querySelector('.title h1')
let titleBg = document.querySelector('.title-bg')

// Set initial width and height
titleBg.style.width = `${h1.offsetWidth}px`
titleBg.style.height = `${h1.offsetHeight}px`

// Initialize ResizeSensor to auto-update on element resize
new ResizeSensor(title, ()=> {
    titleBg.style.width = `${h1.offsetWidth}px`
    titleBg.style.height = `${h1.offsetHeight}px`
})

Feel free to try it out yourself: http://jsfiddle.net/ktdfqhzo/52/

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

Button Hover Effect: Transition with Style

I am trying to implement a one-second transition from the default color scheme to the hover color for a Button element in Material UI. I am using the transitions.create(props, options) method as described in this article: https://medium.com/@octaviocoria/c ...

How can I extract the HTML value of a JSON array element using jQuery?

My jQuery function takes PHP JSON encoded data as an argument. function html_modify(html) { var str = JSON.stringify(html); var arr = $.parseJSON(str); var tot = ''; $.each(arr, function(i, val){ if(i == 'options') { ...

What is the best way to emphasize a row in an Angular Material table based on a

I am facing an issue with highlighting row colors conditionally in my code. Although there are no errors, the background color is not being applied to the rows as expected. I have a total of 5 rows with the 'riskIndex' value set to 'H'. ...

Utilize JavaScript to parse HTML content retrieved through AJAX requests

My current project involves writing JavaScript code, specifically a Chrome extension, that needs to: Retrieve the contents of a web page using AJAX. Extract specific content from the page by identifying certain elements within the HTML string and retriev ...

CSS: Eliminate unnecessary space at the top by implementing a margin and padding reset

I am puzzled by the presence of approximately 10px of whitespace at the top of my HTML file. Despite setting margin and padding to 0 in the "body" section of my CSS, the whitespace persists. Any suggestions? Thank you! Update: I discovered that removing t ...

I'm a complete programming newbie and I want to start learning JavaScript, jQuery, and other programming languages. Where should I

Coming from a design background with zero programming knowledge, I have recently learned XHTML and CSS. Now, I am eager to expand my skills by mastering JavaScript, jQuery, and more. Where should I begin? This will be my first foray into programming. Whil ...

Safari re-downloads background image when revisiting with jQuery CSS

Using jQuery to set a background-image on my website: $('.header-image').css('background-image', 'url(/img/image.jpg)'); However, upon returning to the page from Safari, the image is downloaded again, unlike Chrome and F ...

Place an overlay element in the top-left corner of a perfectly centered image

Currently, there is an image that is centered on the screen using flexbox: .center-flex { display: flex; justify-content: center; } <div class="center-flex"> <img id="revealImage"> </div> An attempt is be ...

Revive the design of a website

As I work on creating my own homepage, I came across someone else's page that I really liked. I decided to download the page source and open it locally in my browser. However, I noticed that while the contents were all there, the style (frames, positi ...

Having trouble getting SCSS to function properly? (Updated Code)

Transitioning from CSS to SCSS is my current project. I decided to make the switch because of SCSS's nesting capabilities, which I find more convenient for coding. However, I'm facing some challenges getting it to work properly. In my regular CSS ...

Unleash the power of CSS3 to style this button

I received an image of a button that I need to replicate on a website, but unfortunately, only the image was provided without any information about the font-family or size. Despite not being a designer or CSS expert, I attempted to create a CSS style that ...

Guide to dynamically loading HTML and scripts as requested by the user

As I embark on creating my first single page application, I am faced with a challenge. The application contains an overwhelming amount of HTML code that I do not want to be loaded all at once on the client side. Instead, I would like to load the HTML conte ...

Is there a CSS3-compatible CSS parser available in C/C++?

Are there any C/C++ CSS parsers that currently support CSS3? I have come across a few, but none of them seem to offer full CSS3 compatibility. ...

Any tips on creating a smooth fade effect for Bootstrap tabs when sliding to the edges on smaller screens?

Is it possible to make the text fade when it reaches the red highlighted area and also on the search icon on the left? These tabs slide left and right on smaller screens as they are bootstrap tabs. I attempted to add opacity to the text at (min-width: 320p ...

Fluid and static containers in Bootstrap offer flexible and fixed-width layout

I am experimenting with combining fluid containers and fixed containers within a single page layout using Bootstrap. For example, I want to have a large image as a hero unit that spans 100% of the width and height of the viewport, or three column images e ...

A guide to placing tooltips dynamically in highcharts column charts

I am encountering an issue with tooltips in Highcharts column charts. The problem arises when the series fill up my chart, causing the tooltip to be hidden below the series and cut off by the end of the div. You can see an example here: https://i.stack.i ...

Designing div arrangements

I am trying to create a layout of divs similar to the one shown in the image: https://i.sstatic.net/DLUe8.png The challenge I am facing is that I need to arrange them in a row, with one large div in the center and four smaller divs on the sides. I am plann ...

Tips on inline password field placement for a better user interface experience?

While creating a registration form, I ran into a user interface problem. There are two specific changes I'd like to make: The label for Confirm Password should be inline on the same line. The password input should have an eye icon embedded within it ...

ajax and codeigniter combination for selecting options

Is it possible to implement a set_select option within an AJAX component for a dynamic dependent dropdown list that is being cleared after validation errors? I am looking to incorporate the set_select functionality in the code snippet below: <script ty ...

Should I use a tooltip or a pop-up for the tablet version?

I'm currently working on a web application that involves presenting 10 questions, each with 3 possible answers. For each answer, I require a tooltip or popover that provides guidance. While I have attempted to use tooltips and popovers, there is an is ...