extra space when centering elements using flexbox - html

I'm using align-items and justify-content to center the elements, my html is:
<div class="flex-container">
<div class="item-1">div</div>
<div class="item-2">w=250px</div>
<div class="item-3">h=250px</div>
<div class="item-4">w/h=300px</div>
<div class="item-5">w=350px</div>
<div class="item-6">w=350px</div>
</div>
my css code is something like:
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: center;
align-content: center;
}
(I leave out some unimportant css code.)
so the result will be like:
but if I shrink the browser window, it will be like:
I don't understand why there is so much space between two lines (I know using align-content: center; can fix, but I want to know how those excess space is there in the first place)
* {
box-sizing: border-box;
font-size: 1.5rem;
}
html {
background: #b3b3b3;
padding: 5px;
}
body {
background: #b3b3b3;
padding: 5px;
margin: 0;
}
.flex-container {
background: white;
padding: 10px;
border: 5px solid black;
height: 800px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
.item-1 {
background: #ff7300;
color: white;
padding: 10px;
border: 5px solid black;
margin: 10px;
}
.item-2 {
background: #ff9640;
color: white;
padding: 10px;
border: 5px solid black;
margin: 10px;
width: 250px;
/* font-size: 1.8rem; */
}
.item-3 {
background: #ff9640;
color: white;
padding: 10px;
border: 5px solid black;
margin: 10px;
height: 250px;
}
.item-4 {
background: #f5c096;
color: white;
padding: 10px;
border: 5px solid black;
margin: 10px;
width: 300px;
height: 300px;
}
.item-5 {
background: #d3c0b1;
color: white;
padding: 10px;
border: 5px solid black;
margin: 10px;
width: 350px;
}
.item-6 {
background: #d3c0b1;
color: white;
padding: 10px;
border: 5px solid black;
margin: 10px;
width: 350px;
}
<div class="flex-container">
<div class="item-1">div</div>
<div class="item-2">w=250px</div>
<div class="item-3">h=250px</div>
<div class="item-4">w/h=300px</div>
<div class="item-5">w=350px</div>
<div class="item-6">w=350px</div>
</div>
and if I shrink the browser window more, then there is no such excess space:

align-content
Note that align-content: stretch is also in play here.
The align-content property distributes free space among flex lines. It's default value is stretch.
So when your items wrap to two lines, align-content: stretch distributes free space equally across lines.
align-items
Remove align-items: center from the container. You'll then notice that when items wrap, there is no gap between lines (or "rows", in this case). demo
Line heights are set by align-content, the height of the items, and the content of the items.
align-content and align-items working together
Restore align-items: center. Now when items wrap, there is a visible gap between lines.
This is because align-items: center positions the items in the vertical center of the line, based on line heights established by align-content: stretch, item heights, and item content.
The line heights are set here (with align-content: stretch and align-items: stretch):
... and continue here (with align-content: stretch and align-items: center):
align-items is having no effect on the height of the flex line. That job is andled by align-content.
However, by changing the value of align-content (to flex-start, flex-end, space-between, center, etc.), you pack the flex lines, squeezing out the free space, and hence removing the gaps.
Why is the first row taller than the second row with align-content: stretch?
The container is set to height: 800px.
There are two items with defined heights:
.item-3 { height: 250px }
.item-4 { height: 300px }
When .item-5 and .item-6 form the second row, the free space in the container is, in its simplest form, 500px (800px - 300px).
So, in a container with two rows and align-content: stretch, 250px is distributed to the height of each row.
first row is 300px (defined height) plus 250px (free space)
second row is 250px (free space)
That's why the first row is taller.
Just note that the free space calculation above is slightly off in the actual layout. That's because there is text in the items, which consumes free space. You can factor in the height of the text to get the precise figures, or remove the text altogether to see the calculations above fall into place.
More details:
How does flex-wrap work with align-self, align-items and align-content?
Equal height rows in a flex container

To make it easy, I will reduce the code so we can better understand the behavior.
Let's consider this initial code:
* {
box-sizing: border-box;
font-size: 1.5rem;
}
html {
background: #b3b3b3;
padding: 5px;
}
body {
background: #b3b3b3;
padding: 5px;
margin: 0;
}
.flex-container {
background: white;
padding: 10px;
border: 5px solid black;
height: 400px;
display: flex;
flex-direction: row;
flex-wrap:wrap;
}
.item-1 {
background: #ff7300;
color: white;
padding: 10px;
border: 5px solid black;
margin: 10px;
}
.item-2 {
background: #ff9640;
color: white;
padding: 10px;
border: 5px solid black;
margin: 10px;
width: 250px;
}
.item-3 {
background: #ff9640;
color: white;
padding: 10px;
border: 5px solid black;
margin: 10px;
height: 150px;
}
<div class="flex-container">
<div class="item-1">div</div>
<div class="item-2">w=250px</div>
<div class="item-3">h=150px</div>
</div>
The container has a fixed height and only one element has a fixed height and the other will be stretched to fill the parent height since by default align-items is stretch.
Now let's decrease the width of the container in order to make the third element in the second row:
* {
box-sizing: border-box;
font-size: 1.5rem;
}
html {
background: #b3b3b3;
padding: 5px;
}
body {
background: #b3b3b3;
padding: 5px;
margin: 0;
}
.flex-container {
background: white;
padding: 10px;
border: 5px solid black;
height: 400px;
display: flex;
flex-direction: row;
flex-wrap:wrap;
width:500px;
}
.item-1 {
background: #ff7300;
color: white;
padding: 10px;
border: 5px solid black;
margin: 10px;
}
.item-2 {
background: #ff9640;
color: white;
padding: 10px;
border: 5px solid black;
margin: 10px;
width: 250px;
}
.item-3 {
background: #ff9640;
color: white;
padding: 10px;
border: 5px solid black;
margin: 10px;
height: 150px;
}
<div class="flex-container">
<div class="item-1">div</div>
<div class="item-2">w=250px</div>
<div class="item-3">h=150px</div>
</div>
Here we have a complex behavior where we have a multiline flex container where item1 and item2 belong to the first line and item3 to the second line. I cannot explain very well how the height of each line is defined (the complex part). After this each flex item will stretch to fill the height of its line unless it has a fixed height like item3 or we change the alignment.
Now, if we change align-items to something different than stretch we will have the gap:
* {
box-sizing: border-box;
font-size: 1.5rem;
}
html {
background: #b3b3b3;
padding: 5px;
}
body {
background: #b3b3b3;
padding: 5px;
margin: 0;
}
.flex-container {
background: white;
padding: 10px;
border: 5px solid black;
height: 400px;
display: flex;
flex-direction: row;
flex-wrap:wrap;
width:500px;
align-items:flex-start;
}
.item-1 {
background: #ff7300;
color: white;
padding: 10px;
border: 5px solid black;
margin: 10px;
}
.item-2 {
background: #ff9640;
color: white;
padding: 10px;
border: 5px solid black;
margin: 10px;
width: 250px;
}
.item-3 {
background: #ff9640;
color: white;
padding: 10px;
border: 5px solid black;
margin: 10px;
height: 150px;
}
<div class="flex-container">
<div class="item-1">div</div>
<div class="item-2">w=250px</div>
<div class="item-3">h=150px</div>
</div>
If we compare the above code with the previous one we can see that item3 kept his place and only the height of item1 and item2 have changed. This explain that align-items will align items inside their lines that was previously defined due to wrapping.
In other words, when we have a multiline flex container we first define the lines (considering the height of the container, the height of elements and other flexbox properties) then we align the items inside their line and the gap we have is due to how the alignment is done.
Here is a better example to show different cases:
.flex-container {
background: white;
padding: 10px;
border: 5px solid black;
height: 200px;
display: inline-flex;
vertical-align:top;
flex-direction: row;
flex-wrap:wrap;
width:100px;
}
.item-1 {
background: #ff7300;
color: white;
border: 1px solid black;
margin: 2px;
}
.item-2 {
background: #ff9640;
color: white;
border: 1px solid black;
margin: 2px;
width: 70px;
}
.item-3 {
background: #ff9640;
color: white;
border: 1px solid black;
margin: 2px;
height: 50px;
}
<div class="flex-container">
<div class="item-1">A</div>
<div class="item-2">B</div>
<div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:flex-start;">
<div class="item-1">A</div>
<div class="item-2">B</div>
<div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:center;">
<div class="item-1">A</div>
<div class="item-2">B</div>
<div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:flex-end;">
<div class="item-1">A</div>
<div class="item-2">B</div>
<div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:flex-end;">
<div class="item-1">A</div>
<div class="item-2">B</div>
<div class="item-3" style="margin-bottom:auto;">C</div>
</div>
<div class="flex-container">
<div class="item-1" style="margin-top:auto;">A</div>
<div class="item-2">B</div>
<div class="item-3" >C</div>
</div>
We can clearly notice that we have the same lines accross all the container and only the alignment is changing which create different gaps.
In case there is no element with a fixed height, the lines will have the same height, so the container will be splitted equally.
.flex-container {
background: white;
padding: 10px;
border: 5px solid black;
height: 200px;
display: inline-flex;
vertical-align:top;
flex-direction: row;
flex-wrap:wrap;
width:100px;
}
.item-1 {
background: #ff7300;
color: white;
border: 1px solid black;
margin: 2px;
}
.item-2 {
background: #ff9640;
color: white;
border: 1px solid black;
margin: 2px;
width: 70px;
}
.item-3 {
background: #ff9640;
color: white;
border: 1px solid black;
margin: 2px;
}
<div class="flex-container">
<div class="item-1">A</div>
<div class="item-2">B</div>
<div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:flex-start;">
<div class="item-1">A</div>
<div class="item-2">B</div>
<div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:center;">
<div class="item-1">A</div>
<div class="item-2">B</div>
<div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:flex-end;">
<div class="item-1">A</div>
<div class="item-2">B</div>
<div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:flex-end;">
<div class="item-1">A</div>
<div class="item-2">B</div>
<div class="item-3" style="margin-bottom:auto;">C</div>
</div>
<div class="flex-container">
<div class="item-1" style="margin-top:auto;">A</div>
<div class="item-2">B</div>
<div class="item-3" >C</div>
</div>
By changing align-content we will change how the lines are created before considering align-items to align the items inside their lines:
.flex-container {
background: white;
padding: 10px;
border: 5px solid black;
height: 200px;
display: inline-flex;
vertical-align:top;
flex-direction: row;
flex-wrap:wrap;
width:100px;
}
.item-1 {
background: #ff7300;
color: white;
border: 1px solid black;
margin: 2px;
}
.item-2 {
background: #ff9640;
color: white;
border: 1px solid black;
margin: 2px;
width: 70px;
}
.item-3 {
background: #ff9640;
color: white;
border: 1px solid black;
margin: 2px;
height:50px;
}
<div class="flex-container">
<div class="item-1">A</div>
<div class="item-2">B</div>
<div class="item-3">C</div>
</div>
<div class="flex-container" style="align-content:flex-start;">
<div class="item-1">A</div>
<div class="item-2">B</div>
<div class="item-3">C</div>
</div>
<div class="flex-container" style="align-content:center;">
<div class="item-1">A</div>
<div class="item-2">B</div>
<div class="item-3">C</div>
</div>
<div class="flex-container" style="align-content:flex-end;">
<div class="item-1">A</div>
<div class="item-2">B</div>
<div class="item-3">C</div>
</div>
In order to understand the complex part of this answer (how lines are defined) you can refer to the specification : https://www.w3.org/TR/css-flexbox-1/#layout-algorithm

Related

How to start a new line and align the newline with another item within flexbox?

I have a flexbox with different items inside.
When it wraps onto a new line I want to align this new line with the 2nd item on the first row of the flexbox, but I can't figure out how to do this. The width of the elements will be dynamic, based on the text inside.
div {
font-family: arial, sans-serif;
margin: 5px;
color: white;
border: 1px dotted black;
}
.parent {
display: flex;
flex-wrap: wrap;
width: 300px;
}
.unique_element {
background-color: Crimson;
width: 30%;
padding: 10px 10px 10px 10px;
}
.child {
background-color: CornflowerBlue;
padding: 10px 10px 10px 10px;
}
<div class="parent">
<div class="unique_element">First</div>
<div class="child">Second</div>
<div class="child">Third</div>
<div class="child">Fourth</div>
<div class="child">Fifth</div>
</div>
When it wraps onto a new line I want to align this new line with the 2nd item on the first row of the flexbox.
So, the real question is: How to re-arrange flex items when wrapping occurs?
Since HTML and CSS, by themselves, have no concept of when elements wrap, they have no control of this situation. You have to handle it, either with media queries or JavaScript.
Once you've selected your method for detecting the wrap, you can use the order property to re-arrange the items.
To expand on #MichaelBenjamin's fantastic answer:
Since HTML and CSS, by themselves, have no concept of when elements wrap, they have no control of this situation. You have to handle it, either with media queries or JavaScript.
You can work around this by setting a new parent element and nest the unique element as the first child. Set this new master-parent to display: flex;.
div {
font-family: arial, sans-serif;
margin: 5px;
color: white;
border: 1px dotted black;
}
.parent {
display: flex;
flex-wrap: wrap;
width: 300px;
}
.unique_element {
background-color: Crimson;
width: 30%;
height: 27px;
padding: 10px 10px 10px 10px;
}
.child {
background-color: CornflowerBlue;
padding: 10px 10px 10px 10px;
}
.master-parent {
display: flex;
width: 400px;
}
<div class="master-parent">
<div class="unique_element">First</div>
<div class="parent">
<div class="child">Second</div>
<div class="child">Third</div>
<div class="child">Fourth</div>
<div class="child">Fifth</div>
</div>
</div>
You can create two divs inside the parent div, one that holds the unique element and one that holds generic children. That's how you get the separation
<div class="parent">
<div class="unique-wrapper">
<div class="unique_element">First</div>
</div>
<div class="child-wrapper">
<div class="child">Second</div>
<div class="child">Third</div>
<div class="child">Fourth</div>
<div class="child">Fifth</div>
</div>
</div>
Style the CSS as shown. Note .unique-wrapper has flex: 3 because you set the width of the element as 30%.
div {
font-family: arial, sans-serif;
margin: 5px;
color: white;
border: 1px dotted black;
}
.parent {
display: flex;
width: 300px;
}
.unique_element {
background-color: Crimson;
padding: 10px 10px 10px 10px;
}
.unique-wrapper, .child-wrapper {
border: none;
margin: 0;
}
.unique-wrapper {
flex: 3;
}
.child-wrapper {
flex: 7;
display: flex;
flex-wrap: wrap;
}
.child {
width: auto;
background-color: CornflowerBlue;
padding: 10px 10px 10px 10px;
}
Here is my codepen if you want to play with the code.
create a dummy element for spacing
div {
font-family: arial, sans-serif;
margin: 5px;
color: white;
border: 1px dotted black;
}
.parent {
display: flex;
flex-wrap: wrap;
width: 300px;
}
.unique_element {
background-color: Crimson;
width: 30%;
padding: 10px 10px 10px 10px;
}
.child {
background-color: CornflowerBlue;
padding: 10px 10px 10px 10px;
}
.hideme{
visibility:invisible;
background-color:white;
border:none;
}
<div class="parent">
<div class="unique_element">First</div>
<div class="child">Second</div>
<div class="child">Third</div>
<div class="unique_element hideme"></div>
<div class="child">Fourth</div>
<div class="child">Fifth</div>
</div>

place button at the right of div

here is how my screen should look like:
the orange button should be on the right of the "dashboard-detail-body" and have margins to the top, left, and bottom ("dashboard-container")
this is what I tried:
<div class="dashboard-detail-body">
<div style="float: right; margin-right: 10px; margin-top: 15px;">
{{ui-5/button label="click me"}}
</div>
<div class="dashboard-container">
but I do not get the desired behavior - no margin bottom (the orange button is overlapping with the bottom div)
margin-bottom, did not solve it, how can I get the desired behavior?
The issue is with the float: right; style. This makes the element overlap.
You can solve this issue by using flex-box, with the following code:
.dashboard-detail-body{
display: flex;
flex-direction:column;
}
.align-right{
align-self: flex-end;
}
<div class="dashboard-detail-body">
<div class="align-right">
I am right
</div>
<div class="dashboard-container">
<p>a<p>
<p>b<p>
<p>c<p>
</div>
</div>
Though it was difficult to understand and recreate your problem from the available data, I assume that you want to align a button center-right inside the container. You can use flexbox to align elements inside a parent.
.container {
height: 200px;
border: solid 1px #333;
display: flex;
justify-content: right;
align-items: center;
}
button.orange {
border: none;
outline: none;
height: 1.5rem;
/* optional basic styling */
background: orange;
color: #fff;
}
<div class="container">
<button class="orange">Click Me</button>
</div>
You can try with css grid:
.dashboard-detail-body{
display: grid;
grid-template-columns: 1fr;
justify-items: center;
border: 1px solid grey;
border-radius: 2em;
}
.right{
justify-self: end;
margin: 1em 3em 1em 1em;
background-color: orange;
padding: .5em;
border-radius: .5em;
}
.dashboard-container {
display: flex;
justify-content: center;
align-items: start;
border: 1px dashed grey;
border-radius: 1.5em;
margin-bottom: 2em;
width: 95%;
height: 200px;
}
.dashboard-container > p {
padding: 1.5em 2em;
margin: 1em;
border: 1px solid grey;
border-radius: .5em;
}
<div class="dashboard-detail-body">
<div class="right">
click me
</div>
<div class="dashboard-container">
<p></p>
<p></p>
<p></p>
</div>
</div>
As you are shrinking your div with float right it frees space on the left. The clear property doesn't work.
So the solution I came up with is to keep the div full & use a button
.dashboard-detail-body {
background: #eeeeee;
border: 3px solid #bbbbbb;
border-radius: 20px;
height: 80vh;
width: 80%;
min-height: 40rem;
min-width: 45rem;
margin: auto;
}
.btn-area {
height: 5rem;
width: 100%;
/* border: 1px solid red; */
}
.btn {
background: #ff9900;
padding: 10px 15px;
border-radius: 10px;
border: 2px solid #9c7842;
/* clear: left; */
/* display: inline-block; */
float: right;
margin-right: 25px;
margin-top: 25px;
}
.dashboard-container {
border: 3px solid #bbbbbb;
margin: auto;
width: 75%;
height: 75%;
border-radius: 20px;
display: flex;
justify-content: center;
/* align-items: center; */
}
.box {
border: 3px solid #bbbbbb;
width: 6.5rem;
height: 6.5rem;
border-radius: 20px;
float: left;
margin: 1rem;
}
<div class="dashboard-detail-body">
<div class="btn-area">
<button class="btn">Click Me</button>
</div>
<div class="dashboard-container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>

Having trouble with flexbox properties

I have few problems to fix, that are
1- Why logo class properties not working ?
2- Why class title does not move to right, ie justify-content: flex-end not working OR which other way this can be done ?
3- Do I have to write display: flex; in all parent classes or simply container, which has all of them inside is enough ?
4- How it effect if I use display: flex; on all parent classes ?
Many Thanks
---HTML---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name = "viewport" content = "width=device-width", initial-scale = 1.0>
<title>My Portfolio</title>
<link rel="stylesheet" type="text/css" href="port.css">
</head>
<body>
<div class="container">
<div class="header">
<div id="logo"> Logo </div>
<div class="title">JAMES O BRAIN
<div class="sub-title">FRONT-END MONK</div> </div>
</div>
<div class="container2">
<div class="centre-picture">Central Pic</div>
<div class="left-boxs">
<div class="blue-box">Blue Box</div>
<div class="grey-box">Grey Box</div>
<div class="green-box">Green Box</div>
</div>
</div>
<div class="bottom-boxs">
<div class="featured-work">Featured Work</div>
<div class="appify">APPIFY</div>
<div class="sunflower">SUNFLOWER</div>
<div class="bokeh">BOKEH</div>
</div>
</div>
</body>
</html>
---CSS---
.container {
display: flex;
flex-direction: column;
border: 5px solid black;
margin: 10px;
padding: 50px;
}
.header {
display: flex;
border: 5px solid green;
}
.logo {
/* why these all properties not working at all ? */
border: 3px solid black;
padding: 10px;
margin: 10px;
}
.title {
border: 3px solid orange;
justify-content: flex-end; /* why this property not working, how can i get this to right ?*/
padding: 10px;
margin: 10px;
}
.sub-title {
border: 3px solid black;
padding: 5px;
margin: 5px
}
.container2 {
display: flex;
border: 5px solid red;
margin: 10px;
padding: 10px;
height: 300px;
}
.centre-picture {
border: 3px solid black;
margin: 10px;
padding: 10px;
}
.left-boxs {
border: 3px solid goldenrod;
margin: 10px;
padding: 10px;
order: -1;
}
.green-box {
background-color: green;
padding: 5px;
margin: 5px
}
.blue-box {
background-color: blue;
padding: 5px;
margin: 5px
}
.grey-box {
background-color: grey;
padding: 5px;
margin: 5px
}
.bottom-boxs {
display: flex;
border: 5px solid blue;
}
.appify {
border: 3px solid black;
margin: 10px;
padding: 10px;
}
.sunflower {
border: 3px solid black;
margin: 10px;
padding: 10px;
}
.bokeh {
border: 3px solid black;
margin: 10px;
padding: 10px;
}
As Daniel stated, you should make sure that you are not confusing #id and .class selectors in your markup/CSS. In your stylesheet you should be using #logo instead of .logo.
There are several ways you can align the items in your header. In the example below I attached justify-content: space-between; to the .header div which will align any direct child elements with an even amount of left over space between them. There are other ways you can do this...this is just one option. You can play around with margins, padding, and other flexbox values to see what works best for you.
Giving a container display: flex will have effect on all of the children elements inside the container, but not the contents inside each of those children. For example: If you have a container with three div elements inside it, and you give the container display: flex; justify-content: center; this will center each div horizontally, but not the text, images, etc, inside each div. In your case, at least in this example, yes, you need to add display: flex; to each of the divs inside the header in order to apply flexbox properties to the text inside.
Hope that helps a little. See the snippet below for one example. Good luck!
.container {
display: flex;
flex-direction: column;
border: 5px solid black;
width: 80%;
padding: 50px;
}
.header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
border: 5px solid green;
padding: 10px;
}
#logo {
display: flex;
justify-content: center;
align-items: center;
border: 3px solid black;
padding: 10px;
}
.title {
display: flex;
justify-content: center;
align-items: center;
border: 3px solid orange;
padding-left: 10px;
}
.sub-title {
display: flex;
justify-content: center;
align-items: center;
margin: 10px;
padding: 10px;
border: 3px solid black
}
<div class="container">
<div class="header">
<div id="logo">Logo</div>
<div class="title">JAMES O BRAIN
<div class="sub-title">
FRONT-END MONK
</div>
</div>
</div>
</div>
It's because in your HTML you are using an id, #, but your CSS is targeting a class .. Change your CSS to this instead:
#logo {
/* why these all properties not working at all ? */
border: 3px solid black;
padding: 10px;
margin: 10px;
}

