So, I have a DIV #Wrapper
which has a fixed width. Inside that DIV, I have another DIV #Panel
which also has a fixed width:
<div id="Wrapper">
<p>...</p>
<div id="Panel">Panel</div>
<p>...</p>
</div>
Sometimes, the width of the Panel is larger than the with of the Wrapper, and in those cases I would like to widen the Wrapper via JavaScript, so that it wraps the Panel perfectly.
Live demo: http://jsfiddle.net/H6rML/
I intended to use .scrollWidth
on the Wrapper to determine the width of the Panel. However, the problem is that the Wrapper has horizontal padding, and the .scrollWidth
for some reason only includes the left-padding of the wrapper. So:
Wrapper.scrollWidth === Wrapper.LeftPadding + Panel.Width
So, given:
#Wrapper {
width: 200px;
padding: 10px;
}
#Panel {
width: 300px;
}
Wrapper.scrollWidth
returns 310px
, which is not very useful. If .scrollWidth
didn't include any padding and only returned the width of the Panel, I could work with that (I would add the padding manually to that value). If both paddings were included, I could work with that too. But why is only the left padding included? (Btw this behavior appears to be cross-browser.)
A few additional notes:
I cannot set the width on the Wrapper directly. In my actual code, I set the width on an ancestor element that is several levels above the Wrapper, and I use a custom API to set the width. This is why I need to retrieve the full 320px
value.
I would like a solution that does not depend on the content of the Wrapper. In my demo it's a Panel, but in other scenarios there could be a different element that overflows, or even multiple elements. That is why I went with .scrollWidth
on the Wrapper.
Is there a way to get the value 320px
without having to manually add the right padding to the .scrollWidth
value?
Btw, according to the standard, the right padding should be included:
The scrollWidth attribute must return the result of running these steps:
If the element does not have any associated CSS layout box return zero and terminate these steps.
If the element is the root element and the Document is not in quirks mode return max(document content width, value of innerWidth).
If the element is the HTML body element and the Document is in quirks mode return max(document content width, value of innerWidth).
Return the computed value of the 'padding-left' property, plus the computed value of the 'padding-right', plus the content width of the element.
Source: http://www.w3.org/TR/cssom-view/
Why don't the browsers behave accordingly?
To further improve the clarity of my post, let me sum up the two main questions:
(1) If the standard states that the right padding should be included in the .scrollWidth
value, then why don't the browsers behave accordingly?
(2) Is it possible to retrieve the correct value (320px
in my case), without having to manually add the right padding?
The answer to this question is located here: When a child element overflows horizontally, why is the right padding of the parent ignored?
The scroll width refers to the entire width of that element in the HTML page, even if it is not viewable due to the overflow property. The element's scroll width includes the width assigned in CSS property plus the padding, but it does not include the margin, border, or scrollbar.
The Element. clientWidth property is zero for inline elements and elements with no CSS; otherwise, it's the inner width of an element in pixels. It includes padding but excludes borders, margins, and vertical scrollbars (if present).
The scrollWidth value is equal to the minimum width the element would require in order to fit all the content in the viewport without using a horizontal scrollbar. The width is measured in the same way as clientWidth : it includes the element's padding, but not its border, margin or vertical scrollbar (if present).
clientWidth is the inner width (ie. the space inside an element including padding but excluding borders and scrollbars) offsetWidth is the outer width (ie. the space occupied by the element, including padding and borders)
I'm not sure if I understand correctly, but from what I read, I assume you want to change width of #Wrapper based on #Panel. In that case, maybe you could try the following:
#Wrapper {
display: inline-block;
make sure to remove width from #Wrapper
}
I have no idea why leading browsers share this bug up until today, but here is a demo of the problem and inline-block
workaround.
document.body.innerHTML += 'one.scrollWidth = '+ document.querySelector('.one').scrollWidth
+'<br>two.scrollWidth = '+ document.querySelector('.two').scrollWidth
+'<br>three.scrollWidth = '+ document.querySelector('.three').scrollWidth
+' (fix applied to grand children)<br>four.scrollWidth = '+ document.querySelector('.four').scrollWidth +' (fix applied to direct child)';
.parent{
border:1px solid rgba(50,150,220,1);
}
.child{
background:rgba(100,200,255,0.3);
padding:10px 20px;
white-space:nowrap;
}
.scroll-container{
border:1px solid red;
display:inline-block;
overflow:hidden;
}
.two, .three, .four{
width:60px;
}
.three .child{
display:inline-block;
}
.four .parent{
display:inline-block;
}
<div class="scroll-container one">
<div class="parent">
<div class="child">Lorem ipsum dolor</div>
<div class="child">Lorem ipsum dolor sit amet</div>
</div>
</div>
<br>
<div class="scroll-container two">
<div class="parent">
<div class="child">Lorem ipsum dolor</div>
<div class="child">Lorem ipsum dolor sit amet</div>
</div>
</div>
<br>
<div class="scroll-container three">
<div class="parent">
<div class="child">Lorem ipsum dolor</div>
<div class="child">Lorem ipsum dolor sit amet</div>
</div>
</div>
<br>
<div class="scroll-container four">
<div class="parent">
<div class="child">Lorem ipsum dolor</div>
<div class="child">Lorem ipsum dolor sit amet</div>
</div>
</div>
<br>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With