Skip to content Skip to sidebar Skip to footer

Centering Items With Flexbox And Overflow

Problem Summary My desired layout is to be able to center (both vertically and horizontally) an image of unknown size on the page. If the image is too big to fit in either directio

Solution 1:

Just remove the justify-content from your .container and add a margin: auto to your image.

.body {
  height: 600px;
}

.container {
  margin: auto;
  display: flex;
  /* align-items: center; // no need for this anymore *//* justify-content: center; // remove this */border: 1px solid red;
  height: 100%;
  overflow: auto;
}

img {
  border: 5px solid black;
  margin: auto;  /* add this */
}
<divclass="body"><divclass="container"><imgsrc="http://placehold.it/700x700" /></div></div>

Solution 2:

You can achieve this by wrapping your image in a container within a flex container, as follows:

  • Flex container
    • display: flex
    • height: 100vh
  • Inner container
    • margin: auto

This will allow you to get an image of unknown size centered in the viewport both vertically and horizontally, without losing the ability to scroll to any part of the image in case it doesn't fit inside the viewport in either direction.

Example 1: (Image centered in viewport)

body {
  margin: 0;  /* Override user agent styles */
}

.flex {
  display: flex;
  height: 100vh;
}
.container {
  margin: auto;
}
<bodyclass="flex"><mainclass="container"><imgsrc="http://placehold.it/100x100"></main></body>

Example 2: (Image doesn't fit in viewport, yet can still be scrolled)

body {
  margin: 0;  /* Override user agent styles */
}

.flex {
  display: flex;
  height: 100vh;
}
.container {
  margin: auto;
}
img {
  border: 1px solid red;
}
<bodyclass="flex"><mainclass="container"><imgsrc="http://placehold.it/1000x1000"></main></body>

It works in the latest version of Chrome, Firefox, Opera, and Edge.

Solution 3:

So the criteria is that you always want a centered image vertically and horizontally, and have it scrollable no matter how small or large the viewport is? Take a look at this snippet and let me know if I'm close. If I'm totally wrong then I have plan B. If I have succeeded or almost there, I'll explain what I did.

SUMMARY

  1. Define <body> because if you don't then you can't dictate how far your scrollbars can go.

    position: relative, top, bottom, right, and left at 0 stretches the <body> to cover the viewport.

    width and height of body are 100vw and 100vhenforcing a limit on <body>

    ♦ Since <body> is a container all flexbox properties will influence .x for centering horizontally.

    Since you emphasized the use of scrollbars, overflow: scroll scroll bars will persist even if not needed. Which is good in circumstances involving dynamic content because there wouldn't be any jumping.

  2. The outer container .x has flexbox properties to center the inner container .y. In addition you'll notice a very little known property.

  3. .y has flex-flow: column nowrap to center the image.

  4. body has min-content applied to both height and width which will force it's content's borders into a tight package. This is how you're able to see the image's borders without the usual cutoff.

UPDATE

This demo has some simple JS to demonstrate that images of any size are:

  1. Centered horizontally
  2. Centered vertically
  3. All sides can be viewed at any size.

Note: Anything under DEMO is entirely safe to delete or comment out.

// DEMO var s = document.getElementById('s');
s.addEventListener('click', function(event) {
  event.preventDefault();
  var w = document.getElementById('w'),
    h = document.getElementById('h'),
    pic = document.getElementById('pic'),
    wv = w.value,
    hv = h.value;
  pic.src = "http://placehold.it/" + wv + "x" + hv + "/";
}, false);
/* RESET */html {
  box-sizing: border-box;
  font: small-caps 40016px/1.45'Source Code Pro';
}
*,
*:before,
*:after {
  box-sizing: inherit;
  margin: 0;
  padding: 0;
  border: 0 solid transparent;
}
/* REQUIRED */body {
  position: relative;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  width: 100vw;
  height: 100vh;
  overflow: auto;
  margin: auto;
  width: -moz-min-content;
  width: -webkit-min-content;
  width: min-content;
  height: -moz-min-content;
  height: -webkit-min-content;
  height: min-content;
}
.x {
  height: 600px;
  flex-flow: row nowrap;
  display: flex;
  align-items: center;
  justify-content: center;
  align-content: center;
}
.y {
  margin: auto;
  display: flex;
  flex-flow: column nowrap;
  align-items: center;
  justify-content: center;
  align-content: center;
  border: 2px dashed red;
}
/* DEMO */.ui {
  position: fixed;
  top: 1em;
  left: 1em;
  width: 500px;
  line-height: 1.3;
  z-index: 1;
}
fieldset {
  border: 1px solid lightgrey;
  border-radius: 6px;
}
input {
  width: 48px;
  line-height: 1.2;
  border: 1px solid grey;
  border-radius: 6px;
  padding: 2px;
  margin: 2px1px;
}
label {
  margin: 2px02px2px;
}
<!doctype html><html><head><metacharset="utf-8"><title>C.R.A.P.D. -=- Changing Rectangle Alignment, Position, and Dimensions</title></head><body><!-- DEMO --><headerclass="ui"><fieldset><legend>Changing Rectangle Alignment Position and Dimensions</legend><labelfor="w">Width
        <inputid="w"type="text"value="300" /></label><labelfor="h">Height
        <inputid="h"type="text"value="300" /></label><inputid="s"type="submit"value="Submit" /></fieldset></header><!-- REQUIRED --><mainclass="x"><sectionclass="y"><imgid="pic"src="http://placehold.it/300x300/" /></section></main></body></html>

Solution 4:

Found a solution with double flex container:

.body {
  height: 600px;
  overflow: auto;
  display: flex;
  flex-direction: column;
}
.container {
  display: flex;
  align-items: center;
  flex-grow: 1;
}
.content {
  flex-grow: 1;
  text-align: center;
}
img {
  border: 1px solid red;
}
<divclass="body"><divclass="container"><divclass="content"><imgsrc="http://placehold.it/700x700" /></div></div></div>

Post a Comment for "Centering Items With Flexbox And Overflow"