How to center inline-block element with margin

HTML:
<div id="wrap">
<div id="block1"></div>
<div id="block2"></div>
</div>
CSS:
div#wrap{
margin-top: 3em;
border: solid 1px black;
text-align: center;
}
div#wrap *{
display: inline-block;
width: 12.5em;
margin-top: 1em;
height: 8em;
}
div#wrap *:not(:last-child){
margin-right: 8em;
}
#block1{
background: orange;
}
div#wrap #block2{
background: magenta;
}
These 2 blocks are supposed to be centered in responsive design mode. When the screen is wide enough to have 2 blocks in a row, the code works. But when I narrow the screen down, the top block is shifted to the left because of the margin:
fiddle
Is it possible to fix this without media queries?
Edit
I tried flex-box:
div#wrap{
margin-top: 3em;
border: solid 1px black;
display: flex;
flex-flow: row wrap;
justify-content: center;
}
fiddle2
A solution is to use flex and justify-content:space-around and remove margin:
div#wrap {
margin-top: 3em;
border: solid 1px black;
justify-content:space-around;
display: flex;
flex-wrap: wrap;
}
div#wrap * {
display: inline-block;
width: 12.5em;
margin-top: 1em;
height: 8em;
}
#block1 {
background: orange;
}
#block2 {
background: magenta;
}
<div id="wrap">
<div id="block1"></div>
<div id="block2"></div>
</div>
If you use a container with negative margin, you don't need to vary the margin for the endpoints of the rows at different breakpoints and you can just go with inline-block. I set font-size to zero in the container so I can calculate my widths using percents without worrying about white space.
div#wrap {
margin-top: 3em;
border: solid 1px black;
padding: 20px;
text-align: center;
}
.block {
display: inline-block;
width: 12.5em;
margin: 20px;
height: 8em;
font-size: 16px;
}
.block-container {
margin: -20px;
font-size: 0;
}
#block1 {
background: orange;
}
#block2 {
background: magenta;
}
<div id="wrap">
<div class="block-container">
<div class="block" id="block1"></div>
<div class="block" id="block2"></div>
</div>
</div>

