Is there a way to determine the dimensions of an element that is set to "display: none"?

Is it possible to retrieve the dimensions of child elements inside a div that has been hidden with CSS property display: none? If so, how can this be achieved?

Check out the Fiddle Demo here

var o = document.getElementById('output');
var wmd1 = document.getElementById('whats-my-dims1');
var wmd2 = document.getElementById('whats-my-dims2');
o.innerHTML = 'wmd1: "' + wmd1.clientWidth + '", "' + wmd1.clientHeight + '", wmd2: "' + wmd2.clientWidth + '", "' + wmd2.clientHeight + '"';
#some-hidden-div{
  display: none;
}
.whats-my-dims{
  width: 69px;
  height: 42px;
  background-color: #f00;
}
<div id='output'>Processing... :p</div>
<div id='some-hidden-div'>
  <div class='whats-my-dims' id='whats-my-dims1'></div>
</div>
<div class='whats-my-dims' id='whats-my-dims2'></div>

I am looking for a solution using pure JavaScript only (no jQuery).

The restriction is not to modify parameters such as top, left, right, bottom, transform, translate, etc. This is necessary as the functionality will be integrated into an animated sprite sheet custom component with child elements.

Answer №1

Discovering the dimensions of an element is not possible when it has a CSS property of display: none. However, you can toggle the display property to 'block', retrieve the dimensions, and then set it back to hidden without any visual changes.

var o = document.getElementById('output');
var wmd1 = document.getElementById('whats-my-dims1');
var someHiddenDiv = document.querySelector('#some-hidden-div');
someHiddenDiv.style.display = 'block';
var wmd2 = document.getElementById('whats-my-dims2');
o.innerHTML = 'wmd1: "' + wmd1.clientWidth + '", "' + wmd1.clientHeight + '", wmd2: "' + wmd2.clientWidth + '", "' + wmd2.clientHeight + '"';
someHiddenDiv.style.display = 'none';
#some-hidden-div {
  display: none;
}
.whats-my-dims {
  width: 75px;
  height: 42px;
  background-color: #f00;
}
<div id='output'>
  Processing... :p
</div>
<div>
  Sooo... How do I get the width and height of whats-my-dims1?
</div>
<div id='some-hidden-div'>
  <div class='whats-my-dims' id='whats-my-dims1'></div>
</div>
<div class='whats-my-dims' id='whats-my-dims2'></div>


Keep in mind that reverting the display: none using inline styles may result in unnecessary complications (as inline styles override CSS selectors unless marked with !important). In such scenarios, removing the style attribute entirely might be preferable.

In the code snippet below, adding the .show class doesn't have any effect due to the higher precedence of the inline display: none.

var o = document.getElementById('output');
var wmd1 = document.getElementById('whats-my-dims1');
var someHiddenDiv = document.querySelector('#some-hidden-div');
someHiddenDiv.style.display = 'block';
var wmd2 = document.getElementById('whats-my-dims2');
o.innerHTML = 'wmd1: "' + wmd1.clientWidth + '", "' + wmd1.clientHeight + '", wmd2: "' + wmd2.clientWidth + '", "' + wmd2.clientHeight + '"';
someHiddenDiv.style.display = 'none';


var btn = document.querySelector('#show');

btn.addEventListener('click', function() {
  someHiddenDiv.classList.add('show');
});
#some-hidden-div {
  display: none;
}
.whats-my-dims {
  width: 75px;
  height: 42px;
  background-color: #f00;
}
#some-hidden-div.show {
  display: block;
}
<div id='output'>
  Processing... :p
</div>
<div>
  Sooo... How do I get the width and height of whats-my-dims1?
</div>
<div id='some-hidden-div'>
  <div class='whats-my-dims' id='whats-my-dims1'>Some text</div>
</div>
<div class='whats-my-dims' id='whats-my-dims2'></div>

<button id='show'>Show the hidden div</button>

Conversely, there shouldn't be any issues in the following example since the inline style is completely removed.

var o = document.getElementById('output');
var wmd1 = document.getElementById('whats-my-dims1');
var someHiddenDiv = document.querySelector('#some-hidden-div');
someHiddenDiv.style.display = 'block';
var wmd2 = document.getElementById('whats-my-dims2');
o.innerHTML = 'wmd1: "' + wmd1.clientWidth + '", "' + wmd1.clientHeight + '", wmd2: "' + wmd2.clientWidth + '", "' + wmd2.clientHeight + '"';
someHiddenDiv.style = null;


var btn = document.querySelector('#show');

