jsmars
jsmars

Reputation: 1928

Making elements not affect page height (thus scrolling)

I'm making a website with a number of "floating" images one each side of the screen. Pages range in height between about 900-3000 pixels, so I've created floating images to cover this area.

The problem is, that even if a page is only 900 pixels high, the page will see the floating images as objects on the page and make scrolling to them possible.. making the page much longer than needed.

From what I could gather on StackOverflow. Absolute elements shouldn't count into the flow of the document, but clearly these are. I've also seen answers involving usage of overflow:hidden, but this doesn't seem to have the desired effect at all.

Maybe the only way would be to create the images depending on the page height using javascript?

here is the WIP of the site in question: http://apa.smars.se

Upvotes: 4

Views: 6756

Answers (3)

Tigerrrrr
Tigerrrrr

Reputation: 1344

A relatively new CSS-only answer would be to use the contain property, this property can easily cause unwanted effects or lag, so don't overuse it. The property became supported on all major browsers in 2020.

To be more specific, you probably want contain: layout; in this case, here's an example:

document.getElementById('toggle-contain').addEventListener('click', () =>  {
    let contentWrapper = document.getElementById('content-wrapper');
    
    let checkLayout = contentWrapper.style.contain === 'layout';
    if (checkLayout) contentWrapper.style.contain = '';
    else contentWrapper.style.contain = 'layout';
    
    contentWrapper.getElementsByTagName('b')[0].textContent = !checkLayout;
});
* { margin: 0; box-sizing: border-box; }

body {
    min-height: 100dvh;
    align-content: center;
}

button {
  cursor: pointer;
  display: block;
  margin: 0 auto 1em;
}

hgroup {
    width: 5000px;
    height: 100px;
    background-color: lightgreen;
    align-content: center;
    padding: 0 2ch;
}

code {
  display: inline-block;
  margin: 0.5em 0;
  padding: 0.25em 1ch;
  background: rgb(0 0 0 / 0.1);
}
<button id="toggle-contain">Toggle <code>contain: layout;</code></button>

<div id="content-wrapper">
  <hgroup>
    <p>It is true that this green box is too wide for it's scroll container.</p>
    <p>And it is <b>false</b> that the container of the box has <code>contain: layout;</code>. </p>
  </hgroup>
</div>

What containment does is isolate a section of the DOM, so in this case by doing contain: layout we're simply saying "ignore this element and all its children when calculating whether or not the scroll container should show the scrollbar.

Upvotes: 0

HasanAboShally
HasanAboShally

Reputation: 18675

When you give an absolute position to an element it becomes absolute related to the first relative element that contains the absolute element.

And because the default position for elements is static, you may have to change it for the container element (maybe the body in your case).

Good luck!

Upvotes: 1

smnh
smnh

Reputation: 1745

If you want a CSS only solution here is what you should do:

  1. Add position:relative; and margin:0 to the <body> element.
  2. Add next element as a first element in your <body>:

    <div style="position:absolute; left:0; top:0; width:100%; height:100%; overflow:hidden;">
    
  3. Move the <div class="botleft ..."> and <div class="botright ..."> elements to that div.

By applying position:relative to the <body> element and adding to it another element with position:absolute; left:0; top:0; width:100%; height:100% you are telling that element to "track" the size of the <body> element. And by adding overflow:hidden; hides the bottom-overflowed images.

The downside in this solution is that you may see cut images at the bottom of the page. Well, nothing is perfect :)

Here is how your DOM tree should look like after this change

enter image description here

To see the results immediately you can run following code from browser's console:

d = document.createElement("div");
d.style.cssText = "position:absolute; left:0; top:0; width:100%; height:100%; overflow:hidden;";
document.body.insertBefore(d, document.body.firstChild);
d.appendChild(document.getElementsByClassName("botleft")[0]);
d.appendChild(document.getElementsByClassName("botright")[0]);
document.body.style.position = "relative";
document.body.style.margin = "0";

Upvotes: 3

Related Questions