Reputation: 1312
EDIT 3/Final: Th Computed Style problem/question is explained below but, for the benefit of others coming later, my real problem is solved with Flex Boxes and Vx measurements in conjunction with border-box. IMHO "display: flex;" is the answer to many questions and, although I'm struggling to get it to do what I want, stops you having to work against CSS!
EDIT 2: The following undoubtedly needs refactoring but if you can tell me that it does what I was asking for that'd be great. The change I had to make was to add clientTop in with offsetTop in the equation: -
function resizeContent()
{
var browserHeight = window.outerHeight;
var offesetHeight, offsetWidth;
var viewHeight = window.innerHeight;
var viewWidth = window.innerWidth;
var chromeFootPrint = browserHeight - viewHeight;
var tmpHeight = viewHeight;
if (window.matchMedia("(orientation: portrait)").matches) {
if (viewWidth > viewHeight) {
viewHeight = viewWidth - chromeFootPrint;
viewWidth = tmpHeight + chromeFootPrint;
}
} else {
if (viewWidth < viewHeight) {
viewHeight = viewWidth - chromeFootPrint;
viewWidth = tmpHeight + chromeFootPrint;
}
}
var dimTarget = logScroll;
var offsetTop = dimTarget.offsetTop + dimTarget.clientTop;
var offsetLeft = dimTarget.offsetLeft + dimTarget.clientLeft;
while (dimTarget = dimTarget.offsetParent) {
offsetTop += dimTarget.offsetTop + dimTarget.clientTop;
offsetLeft += dimTarget.offsetLeft + dimTarget.clientLeft;
}
logScrollHeight = viewHeight - (offsetTop + fireBreak);
logScroll.style.height = logScrollHeight + "px";
logScroll.style.width = getStyle(contentDiv).width;
logWindow.style.height = logScroll.style.height;
logWindow.style.width = logScroll.style.width;
logWindow.scrollTop = logWindow.scrollHeight - logScrollHeight;
contentDiv.style.visibility = "visible"; // Now we're presentable
}
and this is the fire-break calculation: -
var outerStyle = getStyle(wholeScreen);
fireBreak = Number(outerStyle.paddingBottom.match("[0-9.]*"))
+ Number(outerStyle.borderBottomWidth.match("[0-9.]*"))
;
resizeContent();
EDIT 1: Ok, let me re-phrase the question: - How to I find out the height of my DIVs content with: -
width: 250px;
border: 3px solid green;
padding: 0.5em;
box-sizing: border-box;
I am currently having to do this: -
logScrollHeight = viewHeight -
(offsetTop + Number(getStyle(headerDiv).paddingBottom.match("[0-9.]*")));
Original question: -
This is bound to be a duplicate but after nearly an hour of looking I have found many similar/identical questions but no real answer :-(
Why aren't the boundryWith and padding deducted from height?
Thankfully the boundryBottomWidth and PaddingBottom return have been converted to pixels (including the "px" string sadly) but doesn't the standard say that the usable height should be returned?
Upvotes: 0
Views: 1903
Reputation: 136707
To get the height of an element, you don't use getComputedStyle
.
getComputedStyle
should only be used to get the parsed values that are currently applied from different style-sheets. In other words, you can see it as a live style-sheet, only targeted to a single element, with standardized units.
But in no way it should be used to get the current height or width of an element. Too many factors may interfere with the set value, and an element can even have an height without having any CSS height
rule set.
So yes... when the height
CSS rule is set to auto
, you will get the computed value, which may coincide with the real height of the element, but it also may not be so.
So in order to get the displayed height of an element, without the border and padding, we will need to do some calculations ourself.
Element#getBoundingClientRect()
will give us the real displayed dimensions of our element, transformations included. .offsetHeight
will give us the untransformed height including the border-box, and .clientHeight
will give us the untransformed height with the padding-box.
This means that we will first have to get all the border and padding computed values, then get the current scale of our element, and finally remove the scaled padding + border boxes from the values we get with getBoundingClientRect
.
Here is an example, which will draw a new rectangle div atop the element's bounding-box without padding and border boxes.
let marker;
scale.onclick = e => {
element.classList.toggle('scaled');
drawRect();
}
boxSizing.onclick = e => {
element.classList.toggle('boxSized');
drawRect();
}
function drawRect() {
// remove previous marker if any
if (marker && marker.parentNode) {
marker.remove();
marker = null;
}
// first get the border and padding values
let computed = getComputedStyle(element);
let borderLeft = parseFloat(computed.borderLeftWidth);
let borderWidth = borderLeft + parseFloat(computed.borderRightWidth);
let borderTop = parseFloat(computed.borderTopWidth);
let borderHeight = borderTop + parseFloat(computed.borderBottomWidth);
let paddingLeft = parseFloat(computed.paddingLeft);
let paddingWidth = paddingLeft + parseFloat(computed.paddingRight)
let paddingTop = parseFloat(computed.paddingTop);
let paddingHeight = paddingTop + parseFloat(computed.paddingBottom);
// get the current bounding rect, including the border-box
let rect = element.getBoundingClientRect();
// we need to get the current scale since the computed values don't know about it...
let scale = 1 / (element.offsetHeight / rect.height);
// the real displayed height and width without border nor padding
let height = rect.height - ((borderHeight + paddingHeight) * scale);
let width = rect.width - ((borderWidth + paddingWidth) * scale);
// create our rectangle
marker = document.createElement('div');
marker.classList.add('marker');
marker.style.height = height + 'px';
marker.style.width = width + 'px';
// we need to scale border + padding again
marker.style.top = (rect.top + (borderTop + paddingTop) * scale) + 'px';
marker.style.left = (rect.left + (borderLeft + paddingLeft) * scale) + 'px';
document.body.append(marker);
}
#element {
width: 250px;
border: 0.5em solid green;
padding: 0.5em;
margin-top: 12px;
}
#element.scaled {
transform: scale(2);
transform-origin: top left;
}
#element.boxSized {
box-sizing: border-box;
}
.marker {
position: fixed;
width: 3px;
background: rgba(0, 0, 0, .3)
}
<label>scale
<input id="scale" type="checkbox">
</label>
<label>box-sizing
<input id="boxSizing" type="checkbox">
</label>
<div id="element">
Hello
<br> world
</div>
Upvotes: 1
Reputation: 1238
when you set box-sizing as border-box:
The width and height properties include the content, the padding and border, but not the margin
So when you use getComputedStyle to get a element's height, of course it includes the height of padding and border.
you can have a look at box-sizing property and css box model
Upvotes: -1