btn.addEventListener('click', function() {
  someHiddenDiv.classList.add('show');
});
#some-hidden-div {
  display: none;
}
.whats-my-dims {
  width: 75px;
  height: 42px;
  background-color: #f00;
}
#some-hidden-div.show {
  display: block;
}
<div id='output'>
  Processing... :p
</div>
<div>
  Sooo... How do I get the width and height of whats-my-dims1?
</div>
<div id='some-hidden-div'>
  <div class='whats-my-dims' id='whats-my-dims1'>Some text</div>
</div>
<div class='whats-my-dims' id='whats-my-dims2'></div>

<button id='show'>Show the hidden div</button>

Answer №2

Utilize the window.getComputedStyle() method

var element = document.getElementById('output');
var firstDim = document.getElementById('dimension1');
var secondDim = document.getElementById('dimension2');
element.innerHTML = 'first: "' + window.getComputedStyle(firstDim).getPropertyValue("width") 
+ '", "' 
+ window.getComputedStyle(firstDim).getPropertyValue("height") 
+ '", second: "' 
+ window.getComputedStyle(secondDim).getPropertyValue("width") + '", "' 
+ window.getComputedStyle(secondDim).getPropertyValue("height") + '"';
#hidden-box{
  display: none;
}
.dimensions{
  display:block;
  width: 50px;
  height: 30px;
  background-color: #0f7;
}
<div id='output'>
  Processing... :D
</div>
<div>
  How can I retrieve the dimensions of dimension1 and dimension2?
</div>
<div id='hidden-box'>
  <div class='dimensions' id='dimension1'></div>
</div>
<div class='dimensions' id='dimension2'></div>

Check out the code on jsfiddle here: https://jsfiddle.net/yj6m92gc/8/

Answer №3

When an element has a CSS property of display: none, it is hidden and does not take up any space on the page, which means it has no dimensions that can be retrieved. This same principle applies to its child elements as well.

To work around this limitation, you can temporarily make the element visible, retrieve the dimensions of its children, and then hide the element again. As mentioned by @JanDvorak:

Browsers do not repaint while synchronous JavaScript is running, so the element should never actually appear on the screen.

Here is an example code snippet:

var o = document.getElementById('output');
var wmd1 = document.getElementById('whats-my-dims1');
var wmd2 = document.getElementById('whats-my-dims2');
var hiddenDiv = document.getElementById("some-hidden-div");
hiddenDiv.style.display = "block";
o.innerHTML = 'wmd1: "' + wmd1.clientWidth + '", "' + wmd1.clientHeight + '", wmd2: "' + wmd2.clientWidth + '", "' + wmd2.clientHeight + '"';
hiddenDiv.style.display = "";

For a live demonstration, check out this JS Fiddle demo.

Answer №4

If you are looking to create a context menu or hint window:

Using the getComputedStyle() method may not work properly on elements with dynamic width/height, as it returns auto.

One solution is to set visibility: hidden and change the display property to something other than none (the value needed to display your element).

I implemented this 3-step process in a context menu component for determining where to position the menu relative to the click location, ensuring it always stays within view:

  1. Set visibility: hidden and remove display: none (set it to what it will be when the menu is shown)
  2. Get the dimensions of the menu
  3. Remove visibility: hidden

This approach may not work if the parent element also has a display: none property, but this wasn't an issue in my use case since one should not access a context menu for an object that isn't visible anyway.

Answer №5

Include the following code snippet:

let elementStyle = window.getComputedStyle(element);
output.innerHTML = 'Element width: "' + parseInt(elementStyle['width'], 10) + '", height: "' + parseInt(elementStyle['height'], 10) + '", wmd2: "' + wmd2.clientWidth + '", "' + wmd2.clientHeight + '"';

Answer №6

In my approach, I have discovered a method that surprisingly works without a clear explanation. Specifically, in the context of my project, I require knowledge of the tab heights to facilitate smooth toggling using vanilla JavaScript.

Here are the steps I follow to calculate the height in JavaScript:

  1. The element is initially displayed with "height:0px" and "overflow:hidden" (instead of "display: none")
  2. I set the element to "height:auto"
  3. I determine the height of the element using the offsetHeight property
  4. The element is reverted back to "height:0px"
  5. Subsequently, I assign the calculated height to the element within a setTimeout function, combined with a CSS transition for smoother animation

