skip to Main Content

I have a parent element and a child element. On window resize event, the child element has its width and height set to the parents’ offsetWidth and offsetHeight, however on every other resize both the width and height are off by 12px on Firefox and 15px on Edge.

Here’s the code, when you resize the page, there’s a white gap on the right:

const parent = document.getElementById("parent");
const child = document.getElementById("child");

const matchDimensions = () => {
    child.style.width = parent.offsetWidth + "px";
    child.style.height = parent.offsetHeight + "px";
};

matchDimensions();
window.addEventListener("resize", matchDimensions);
html, body, #parent {
    width: 100%;
    height: 100%;
    margin: 0;
}

#child {
    background: red;
}
<div id="parent">
    <div id="child"></div>
</div>

Weirdly, it only happens if I scale the page down but not if I scale it up. Also, removing margin: 0 stops this from happening but I need it in order to have the parent fill the entire page.

The reason I’m using JS to match the child to the parent is because in reality the child is a canvas which doesn’t automatically resize with the parent with just CSS.

3

Answers


  1. Possible the browser has some default styling getting in the way since it changes behavior with the size of the viewport.

    You could try a css reset (one example) or normalize to see if that solves the issue.

    Login or Signup to reply.
  2. Referring to my comment, i updated your Javascript code to calculate the srollbar width, add the result to child.style.width and so get rid of the gap.

    const parent = document.getElementById( "parent" );
    const child = document.getElementById( "child" );
    
    /* Create a temporary element to calculate
       the scrollbar width; then delete it.
    */
    const scrollBarWidth = () => {
      let el, width;
      el = document.createElement( "div" );
      el.style.cssText = "position:absolute; visibility:hidden; overflow:scroll;";
      document.body.appendChild( el );
      width = el.offsetWidth - el.clientWidth;
      el.remove();
      return width;
    }
    
    const matchDimensions = () => {
      child.style.width = parent.offsetWidth + scrollBarWidth + "px";
      child.style.height = parent.offsetHeight + "px";
    };
    
    matchDimensions();
    window.addEventListener( "resize", matchDimensions );
    html, body, #parent {
        width: 100%;
        height: 100%;
        margin: 0;
    }
    
    #child {
        background: red;
    }
    <div id="parent">
        <div id="child"></div>
    </div>
    Login or Signup to reply.
  3. The issue here is most likely caused by how browsers handle subpixel rendering, which can result in minor fluctuations in element size. To solve this problem, use the Math.round() function to round the width and height values to the nearest whole number. Here’s how to change the matchDimensions() function to accomplish this:

    JavaScript:

    const matchDimensions = () => {
      child.style.width = Math.round(parent.offsetWidth) + "px";
      child.style.height = Math.round(parent.offsetHeight) + "px";
    };

    This should help to eliminate the white gap on the right that appears in Firefox and Edge. Additionally, if you need to maintain the margin on the parent element, you can add a box-sizing rule to include the margin in the calculation of the element’s total width and height:

    CSS:

    html, body {
      margin: 0;
      height: 100%;
    }
    
    #parent {
      width: 100%;
      height: 100%;
      margin: 0;
      box-sizing: border-box;
    }
    
    #child {
      background: red;
      width: 100%;
      height: 100%;
    }

    With these modifications, the child element should resize dynamically to match the parent element’s dimensions without any gaps or off-by-pixel issues.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search