Absolute positioning causes an element's height to increase

As I delve into the realm of typographical animations and seek to calculate the baseline of a font at various sizes, I've stumbled upon a peculiar discovery: It appears that the height values of elements tend to increase in an erratic manner when their position is switched to absolute.

Heights without Position Absolute (tap to log heights)

const
  small = document.querySelector('#small'),
  large = document.querySelector('#large')

window.onclick = () => {
  console.log(small.getBoundingClientRect().height,
              large.getBoundingClientRect().height)
}
div {
  border: solid purple 2px;
}

#small {
  border: solid red 2px;
}

#large {
  border: solid black 2px;
  font-size: 10rem;
}
<div>
  <span id='small'>.</span>
  <span id='large'>.</span>
</div>

Heights with Position Absolute (tap to log heights)

const
  small = document.querySelector('#small'),
  large = document.querySelector('#large')

window.onclick = () => {
  console.log(small.getBoundingClientRect().height,
              large.getBoundingClientRect().height)
}
div {
  border: solid purple 2px;
}

#small {
  border: solid red 2px;
}

#large {
  border: solid black 2px;
  font-size: 10rem;
}

span {
  position: absolute;
}
<div>
  <span id='small'>.</span>
  <span id='large'>.</span>
</div>

Could someone shed light on this phenomenon?

Answer №1

Discover the secret lies within the display method, with no clear correlation to the height values due to differing calculations in each case.

For inline elements in the first scenario, expect the 'height' property not to apply as the content area's height is based on font properties such as the em-box or maximum ascender and descender. The vertical padding, border, and margin for an inline non-replaced box start at the top and bottom of the content area, unrelated to line-height calculations.ref

The span's height depends solely on font properties (font-family, font-size) along with the border top/bottom. Without delving into specific font details, it becomes challenging to pinpoint the exact calculation method.

Related:

Can specific text character change the line height?

What determines the space between the highest and lowest letter and the top and bottom border of the element the letter's in?


In the second instance, the span evolves into a block element through the use of position:absolute. Following the rule here: https://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height, the height now equals the distance between the topmost and bottommost line boxes.

Thus, our element's height aligns with the line box defined by line-height, impacted by both line-height and vertical alignment but simplified when dealing with single characters.

Adjusting the default line-height set by the browser can yield desired height results:

const
  small = document.querySelector('#small'),
  large = document.querySelector('#large')

window.onclick = () => {
  console.log(small.getBoundingClientRect().height,
              large.getBoundingClientRect().height)
}
div {
  border: solid purple 2px;
}

#small {
  border: solid red 2px;
  line-height:1; /* will give a height = 1*16 + 4 */
}

#large {
  border: solid black 2px;
  font-size: 10rem;
  line-height:1; /* will give a height = 1*10*16 + 4 */
}

span {
  position: absolute;
}
<div>
  <span id='small'>.</span>
  <span id='large'>.</span>
</div>

Related: How does height will be calculated, based on font-size?


Converting the span element to inline-block produces parallel behavior to the second case following rules detailed here: https://www.w3.org/TR/CSS21/visudet.html#block-root-margin, leading to identical outcomes seen with absolute elements (https://www.w3.org/TR/CSS21/visudet.html#root-height). In this context, line-height dictates the element's height:

const
  small = document.querySelector('#small'),
  large = document.querySelector('#large')

window.onclick = () => {
  console.log(small.getBoundingClientRect().height,
              large.getBoundingClientRect().height)
}
div {
  border: solid purple 2px;
}

#small {
  border: solid red 2px;
  display:inline-block;
  line-height:1;
}

#large {
  border: solid black 2px;
  font-size: 10rem;
  display:inline-block;
  line-height:1;
}
<div>
  <span id='small'>.</span>
  <span id='large'>.</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

Show the components only if the final digit in their identification number is less than i

I have several span elements with IDs like "tag1", "tag2", etc. I want to display only the spans whose ID ends with a number less than 19. These elements are part of a class called "notVis", which is hidden by default using $(".notVis").hide(); when the ...

The file field appears to be empty when sending a multipart/form-data request via AJAX

I'm encountering an issue when attempting to submit a multipart/form-data using AJAX. Here is the HTML code snippet: <form id='form_foto' method='post' enctype='multipart/form-data'> <input type='hidden ...

Tips on causing JavaScript execution to halt until an element has finished rendering

test.view.js timeDBox = new sap.ui.commons.DropdownBox({layoutData: new sap.ui.layout.GridData({linebreak: true}), change: function(oEvent){ oController.getKeyEqChart(); }, }), new sap ...

