Issue with CSS line height - Struggling to determine the precise number of lines

Despite finding an old post on this topic, the most popular answer and other solutions didn't work for many people. Even years later, I am still facing the same issue.

My goal is to create a div that is precisely 19 lines tall (ideally aiming for 19.5 lines so there's always half a line visible when scrolling through more text, but starting with 19). However, as I adjust my browser window size, I notice various fractional overflows of text occurring - which is exactly what I want to avoid. Currently, around 19 lines and approximately half are displayed:

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

Below you can see the CSS I'm using for both the outer div mentioned above and the inner darker div:

#marquee-dialog > div {
  font-size: 3vh;
  line-height: 3.6vh;
  position: absolute;
  margin: auto;
  top: 0; left: 0; bottom: 0; right: 0;
  width: 80vw;
  height: 80vh;
  padding: 1em;
  background-color: white; /* Changed via JavaScript later */
  color: black;
}

#marquee-big-text {
  font-size: 3vh;
  line-height: 3.6vh;
  max-height: 22.8em;
  overflow: auto;
}

I have set the line height to be 1.2 times larger than the font size, and the max-height to be 19 * 1.2 = 22.8 em. Despite these adjustments, it seems like the exact number of lines should be achieved to the best of floating point precision.

Upon checking the web console, the height of the div appears to be almost exactly 19 times the line height and nearly 22.8 times the em size, as confirmed by examining the size of the padding of the outer div.

The inner div has no padding, margin, or border to disrupt the calculations.

Although all numeric values seem to align to give me the desired 19 lines, the rendering displays just slightly more. This overflow is observed on Chrome, Firefox, and Safari alike.

Is there something obvious that I might be missing?

UPDATE

I attempted using exact pixel values derived from the web console:

#marquee-big-text {
  font-size: 3vh;
  line-height: 31.968px; /* 3.6vh; */
  max-height: 607.392px; /* 22.8em; */
  overflow: auto;
}

Even after implementing these close-to-exact values for 19 lines, the issue persists.

UPDATE 2

After taking some measurements from a screenshot, I determined that each rendered text line measures 62 pixels in height from baseline to baseline. The entire div spans 1212 pixels in height. Based on these measurements, roughly 19.55 lines should fit within the space, explaining the discrepancy between the expected and actual number of lines. To achieve a closer match to 19 lines, the baseline-to-baseline measurement should be approximately 63.79 pixels, representing around 2 additional pixels per line.

This anomaly appears akin to a rendering round-off error, although it is peculiar that such consistent discrepancies exist across different browsers.

UPDATE 3

Here is a functional example:

https://codepen.io/kshetline/pen/NWNGOWL

Intriguingly, despite simplifying the example, the issue persists in Chrome and Safari, while Firefox consistently renders correctly.

You may need to switch the Codepen view to this orientation:

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

...to observe the problem. This bug tends to manifest prominently at larger font sizes, where even resizing the browser window only slightly exceeds half a line before reverting back to 19 lines. At this point, it strongly suggests a font-size round-off error, potentially linked to rendering optimization strategies aimed at preventing caching of significant variations in font size.

Answer №1

While this answer may not be what I originally had in mind, it offers a solution using JavaScript to tackle the issue at hand. It appears that I need to mandate the use of integer pixel sizes in order to consistently achieve precise line counts.

const middiv = document.querySelector('.outer > div');
const inner = document.querySelector('.inner');
let lastLineHeight = 0;

function checkFont() {
  const style = document.defaultView.getComputedStyle(middiv, null);
  const exactHeight = parseFloat(style.getPropertyValue('line-height'));
  const roundedHeight = Math.floor(exactHeight);

  if (lastLineHeight !== roundedHeight) {
    inner.style.lineHeight = roundedHeight + 'px';
    inner.style.maxHeight = (roundedHeight * 19) + 'px';
    lastLineHeight = roundedHeight;
  }
}

window.addEventListener('resize', checkFont);
checkFont();

You can view a demo of this code on Codepen: https://codepen.io/kshetline/pen/vYGLjBo

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

Tips for adding a new column to a website

My goal is to inject some custom HTML and CSS into YouTube in order to create a column on the right side that shifts all content towards the left. Essentially, I am trying to replicate the functionality of the Inspect Tool in Chrome. I am working on a Chr ...

Troubleshooting a problem with the navigation links on a single-page website with a

https://i.sstatic.net/5xcv9.png My website alampk.com features a single page layout with a fixed navbar at the top. However, when I click on links like exp, portfolio, etc., the section moves to the top but a portion of 50px gets covered by the navbar. I ...

jQuery registers the enter event, but does not proceed to trigger the enter action

