Search code examples
htmlcssscrollbaroverflowcentering

Center element in parent until it reaches top-left bounds, then stop centering and show scrollbars?


I want to center an element within a parent. That's easy enough with transform, flexbox, grid and so on... The problem is the overflow-behavior. When the parent shrinks below the dimensions of the child, scrollbars appear. But they do not allow me to scroll to the top-left of the child. Here's what I mean: gif animation showing window-resizing and the css behavior

This example uses flexbox for it's centering, html below:

b {
  color: white;
}

html {
  position: absolute;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

body {
  margin: 0;
}

header {
  position: absolute;
  top: 0;
  height: 84px;
  width: 100%;
  background-color: darkolivegreen;
}

footer {
  position: absolute;
  bottom: 0;
  height: 56px;
  width: 100%;
  background-color: darkslateblue;
}

main {
  position: absolute;
  top: 84px;
  bottom: 56px;
  width: 100%;
  background-color: #222222;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: auto;
}

div.content {
  flex-shrink: 0;
  width: 600px;
  height: 600px;
  background-color: darkred;
}
<!DOCTYPE html>
<html lang="en">
<!-- omitted head -->

<body>

  <header>
  </header>

  <main>
    <div class="content">
      <b>Lorem</b> Lots of Lorem ipsum... <b>quod</b>
    </div>
  </main>

  <footer>
  </footer>

</body>

</html>

What I want to achieve looks more like this: gif animation showing window-resizing and the css behavior

In this example I didn't use flexbox-centering. I wrapped the content within a container that has it's margin set to: 0 auto. This will achieve the wanted behavior on the x-axis, but not the y-axis. How can I achieve this on both axes?

Below the html and css of the second example using a container and auto-margin for centering:

b {
  color: white;
}

html {
  position: absolute;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

body {
  margin: 0;
}

header {
  position: absolute;
  top: 0;
  height: 84px;
  width: 100%;
  background-color: darkolivegreen;
}

footer {
  position: absolute;
  bottom: 0;
  height: 56px;
  width: 100%;
  background-color: darkslateblue;
}

main {
  position: absolute;
  top: 84px;
  bottom: 56px;
  width: 100%;
  background-color: #222222;
  /* display: flex;
      justify-content: center;
      align-items: center; */
  overflow: auto;
}

div.container {
  margin: 0 auto;
  width: 600px;
  height: 100%;
  background-color: #333333;
}

div.content {
  /* flex-shrink: 0; */
  width: 600px;
  height: 600px;
  background-color: darkred;
}
<!DOCTYPE html>
<html lang="en">
<!-- omitted head -->

<body>

  <header>
  </header>

  <main>
    <div class="container">
      <div class="content">
        <b>Lorem</b> Lots of Lorem ipsum... <b>quod</b>
      </div>
    </div>
  </main>

  <footer>
  </footer>

</body>

</html>

Ah... I hope to find a solution that doesn't use javascript for this behavior. In case I find the solution, I'll post it with a corresponding gif.


Solution

  • Use display: flex on the .container and margin: auto on the .content .

    This is a method to solve the centering problems of flex and by this way it will center .content

    b {
      color: white;
    }
    
    html {
      position: absolute;
      width: 100%;
      height: 100%;
      overflow: hidden;
    }
    
    body {
      margin: 0;
    }
    
    header {
      position: absolute;
      top: 0;
      height: 84px;
      width: 100%;
      background-color: darkolivegreen;
    }
    
    footer {
      position: absolute;
      bottom: 0;
      height: 56px;
      width: 100%;
      background-color: darkslateblue;
    }
    
    main {
      position: absolute;
      top: 84px;
      bottom: 56px;
      width: 100%;
      background-color: #222222;
      /*display: flex;
      justify-content: center;
          align-items: center; */
      overflow: auto;
    }
    
    div.container {
      display: flex;
      margin: 0 auto;
      width: 600px;
      height: 100%;
      background-color: #333333;
    }
    
    div.content {
      /* flex-shrink: 0; */
      margin: auto;
      width: 600px;
      height: 600px;
      background-color: darkred;
    }
    <!DOCTYPE html>
    <html lang="en">
    <!-- omitted head -->
    
    <body>
    
      <header>
      </header>
    
      <main>
        <div class="container">
          <div class="content">
            <b>Lorem</b> Lots of Lorem ipsum... <b>quod</b>
          </div>
        </div>
      </main>
    
      <footer>
      </footer>
    
    </body>
    
    </html>

    enter image description here