Centering Items With Flexbox And Overflow
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 */
}
<div class="body">
<div class="container">
<img src="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;
}
<body class="flex">
<main class="container">
<img src="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;
}
<body class="flex">
<main class="container">
<img src="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
Define
<body>
because if you don't then you can't dictate how far your scrollbars can go.♦
position: relative
,top, bottom, right,
andleft
at 0 stretches the<body>
to cover the viewport.♦
width
andheight
of body are100vw
and100vh
enforcing a limit on<body>
♦ Since
<body>
is a container allflexbox
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.The outer container
.x
hasflexbox
properties to center the inner container.y
.In addition you'll notice a very little known property..y
hasflex-flow: column nowrap
to center the image.body
hasmin-content
applied to bothheight
andwidth
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:
- Centered horizontally
- Centered vertically
- 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 400 16px/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: 2px 1px;
}
label {
margin: 2px 0 2px 2px;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>C.R.A.P.D. -=- Changing Rectangle Alignment, Position, and Dimensions</title>
</head>
<body>
<!-- DEMO -->
<header class="ui">
<fieldset>
<legend>Changing Rectangle Alignment Position and Dimensions</legend>
<label for="w">Width
<input id="w" type="text" value="300" />
</label>
<label for="h">Height
<input id="h" type="text" value="300" />
</label>
<input id="s" type="submit" value="Submit" />
</fieldset>
</header>
<!-- REQUIRED -->
<main class="x">
<section class="y">
<img id="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;
}
<div class="body">
<div class="container">
<div class="content">
<img src="http://placehold.it/700x700" />
</div>
</div>
</div>
Post a Comment for "Centering Items With Flexbox And Overflow"