Hey there, I've been experimenting with jQuery to capture the enter event. Something peculiar is happening though - after pressing enter in the text area, an alert pops up but the text gets entered only after that. Despite trying various solutions, I ...

React eliminates all white spaces

Presented here is a compilation of various span elements: <span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span> Accompanied by the CSS style for these elements: span{ bac ...

List organized in two columns utilizing the data-* attribute

Is it possible to display a list in a two-column format based on a data attribute of each item? <ul> <li data-list="general_results">general text1</li> <li data-list="general_results">general text2</li> <li dat ...

Create a right-to-left (RTL) CSS file within a create-react-app project and dynamically switch between them depending on changes

I am currently working on a multi-language project using create-react-app. My goal is to incorporate a library like "cssJanus" or "rtlcss" to transform the Sass generated CSS file into a separate file. This way, I can utilize the newly created file when sw ...

Discovering the proper method to reach the parent element in jQuery while within the click event

How can I use jQuery to access the parent element within a click event? $(document).ready(function () { $(".lv1 li").click(function (event) { this.parentElement.parentElement.textContent = this.textContent; $.ajax({ type: 'post&apo ...

Is there a problem with textbox support for multi-line strings?

I'm having trouble getting a textbox to display multiple lines of text. For instance, when I copy three lines of text from Microsoft Word and paste it into the textbox, only the first line appears. The other two lines are not showing up, and I'm ...

Retrieve jQuery CSS styles from a JSON database

I've been attempting to pass CSS attributes into a jQuery method using data stored in a JSON database. However, it doesn't seem to be functioning as expected. I suspect that directly inputting the path to the JSON variable may not be the correct ...

Is there a way to prevent the page's navbar from getting hidden under the slide animation? I want to display the navbar separately at the top, with animations working as usual

I'm struggling with getting my navigation bar to work properly alongside a slide animation. No matter what I try, the navbar keeps overlapping. Here's the code I have so far: Here is the HTML section: Navbar section: <ul class="slidesho ...

Struggling to extract information from HTML code through Python web scraping techniques

Hello there! I'm currently in the process of extracting dividend history data for a specific stock from a website using web scraping in Python. However, being new to Python, I'm facing some challenges in retrieving the data. Below is a snippet of ...

Incorporate a dynamic form into an ngx-sortable control in Angular 6

Having difficulty with the layout implementation in Angular 6. A form component is dynamically added during runtime. Using ngx-sortable, I aim to have dynamic content within it, but am facing challenges with the setup. Implementing Sortable control: &l ...

Alignment of the table with a fixed header and scrollable body

Currently, I am experiencing an issue with aligning a table. My aim is to have a fixed header and a scrollable body for the table. To do this, I have aligned the table header and body using: display: table-header-group For the table body, I have applied ...

Do not incorporate a div in the overlay

I have an image inside a container. When hovering over the image/container, overlay information is displayed (which is currently working correctly). The overlay should cover the entire container (the grey part) where the image is located. The product-tit ...

Tips for eliminating the border from a Bootstrap dropdown menu in the navigation bar

I am utilizing the Bootstrap 5 navigation bar and trying to figure out how to remove the blue border from the "Dropdown" when clicked on. Despite my efforts to find a solution, I have been unsuccessful. <nav class="navbar navbar-expand-lg navbar ...

on clicking GTM, obtain a different child element

My HTML code is structured as follows: <div onclick="location.href='https://ford-parts-accessories.myshopify.com/products/ash-cup-coin-holder-with-lighter-element?refSrc=6748959244479&amp;nosto=productpage-nosto-1-fallback-nosto-1';&q ...

The transition effect for the box shadow is being altered to modify the dimensions

--- UPDATE 2 ---- Here is a different example video showcasing the bizarre behavior of my react application. I am struggling to identify the root cause of this issue. See the issue in action I have a div with the class name side-btn It contains an anim ...

Issue with background/hero video not adjusting its size

I've been experimenting with creating a page that features a video as the background, but no matter what I try, the video never seems to resize properly. The image below shows how it looks: image in question body { margin: 0; } .hero-se ...

Revealing a concealed element by sliding it upwards on a single page, then repeating the

Can someone assist me in achieving a specific effect on my website? I have a top banner section with a button at the bottom. When the button is clicked, a form should slide up into view. The form will initially be hidden. I also need the same effect at the ...

I'm curious about the process behind this. Can I copy a Figma component from a website and transfer it into my

Check out this site for an example: Interested in how uikit.co/explore functions? By hovering over any file, a copy button will appear allowing you to easily paste it into your Figma artboard. Want to know how this works and how to implement it on your o ...