When a block element is absolutely positioned, its offsetWidth should be based on the widths of its child elements, not the entire document.
offset-width.html:
<html>
<body>
<div id="elt" style="position:absolute;top: 100px; left: 100px">
<div style="width:300px;height:300px">
</div>
</div>
</body>
<script>
const elt = document.getElementById('elt');
console.log('elt.offsetWidth', elt.offsetWidth);
console.log('elt.getBoundingClientRect().width', elt.getBoundingClientRect().width);
</script>
</html>
Sample Java main using HtmlUnit 2.53.0:
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import java.io.IOException;
import java.net.MalformedURLException;
public class HtmlUnitMain {
public static void main(String[] args) {
try (WebClient webClient = new WebClient()) {
HtmlPage page = webClient.getPage("http://localhost:8000/offset-width.html");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
Exported (from firefox) console output:
elt.offsetWidth 300
elt.getBoundingClientRect().width 300
Actual console output:
INFO: elt.offsetWidth 110
INFO: elt.getBoundingClientRect().width 110
Similarly, when a statically (or relatively) positioned block element is placed inside an absolutely positioned element, rather than getting its size from the window, it should get its size from its parent's size, and that parent might need to ask its parent and so on. Same java file, different html content to see this issue
offset-width.html:
<html>
<body>
<div style="width:500px;"><!-- grandparent element, with width set -->
<div><!-- parent element, no width or other style set -->
<div id="elt"><!-- target element, should get 500px from grandparent -->
<div style="width:300px;height:300px"><!-- meaningless child, just to make sure we ignore this -->
</div>
</div>
</div>
</div>
</body>
<script>
const elt = document.getElementById('elt');
console.log('elt.offsetWidth', elt.offsetWidth);
console.log('elt.getBoundingClientRect().width', elt.getBoundingClientRect().width);
</script>
</html>
Expected console output:
elt.offsetWidth 500
elt.getBoundingClientRect().width 500
Actual console output:
INFO: elt.offsetWidth 1256
INFO: elt.getBoundingClientRect().width 1256
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too