How does CSS flex-basis affect the width calculation of its container?

In the following example, the flex-basis: 30px and width: 30px of a flex item will result in different container width(flex-basis is shorter).
How does flex-basis affect its parent width in the following example:
.flex-container {
padding: 0;
margin: 0;
display: flex;
border: 1px solid blue;
}
.grand {
display: flex;
border: 1px solid green;
}
.flex-item {
background: tomato;
padding: 10px;
border: 1px solid red;
color: white;
font-size: 2em;
}
.flex1 {
flex-shrink: 0; /* added according to Michael_B's answer */
flex-basis: 100px;
}
<div class="grand">
<div class="flex-container">
<div class="flex-item flex1">1</div>
<div class="flex-item flex2">22222 222222222</div>
</div>
</div>
The is the expected behavior:
.flex-container {
padding: 0;
margin: 0;
display: flex;
border: 1px solid blue;
}
.grand {
display: flex;
border: 1px solid green;
}
.flex-item {
background: tomato;
padding: 10px;
border: 1px solid red;
color: white;
font-size: 2em;
}
.flex1 {
/* flex-basis: 100px; */
width: 100px;
}
<div class="grand">
<div class="flex-container">
<div class="flex-item flex1">1</div>
<div class="flex-item flex2">22222 222222222</div>
</div>
</div>
In the flex-basis version, the flex2 item will wrap the text, while the width version will not. How did that happen.