What method can I use to locate the double quote option within an HTML select element using jQuery?

Here is an example of the select: <select id="id0" name="name0"> <option value='30" size'> 30" size </option> </select> The select contains double quotes. I am trying ...

Adjust the button's hue upon clicking it

The current function is operational. Upon pressing the button, it toggles between displaying "click me" and "click me again". However, I desire the button to appear blue when showing "click me" and red when displaying "click me again". <!DOCTYPE html ...

Personalized Tumblr-style button

Hey there, I've been working on creating a custom Tumblr-like button and tried adding an iframe above it to make it clickable. However, something seems to be off as it's not functioning properly. I'm still trying to wrap my head around how i ...

The usage of ngRoute clashes with the functionality of Animated Scroll

I am experiencing a conflict between my ng-route and the animated scroll feature on my website: Below is the code for my scroll element: <a href="#one" class="goto-next scrolly">Next</a> In this code, "#one" represents the section ID to scro ...

"Experience the power of using Selenium with Node.js in an asynchronous function

I'm currently developing a simple program that retrieves the titles of all the links when conducting a search on Google using Selenium Take a look at the code below: const {Builder,By, Key, until} = require('selenium-webdriver'); driver = ...

What is the method for obtaining the viewModel in a Knockout component?

I need to prepopulate a knockout component when the document is ready. This is the code I have written: function Finding(id, trigger) { var self = this; self.id = ko.observable(id); self.trigger = ko.observable(trigger); } function FindingVi ...

Effective way to manage Angular scope without resorting to $parent.$parent

After doing some research, I have not been able to find a solution that addresses my particular issue. Here is what I know: ng-if and ng-repeat create isolated scopes. Avoid using $parent.someProperty. Using $parent.$parent.someProperty is strongly disc ...

Creating Vertical Text and Div Blocks using CSS

Trying to set up different color section blocks with vertical text on my website's dashboard page. Similar to this example in JSfiddle: http://jsfiddle.net/afpn2y19/4/ <div id="outer"> <div id="inner"> //Feeling lost - ho ...

By utilizing the <tr> element, one can enhance the border thickness by 1 pixel

Is it possible to ensure that row selection in a table is consistent in terms of border alignment on both sides? https://i.stack.imgur.com/qmZiQ.png If you have any suggestions or solutions, please share them. Thank you! table { margin: 10px; bord ...

I encountered a "TypeError: Unable to access property 'name' of undefined" error when attempting to export a redux reducer

UPDATE: I encountered an issue where the namePlaceholder constant was returning undefined even though I was dispatching actions correctly. When attempting to export my selector function, I received an error: Here is the component code: import React, { ...

What is the best way to access a DOM node within a withStyle component?

Currently, I am involved in a react project where my team and I are utilizing Material UI. I encountered a situation where I needed to access the DOM node of another component that was wrapped by a HOC. To achieve this, I attempted using ref in React but o ...

Need help resolving the issue of retrieving feed error in Angular?

I am encountering an issue in Chrome that displays an error message: Error fetching feed: Undefined, 0. Do you have any suggestions on how to resolve this? Below is the Angular code I am using: // Implementing SimpleController, with data demoApp.controll ...

"Error: Unable to access the property '$emit' of an undefined value" - VueJS

I'm currently working on implementing a basic authentication system in vuejs. I have a set of objects containing valid usernames and passwords. I am looping through this list to validate the entered username and password. If there is a match, I trigge ...

Is there a way to compel the browser or JavaScript to delete/disregard a cached file?

I've encountered an issue with my Javascript program that extracts data from a text file and displays it in a table. The problem arises when I update the text file - the changes don't reflect on the table because the browser is caching the file. ...

What is the most effective way to display multiple variables simultaneously in Mongoose/Node.js?

As a newcomer to programming, my initial major project involves building a website using Mongoose and Node.js. I have a query regarding rendering two variables for ejs simultaneously without encountering an error due to attempting to render a query that h ...

Ways to output a string array from a JSON object containing additional attributes

On the client side, I have received a JSON object from a REST service. This object contains multiple attributes, one of which is a String array. I need guidance on how to display this array using embedded AngularJS code in HTML. Here is my JSON object: [ ...

Redirect the Submit button to the specified URL from the form element

Looking for a way to create a form with two fields: Username and Password. Upon clicking submit, the username and password should be added to the URL in a specific format. For instance: The URL structure will remain the same, only the "username_entered_i ...