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:

Note:
::after for filling the right side,
because the container is a grid, thus causing the ugly column gap.Here the mockup of my Navbar.
Please focus on the .js file:
See & edit my sandbox
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
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.
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;
}