Home > Blockchain >  Javascript Detect Overflow with Padding Aware
Javascript Detect Overflow with Padding Aware

Time:10-27

I'm making a Navbar that can transform between desktop & mobile version based on the screen width.

Unlike as Bootstrap's Navbar that utilizes @media (min-width: ${minWidth}px) for switching,
I am using a JavaScript for overflowing detection, by comparing $0.clientWidth & $0.scrollWidth.

The problem is, the paddingRight doesn't substract the $0.clientWidth, so the detection is inaccurate.

I want to get the actual client width without padding as shown by Chrome's page inspector.
As marked by the green rectangle on this illustration: enter image description here

Note:

  • I cannot apply a hack by adding ::after for filling the right side, because the container is a grid, thus causing the ugly column gap.
  • I cannot apply marginRight to the menu because the margin will fill the gridArea.

Here the mockup of my Navbar.
Please focus on the .js file: enter image description here

CodePudding user response:

If you are using list, i mean if your structure is like as

<ul>
   <li>
       <a href="#">
       </a>
   </li>
</ul>

Then give the padding to the anchor tag, and then get the width of the li tag, your problem will be resolve

CodePudding user response:

basically you want the actual width of the element without padding, you can achieve this by using javascript

 <script>
    function getWidth() {

        var elemWidth = 
            document.getElementById("navbar").offsetWidth;
        alert(elemWidth);
    }
</script>

inshort the trick is offsetWidth to get the elements inner-width.

CodePudding user response:

I updated your code please check

javascript

console.log('loaded')
const navbar = document.querySelector("#navbar");
const indicator = document.querySelector("#indicator");
const menu = document.querySelector('.menu');


new ResizeObserver(() => {
  const overflowed = navbar.scrollWidth > navbar.clientWidth;

  if (overflowed) {
    indicator.classList.add('mobile');
    indicator.classList.remove('desktop');
    indicator.value = "overflowed => switch to mobile version";
    menu.classList.add('mobile');
  }
  else {
    indicator.classList.add('desktop');
    indicator.classList.remove('mobile');
    indicator.value = "not overflowed => desktop version";
    menu.classList.remove('mobile');
  }
})
.observe(navbar, { box: 'border-box' });

Css

 body {
  margin: 20px;
}

.navbar {
  padding-inline: 80px;
  padding-block: 10px;
  background: #186EFB;
  border: solid 3px darkblue;
  min-height: 50px;
  display: grid;
  grid-template-columns: min-content 1fr;
  grid-template-rows: 1fr;
  grid-template-areas: "logo   menu";
  column-gap: 10px;

  justify-items: center;
  align-items: center;
}

.logo {
  grid-area: logo;
  display: inline-block;
  background: red;
  border: solid 3px darkred;
  width: 30px;
  height: 30px;
}

.menu {
  grid-area: menu;
  align-self: stretch;
  justify-self: stretch;
  display: block;
  background: #14924C;
  border: solid 3px darkgreen;
  min-width: 300px;
  height: 50px;
}

#indicator.desktop {
  background: lightgreen;
}
#indicator.mobile {
  background: pink;
}

.menu.mobile{
  max-width: 300px;
  min-width: auto;
}
  • Related