I am trying to center two div
elements side by side in a row with flexbox (display:flex
).
The first div
element, on the left, just has an image.
The second div
element, on the right, has left-aligned inline text of unspecified length.
When the line of text is short enough to fit on one line, both divs are aligned and justified to the center as I expect.
When the line of text is long enough to wrap onto two lines, the second div
element does not wrap itself around the content as I expect. Instead, it leaves a large white space on the right side of the div
.
I mocked up an example here: http://codepen.io/anon/pen/NGqYQX?editors=110. Vary your browser window's width to see what I mean.
How can I set the second div
element to shrink itself to fit the text, so that both div
elements appear centered?
HTML:
<div class="flexbox-container">
<div class="div1">
<img src="http://dreamatico.com/data_images/kitten/kitten-2.jpg" width="150px">
</div>
<div class="div2">
This is an example of a line of text.
</div>
</div>
<br>
<div class="flexbox-container">
<div class="div1">
<img src="http://dreamatico.com/data_images/kitten/kitten-2.jpg" width="150px">
</div>
<div class="div2">
This is an example of a much loooooooooooooonger line of text.
</div>
</div>
CSS:
.flexbox-container {
display: flex;
justify-content: center;
align-items: center;
}
.div1 {
margin-right: 30px;
}
.div2 {
font-size: 48px;
line-height: 48px;
text-align: left;
}
Here is a Photoshop mockup showing what I am trying to do:
In order to achieve your goal (as specified in your second image) we need to make a few adjustments to your HTML and CSS. Everything can be done with flexbox.
HTML
<div id="flex-container-main">
<div class="flex-container-child">
<figure>
<img src="http://dreamatico.com/data_images/kitten/kitten-2.jpg" width="150px">
</figure>
<p>This is an example of a line of text.</p>
</div>
<div class="flex-container-child">
<figure>
<img src="http://dreamatico.com/data_images/kitten/kitten-2.jpg" width="150px">
</figure>
<p>This is an example of a much loooooooooooooonger line of text.</p>
</div>
</div><!-- end #flex-container-main -->
CSS
#flex-container-main {
display: flex;
flex-direction: column;
align-items: center;
}
.flex-container-child {
display: flex;
align-items: center;
min-height: 127px;
width: 75%;
margin: 10px;
}
figure {
margin: 0 20px 0 0;
}
img {
width: 150px;
height: 127px;
vertical-align: bottom;
}
p {
font-size: 48px;
margin: 0;
}
Here's what's happening...
Your question asks:
Keeping flexbox centered when text wraps to 2 or more lines
I am trying to center two div elements side by side in a row with flexbox (
display:flex
).
Let's quickly go over your two images.
Image 1
Image 2
In image 1 all flex items are actually centered. The blue highlight from Chrome Dev Tools emphasizes this point. Each item is perfectly centered on the screen.
Yes, it does get a bit clunky as you re-size the screen smaller – mostly because of the large font size – but the flex items remain centered nonetheless.
In image 2, the flex items are not evenly centered. What you've created in your mock-up is more like a column containing both flexboxes, and the column is centered. But individually only the first row is centered on the screen.
A couple of notes about your code:
justify-content
declared on the flex containers, you are centering the flex items. The flex container itself is not centered.<body>
, and <body>
has no defined width, the flexboxes align themselves in relation to the viewport.So to achieve the effect you want we can wrap all your existing mark-up in a new flex container (#flex-container-main
). This converts the original flex containers into flex items, which can then be evenly centered as a group.
The new flex items (now classed as .flex-container-child
) are given a width to create space and a minimum height based on the height of the image. Each flex item is also declared a flex parent (display: flex
) which allows us to use flex properties on child elements. In particular, this is useful for vertically centering the text (as shown in your images).
(Note that my use of HTML semantic elements is not necessary for the code to work. If you prefer the original div
tags just swap them back. The important adjustment is the new parent container.)
Lastly (and this may not be important to your layout but just in case), browsers normally give images a small gap of whitespace under their bottom border. This is used to accommodate descenders. With vertical-align: bottom
, this space is removed. (For more details see my answer about descenders.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With