How to Center One of the Flex/Grid Children(More Than Three) and with Different Widths

Is there a way to center one of the flex/grid children(more than three) and with different widths?

This is not currently possible.

At present there is NO, Flexbox, CSs-Grid or any other layout method or algorithm that allows for centering an element without taking the size of sibling elements into consideration.

You will require Javascript to adjust margins or re-arrange your HTML structure to accomodate your design choices.

It IS possible to center the specific element using absolute positioning (although you have ruled this out) but this ignores the other siblings completely thus their "positions" might be affected and we again fall back on JS being required.

Keep the middle item centered when side items have different widths

If the left and right boxes would be exactly the same size, I get the desired effect. However when one of the two is a different size the centered box is not truly centered anymore. Is there anyone that can help me?

Here's a method using flexbox to center the middle item, regardless of the width of siblings.

Key features:

  • pure CSS
  • no absolute positioning
  • no JS/jQuery

Use nested flex containers and auto margins:

.container {  display: flex;}.box {  flex: 1;  display: flex;  justify-content: center;}
.box:first-child > span { margin-right: auto; }
.box:last-child > span { margin-left: auto; }
/* non-essential */.box { align-items: center; border: 1px solid #ccc; background-color: lightgreen; height: 40px;}p { text-align: center; margin: 5px 0 0 0;}
<div class="container">  <div class="box"><span>short text</span></div>  <div class="box"><span>centered text</span></div>  <div class="box"><span>loooooooooooooooong text</span></div></div><p>↑<br>true center</p>

How can I have two fixed width columns with one flexible column in the center?

Instead of using width (which is a suggestion when using flexbox), you could use flex: 0 0 230px; which means:

  • 0 = don't grow (shorthand for flex-grow)
  • 0 = don't shrink (shorthand for flex-shrink)
  • 230px = start at 230px (shorthand for flex-basis)

which means: always be 230px.

See fiddle, thanks @TylerH

Oh, and you don't need the justify-content and align-items here.

img {
max-width: 100%;
}
#container {
display: flex;
x-justify-content: space-around;
x-align-items: stretch;
max-width: 1200px;
}
.column.left {
width: 230px;
flex: 0 0 230px;
}
.column.right {
width: 230px;
flex: 0 0 230px;
border-left: 1px solid #eee;
}
.column.center {
border-left: 1px solid #eee;
}

Justify-content: center breaks if child's content is wrapped onto more than 1 row with flex-wrap: wrap

You can only achieve this if you set a fixed width to the container that holds the flexbox-items. You can make it a bit simpler and use calc(...) function in CSS here. If you know how many items should be in one row, you can just change the number for multiple breakpoints easily. Even easier if you set the width of one item as a css custom property.

#container {
width: 500px;
display: flex;
justify-content: center;
background-color: #c0faff;
}

#parent {
display: flex;
flex-wrap: wrap;
width: calc(4* 110px)
}

.child {
background-color: #5bb4bb;
width: 100px;
height: 100px;
margin: 5px;
}
<div id="container">
<div id="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>

Positioning two div elements relative to the middle one

You can try with css grid :

#row {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
justify-content: space-between;
align-items: center;
text-align: center;
}

#logo {
height: 20px;
width: 80px;
background-color: red;
}

#contacts {
background-color: blue;
text-align: right;
}

#center-navigation {
background-color: green;
}

h1 {
text-align: center;
background-color: yellow;
}
<div id="row">
<div id="logo">

</div>
<div id="center-navigation">
Some navigation here
</div>
<div id="contacts">
example@mail.org
</div>
</div>
<h1>
Some long website title goes here
</h1>

Align arbitrary number of elements with different widths to a grid with wrapping

CSS grid-template-columns does support content-aware value which is max-content. The only question is that how many columns should be there.

I write an algorithm to probe maximum number of column. The implementation involves JS and requires browser to support CSS Grid. Demo can be found here. (I use Pug to create same source structure as yours and styling is also same as yours so that we can focus on JS panel, the implementation).

In demo, changing viewport size will re-flow grid items. You may trigger re-flow at other interesting moments manually by calling flexgrid(container), e.g. loading items asynchronously then re-flow. Changing dimension properties of items is allowed as long as source structure keeps unchanged.

Here's the algorithm

Step1) Set container as grid formatting context, layout all grid items in one row, set each column width to max-content

|---container---|
|aaaaa|bbb|ccc|ddd|eee|fff|ggggg|hhh|iii|

Step2) find first overflow grid line

|---container---|
|aaaaa|bbb|ccc|ddd|eee|fff|ggggg|hhh|iii|
^overflowed

