Alan Vinícius
Alan Vinícius

Reputation: 166

Why body doesn't hide overflow?

What I want: Set the body width smaller than viewport and then hide everything outside the body.
(I know I can use a div container and get what I want)

Here is a very simple example (Codepen) :

body {
  overflow-x: hidden;
  margin: 0 auto;
}

.hidden {
  position: relative;
  left: -50px;
}


/*----- Decoration -----*/
body {
  border: 5px solid red;
  height: 2000px;
  width: 1000px;
}

.hidden {
  display: flex;
  align-items: center;
  text-align: center;
  height: 100px;
  width: 100px;
  background-color: green;
}

body::after {
  content: "Container";
  position: absolute;
  left: 50%;
  top: 50%;
}
/*-----------------------*/
<div class="hidden" >Should be hidden</div>

Upvotes: 1

Views: 713

Answers (3)

likle
likle

Reputation: 1797

That's because we need a way to control the overflow of the viewport. CSS will treat the overflow of the body element as the overflow of the viewport, unless you specify it already on the html element (e.g. html { overflow: auto; } probably resolves your issue).

Here is the relevant text from the CSS 2.2 specification:

UAs must apply the 'overflow' property set on the root element to the viewport. When the root element is an HTML "HTML" element or an XHTML "html" element, and that element has an HTML "BODY" element or an XHTML "body" element as a child, user agents must instead apply the 'overflow' property from the first such child element to the viewport, if the value on the root element is 'visible'. The 'visible' value when used for the viewport must be interpreted as 'auto'. The element from which the value is propagated must have a used value for 'overflow' of 'visible'.

Upvotes: 5

Riley
Riley

Reputation: 471

Set overflow:hidden on the <html>/root element in addition to what you have on the body. I can't seem to find any documentation about this issue, but it's perhaps related to the part of the spec discussing "special backgrounds." Fascinating problem!

More discussion: https://css-tricks.com/just-one-of-those-weird-things-about-css-background-on-body/

Upvotes: 1

clod9353
clod9353

Reputation: 2002

You can use clip-path to do that. You can just add

clip-path: inset(0 0 0 0);

to your body. You can see a working snippet below:

body {
  margin: 0 auto;
  clip-path: inset(0 0 0 0);
}

.hidden {
  position: relative;
  left: -50px;
}


/*----- Decoration -----*/
body {
  border: 5px solid red;
  height: 2000px;
  width: 80%;
}

.hidden {
  display: flex;
  align-items: center;
  text-align: center;
  height: 100px;
  width: 100px;
  background-color: green;
}

body::after {
  content: "Container";
  position: absolute;
  left: 50%;
  top: 50%;
}
/*-----------------------*/
<div class="hidden" >Should be hidden</div>

Note: I added a width of 80% to the body just to show the result in the snippet.

Upvotes: 2

Related Questions