Surprisingly, despite initial expectations of animation flickering, it remains stable. This straightforward solution continues to amaze me; however, I welcome alternative ideas or insights into its functioning and any potential drawbacks associated with this technique.

  function toggleTabs() {
    let tabs = document.querySelectorAll('.accordionX a span')
    tabs.forEach(tab => {
      tab.addEventListener('click', function(e) {
        tab.classList.toggle('active')
        if (tab.classList.contains('active')) {
          //hide other tabs
          tabs.forEach(tab => {
            if (tab != e.target) {
              tab.classList.remove('active');
              tab.parentElement.nextElementSibling.style.height = '0px';
            }
          })
          var tabContent = tab.parentElement.nextElementSibling;
          tabContent.style.height = 'auto';
          var tabHeight = tabContent.offsetHeight + 'px'
          tabContent.style.height = '0px';
          setTimeout(function() {tabContent.style.height = tabHeight}, 15)
        } else {
          tab.classList.remove('active');
          tab.parentElement.nextElementSibling.style.height = '0px';
        }
      })
    })
  } toggleTabs();
.accordionX{margin:0px 20px}
.accordionX > li{border-bottom:1px solid #e7e7e7;position:relative;list-style-type:none}
.accordionX > li:first-child{border-top:1px solid #e7e7e7}
.accordionX > li a::after{display:none}
.accordionX > li p{color:#3c3c3b;line-height:1.8;text-align:left}
.accordionX > li > a span{position:relative;color:#3c3c3b;padding-right:5%;display:block;cursor:pointer;font-weight:600;line-height:3;text-indent:15px;user-select:none;-webkit-tap-highlight-color:transparent;border:none!important}
.accordionX > li > a span:after{width:8px;height:8px;border-right:1px solid #3c3c3b;border-bottom:1px solid #3c3c3b;position:absolute;right:18px;top:25px;content:" ";top:50%;transform:translate(0,-50%) rotate(-45deg);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}
.accordionX > li > a span > img {vertical-align: middle;margin-right: 10px;}
.accordionX p{font-size:1em;padding:10px 15px 0}
.accordionX > li > a span.active:after{transform:translate(0,-75%) rotate(45deg);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}
.accordionX .in-accordion{box-sizing:content-box;overflow:hidden;height:0px;transition:height .4s ease 0.1s}
.accordionX .in-accordion li {list-style: disc;list-style-position: inside;}
.accordionX .in-accordion p:last-child{padding-bottom:20px}
<ul class="accordionX">
    <li>
        <a id="tab1">
            <span>TAB 1</span>
        </a>
        <div class="in-accordion" style="height: 0px;">
            <p>
                Lorem ipsum dolor sit amet consectetur adipiscing elit placerat vestibulum at, leo torquent arcu tortor lectus gravida commodo neque elementum, semper posuere libero tincidunt velit vulputate morbi iaculis lacinia.
            </p>
        </div>
    </li>

    <li>
        <a id="tab2">
            <span>TAB 2</span>
        </a>
        <div class="in-accordion" style="height: 0px;">
            <p>
                Lorem ipsum dolor sit amet consectetur adipiscing elit placerat vestibulum at, leo torquent arcu tortor lectus gravida commodo neque elementum, semper posuere libero tincidunt velit vulputate morbi iaculis lacinia. Lorem ipsum dolor sit
                amet consectetur adipiscing elit placerat vestibulum at, leo torquent arcu tortor lectus gravida commodo neque elementum, semper posuere libero tincidunt velit vulputate morbi iaculis lacinia. Lorem ipsum dolor sit amet
                consectetur adipiscing elit placerat vestibulum at, leo torquent arcu tortor lectus gravida commodo neque elementum, semper posuere libero tincidunt velit vulputate morbi iaculis lacinia.
            </p>
        </div>
    </li>
</ul>

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

The beautiful synergy between Vuetify's v-input component and overflow animation

I am having trouble implementing an overflow animation on vuetify's v-text-field component. Despite my efforts, I can't seem to make it work as intended: <script setup> const text = 'very long long long long long text' </scri ...

How to insert a JSON object into a nested array using JavaScript

I am currently facing an issue with adding a JSON object based on specific conditions to an array, which is then used to create a WINJSList. The problem arises when I try to access the elements of the list or array after using the array.push method. My goa ...

Testing an ExpressJS route and their corresponding controller individually: a step-by-step guide

I have set up an Express route in my application using the following code snippet (where app represents my Express app): module.exports = function(app) { var controller = require('../../app/controllers/experiment-schema'); app.route('/a ...

Ways to obtain jquery object for replaced DOM element

Is there a way to select the new content after using the replaceWith function in my plugin? I want to chain my plugin for the new content. $.fn.customPlugin = function() { this.replaceWith('<div>New Content</div>'); }; So, ideal ...

Creating smooth transitions with CSS in React by fading text in when a user clicks a button

Within this presentational component: const HowToControls = props => { return ( <div className="col-md-6 how-to"> {props.isOpen ? <p className={`text ${props.isOpen ? 'visible' : ''}`}> lorem ...

Having issues sending multiple variables to PHP through Ajax

Trying to pass three variables through the URL using Ajax - one constant and two from a date picker. The constant passes fine, but the date variables are only passing as their names. Here's the code for the date pickers: <tr> ...

An error occurred in Angular2 when attempting to resolve a Promise: The type 'Promise<Hero[]>' is not compatible with the type 'Hero[]'

Recently updated. Currently, I am working through an Angular2 tutorial which can be found at this link Highlighted below is the code snippet for calling the HeroService from heroes.component.ts, Heroes.component.ts import { Component , OnInit } from ...

Annoying Gap Found Between <header> and <nav>

I am encountering an issue with the spacing between the <header> and <nav> in my HTML5 code. Despite trying to adjust the padding, there remains approximately 5 pixels of empty space that I cannot seem to remove. If anyone could provide insigh ...

Issue with Wicked_pdf stylesheet rendering on Heroku

I am currently working on a Rails application that utilizes wicked_pdf for generating PDF files. Everything works perfectly fine when testing locally, but once the app is deployed to Heroku, the generated PDF does not apply the stylesheet. Specifically fo ...

"Utilize Ajax to dynamically generate options in a dropdown menu with multiple

I am having trouble populating my multiple dropdown list using AJAX. The dropdown list is dependent on another single selection dropdown list. Here is the HTML code: <div class="form-group"> <label for="InputGender">Select Course</ ...

What is the best way to display flash messages within a Bootstrap modal dialog box?

I am facing an issue with my bootstrap modal window and form. I use flask.flash() to display error messages, but when I click upload for the first time, the modal window closes. The error message only shows up when I reopen the modal window. I want the err ...

The set operator in Firestore does not append any new documents to the collection

I recently implemented a promise chain to store user data in Firestore and handle authentication, but I encountered an issue. Initially, I used the add operator to save the data, but later decided to assign users based on their unique UID. After making thi ...

What is the process for activating the appropriate image when clicking on the accordion?

I currently have three accordions on the left side and three images on the right side, but this may grow in the future. My goal is to have the first accordion open and display the first image when the page loads. When the user clicks on the second accordio ...

Determining the precise coordinates of each sphere to construct a larger sphere comprised entirely of interconnected spheres

I am currently working on recreating an atom using THREE.js and I have encountered my first hurdle. Each type of atom contains varying numbers of Protons and Neutrons, so I am trying to figure out a way to automatically position them without colliding with ...

Is it possible to emphasize a single character within the alternative text of an image element by underlining it

I have a client who requires a specific character in their name to be underlined. How can this be achieved using the alt attribute of an img element? <img alt="ab<u>c</u>def" /> <img alt="ab&lt;u&gt;c&lt;/u&gt;def" /&g ...

How come the checkboxes for trees are not being checked in the child component while using Ant Tree Design?

I'm currently troubleshooting an issue with the Ant Tree component. I have a setup where the PageAdmin component fetches data for selected nodes in the tree, stores it in the checkedKeys array, and passes it as props to the CustomTree component. While ...

The method of applying conditional formatting to an HTML table is dependent on the specific

I've come across some code that I want to tweak: conditional formatting of html table cells In my project, there are two different sets of formatting rules for a final table with 37 columns. Most of the columns will follow rule 1, while about 10 of ...

What causes a dot to display when hovering over a link in a list?

Good day. [Click here to access the test page](http://89.111.180.28/CatalogOfProductsAndServices.php) Code: <ul> <li> <a href="#">Бытовая техника</a> <ul> <li><a href="CatalogOfProductsAndServices.php ...

VueJS added a new object to the array, but the data did not update reactively

Here is my current data layout days: [ { id: 0 name: 'Monday', times: [] }, { id: 1 name: 'Tuesday', times: [] } } I have implemented the following function to append an object to the times array. onT ...

jQuery click event handlers may become unresponsive following the loading of an HTML page using the load() method

I am facing an issue where the click event handlers associated with links in HTML pages loaded dynamically using jQuery are not working. When a link is clicked, it loads another HTML file but the event handlers seem to be lost in the process. Below is an e ...