Overflow Fixes and Horizontal Scrollbars

September 18, 2025

Overflow Fixes and Horizontal Scrollbars

Mist rises over a lake against an autumn forest at sunrise. © Michal / Adobe Stock


The fun thing about putting up a new website is hyper-focusing on all the tiny little details that aren't quite right. There were two small issues causing unwanted horizontal scroll bars to appear that needed addressing. Now, web development is not a strong area of mine, so this may be really basic. But that's what this blog is for; documenting my struggles and successes in areas I'm currently dabbling in, and being open about my current skill level. With that said, onward to the things I learned!

Code block overflow

The first, and easier to diagnose were my code blocks. When eleventy processes markdown code syntax, typed with three backticks, it outputs <pre> <code> tags. I needed to apply overflow: auto to the <pre> tag using the :has() relational pseudo-class. This allows you to target the parent element when it contains a specific child element.

The second set of code blocks are the more complex style with line numbers and copy buttons. These are created with the syntax highlight plugin, and a custom eleventy shortcode:

eleventyConfig.addPairedShortcode("codeblock", function(content, id, lang = "bash") {
  const trimmed = content.trim();
  return `<div id="${id}" class="codeblock wa-flank:end wa-gap-xs wa-align-items-start language-${lang}">${trimmed}<wa-copy-button from="${id}"></wa-copy-button></div>`;
});

Adding overflow: auto; to the .codeblock pre selector did the trick for these. Here's the final CSS for my code blocks with the fixes, along with the code that generates the line numbers.

/* styling for code blocks */
pre:has(code) {
  overflow: auto;
}

.codeblock pre {
  margin-bottom: 1rem;
  counter-reset: line;
  overflow: auto;
}

.codeblock .highlight-line::before {
  counter-increment: line;
  content: counter(line);
  /* content: " " counter(line, decimal-leading-zero); */
  display: inline-block;
  min-width: 5ch;
  text-align: right;
  padding: 0 0.5rem;
  margin-left: -1rem;
  margin-right: 1rem;
  color: var(--code-linenumber-color-light);
  border-right: 1px solid var(--code-linenumber-color-light);
}

.wa-dark .codeblock .highlight-line::before {
  color: var(--code-linenumber-color-dark);
  border-right-color: var(--code-linenumber-color-dark);
}

Now that I see that though, I'm bothered by the step in the line numbers from 9 to 10. I'll need to figure out a fix for that to pad 1–9 with a leading space to even that all out. A problem for another day.

Edit, a few hours later: Fixing the line number alignment was easy. Setting right text alignment and the min-width to 5 characters – to account for the space and right border I think – then backing it up with a negative margin-left. Seems to do the trick up to line 999 where it steps out again. But I'll likely never need a code block that long. These small changes are reflected in the code above.

Fixing the full-bleed images

alt text

South Sister and Broken Top mountains reflect over the calm waters of Sparks Lake at sunrise in the Cascades Range in Central Oregon, USA.
© Michal / Adobe Stock
With the code blocks fixed up, I still had a smidge of horizontal scrolling that was caused by my love of large, full-bleed images. Here's my original, non-working CSS for that:
.full-bleed {                                   
width: 100vw;
max-width: none;
margin-left: calc(50% - 50vw);
margin-right: calc(50% - 50vw);
display: block;

This issue is that width: 100vw returns the full width of the browser window, regardless of whether there is a vertical scroll bar or not. When there is a vertical scroll bar, it covers a bit of content and 100vw becomes wider than the visible content area. A horizontal scroll bar appears as a result. There's a bunch of different attempts to fix this that I read through. This one from Ana Rodrigues was a good start, as was this CodePen example. In the end, the fix can be done entirely with CSS, no need to get JavaScript involved to read the viewport, and then subtract the width of the scroll bar, etc.

The explanation as I understand it goes like this: Instead of setting the max-width of the page-container div to 960px, you compute the margins needed for the current cqw — container query width — to leave a 960px area for the content. Save this as a CSS variable (--page-margin) Then apply those margins to the container.

Next, for the .full-bleed selector, multiply the same margin variable by -1 to get the amount to expand the image's container, outside the parent. I needed the additional margin-left and margin-right values calc(50% - 50cqw); otherwise I was getting weird shifts. I think this is recentering the image in the full window, but I'll admit I don't exactly know why that part was required. This combo seemes to do the trick. Here's the completed CSS:

.page-container {
  /* max-width: 960px; */
  /* margin: 0 auto; */
  --page-margin: max(1rem, 50cqw - 960px/2);
  margin-inline: var(--page-margin);
  padding: 1rem;
}

html {                                           /* full page bleed image */
  container-type: inline-size;
}

.full-bleed {
  margin-inline: calc(-1 * var(--page-margin));
  max-width: 100cqw;
  margin-left: calc(50% - 50cqw);
  margin-right: calc(50% - 50cqw);
  border-radius: 0px;
}

With all that in place, we should no longer get any stray horizontal scrolling!


Headshot of Adam Wilbert, a dapper man with a graying beard Headshot of Adam Wilbert, a dapper man with a graying beard

Adam Wilbert is a LinkedIn Learning / Lynda.com author of over 80 courses on SQL Server, Microsoft Access, database design and development, and mapping with ArcGIS. Come say "hi" on Mastodon: @awilbert@mastodon.social.