Step3) reduce grid-template-columns to, in our case, 3.
Since grid-row default to auto, CSS engine layouts a grid item
on next row when it goes beyond last column grid line. I called this
"wrapping". In addition, grid items are auto expanded due to grid-template-columns:max-content(e.g. "ddd" is expanded to the length of widest content of first column)

|---container---|
|aaaaa|bbb|ccc|
|ddd |eee|fff|
|ggggg|hhh|iii|

Since all column grid lines sit "inside" container, we have done. In some cases, a new overflowed grid line is being introduced after "wrapping", we need to repeat step2&3 until all grid lines sit "inside" container, e.g.

#layout in one row
|---container---|
|aaaaa|bbb|ccc|ddd|eee|fff|ggggggg|hhhhh|iii|

#find the first overflowed grid line
|---container---|
|aaaaa|bbb|ccc|ddd|eee|fff|ggggggg|hhhhh|iii|
^overflowed

#reduce `grid-template-columns`
|---container---|
|aaaaa |bbb |ccc|
|ddd |eee |fff|
|ggggggg|hhhhh|iii|

#find the first overflowed grid line
|---container---|
|aaaaa |bbb |ccc|
|ddd |eee |fff|
|ggggggg|hhhhh|iii|
^overflowed

#reduce `grid-template-columns`
|---container---|
|aaaaa |bbb |
|ccc |ddd |
|eee |fff |
|ggggggg|hhhhh|
|iii |

#find the first overflowed grid line
#None, done.

Center one and right/left align other flexbox element

Below are five options for achieving this layout:

  • CSS Positioning
  • Flexbox with Invisible DOM Element
  • Flexbox with Invisible Pseudo-Element
  • Flexbox with flex: 1
  • CSS Grid Layout

Method #1: CSS Positioning Properties

Apply position: relative to the flex container.

Apply position: absolute to item D.

Now this item is absolutely positioned within the flex container.

More specifically, item D is removed from the document flow but stays within the bounds of the nearest positioned ancestor.

Use the CSS offset properties top and right to move this element into position.

li:last-child {  position: absolute;  top: 0;  right: 0;  background: #ddd;}ul {  position: relative;  padding: 0;  margin: 0;  display: flex;  flex-direction: row;  justify-content: center;  align-items: center;}li {  display: flex;  margin: 1px;  padding: 5px;  background: #aaa;}p {  text-align: center;  margin-top: 0;}span {  background-color: aqua;}
<ul>  <li>A</li>  <li>B</li>  <li>C</li>  <li>D</li></ul><p><span>true center</span></p>

Three-column HTML flex box: how to set the middle one to get all the remaining space?

The proper way to do it is with flex. Set flex to 1 1 auto for the middle column, and 0 0 100px for the side columns. This makes it so the side columns are always the specified width (or width of content, if set to auto), and the middle column takes up the remaining space (growing/shrinking accordingly).

#main-container {  display: flex;  justify-content: space-between;  align-items: center;}
#center-content { /* Lets middle column shrink/grow to available width */ flex: 1 1 auto;}
#left-content,#right-content { /* Forces side columns to stay same width */ flex: 0 0 100px;}
img { /* Shrinks images to fit container */ max-width: 100%;}
<div id="main-container">  <div id="left-content">    <div><img src="http://agevoluzione.com/wp-content/uploads/2014/07/Work-in-progress-1024x603.png"></div>    <div><img src="http://agevoluzione.com/wp-content/uploads/2014/07/Work-in-progress-1024x603.png"></div>    <div><img src="http://agevoluzione.com/wp-content/uploads/2014/07/Work-in-progress-1024x603.png"></div>    <div><img src="http://agevoluzione.com/wp-content/uploads/2014/07/Work-in-progress-1024x603.png"></div>  </div>
<div id="center-content"> <div><img src="https://farm6.staticflickr.com/5560/14080568109_9f33dc7964_o.jpg"></div> </div>
<div id="right-content"> <div><img src="http://agevoluzione.com/wp-content/uploads/2014/07/Work-in-progress-1024x603.png"></div> <div><img src="http://agevoluzione.com/wp-content/uploads/2014/07/Work-in-progress-1024x603.png"></div> <div><img src="http://agevoluzione.com/wp-content/uploads/2014/07/Work-in-progress-1024x603.png"></div> <div><img src="http://agevoluzione.com/wp-content/uploads/2014/07/Work-in-progress-1024x603.png"></div> </div></div>


Related Topics



Leave a reply



Submit