How to create margins to the side of inline-flex elements? [duplicate] - css

This question already has answers here:
Equal space between flex items
(6 answers)
Closed 3 years ago.
The community reviewed whether to reopen this question last month and left it closed:
Original close reason(s) were not resolved
I am creating a flexbox layout. I want two flex containers to be displayed inline and have an equal amount of space between them and back sides of the screen (that is, equal margin-left of the first one and margin-right of the second one).
Now all I know about CSS flexboxes is display: flex and display: inline-flex, so I would want to avoid solution paths that include advanced flexbox properties.
To do so, I set the document's margin and padding to 0, box-sizing to border-box to prevent the containers from changing their original width, set the display property to inline-flex, gave both containers equal measurements.
.item1 {
display: inline-flex;
margin-top: 5vh;
background-color: #ff8000;
border: 3px solid transparent;
height: 30vh;
width: 40vw;
/*margin-left: 9vw;*/
}
.item2 {
margin-top: 5vh;
display: inline-flex;
background-color: #ff8000;
border: 3px solid transparent;
height: 30vh;
width: 40vw;
/*margin-right: 9vw;*/
}
<div class="item1"></div>
<div class="item2"></div>
I also set margin-left of the first item equal to the margin-right of the second one, but they're blatantly different visually.

In this situation, you want to use the flex property justify-content: space-evenly;. What this will do, is spacing all the elements evenly, including the right and left margins.
But for that, you need to create a container with the items you want inside. Look at the following example:
.flex{
display: flex;
justify-content: space-evenly;
}
.item {
margin-top: 5vh;
background-color: #ff8000;
border: 3px solid transparent;
height: 30vh;
width:20vw;
}
<div class="flex">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>

Check this Example:
.flex {
display: flex;
}
.center {
margin: auto;d
}
.item1 {
display: inline-flex;
margin-top: 5vh;
background-color: #ff8000;
border: 3px solid transparent;
height: 30vh;
width: 40vw;
/*margin-left: 9vw;*/
}
.item2 {
margin-top: 5vh;
display: inline-flex;
background-color: #ff8000;
border: 3px solid transparent;
height: 30vh;
width: 40vw;
/*margin-right: 9vw;*/
}
<!-- display: flex to center it's content-->
<div class="flex">
<!-- margin: auto to to be centered -->
<div class="center">
<div class="item1"></div>
<div class="item2"></div>
</div>
</div>

Related

Wrapped flex row items start at top [duplicate]

This question already has answers here:
What's the difference between align-content and align-items?
(15 answers)
CSS Flexbox: difference between align-items and align-content [duplicate]
(2 answers)
Closed 5 years ago.
Whilst trying to answer this question, I was trying to come up with a flex solution. The closest I could get was this:
.container {
height: 500px;
width: 500px;
background-color: red;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content:space-between; /* puts spacing between left and right column */
}
.headerTitle {
width:100%;
height: 24px;
margin: 24px 24px 0;
padding: 0;
line-height: 24px;
}
.sectionClass {
width: 249px;
height: 200px;
background-color: yellow;
}
.rightSideDiv {
width: 249px;
height: 200px;
border: 4px solid green;
box-sizing:border-box; /* need this otherwise border will take an extra 8px width in some browsers */
}
<aside>
<div class="container">
<header class="headerTitle"> Header Title </header>
<section class="sectionClass"> . </section>
<div class="rightSideDiv"> </div>
</div>
</aside>
However, I couldn't make the 2 lower boxes start flush to the top heading. Is there a way of doing this using flex? I tried align-items and align-self but that didn't seem to do anything.
I also tried adding a pseudo element to the container with flex-grow:1; but it didn't grow in the required manner.
It would be interesting to see if flex can handle this as I'm still trying to learn the intricacies of it
Just add align-content: flex-start to the .container div:
.container {
height: 500px;
width: 500px;
background-color: red;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content:space-between; /* puts spacing between left and right column */
align-content: flex-start;
}
.headerTitle {
width:100%;
height: 24px;
margin: 24px 24px 0;
padding: 0;
line-height: 24px;
}
.sectionClass {
width: 249px;
height: 200px;
background-color: yellow;
}
.rightSideDiv {
width: 249px;
height: 200px;
border: 4px solid green;
box-sizing:border-box; /* need this otherwise border will take an extra 8px width in some browsers */
}
<aside>
<div class="container">
<header class="headerTitle"> Header Title </header>
<section class="sectionClass"> . </section>
<div class="rightSideDiv"> </div>
</div>
</aside>

how to vertical align bottom inline block elements in container [duplicate]

This question already has answers here:
vertical align bottom + inline block
(2 answers)
Closed 6 years ago.
I have the following html structure
<div class="examples">
<div class="option"></div>
<div class="option"></div>
<div class="option"></div>
</div>
CSS:
.examples {
whitespace: nowrap;
min-height: 400px;
}
.option {
width: 18%;
max-width: 18%;
margin-top: 10px;
margin-bottom: 10px;
margin-right: 1%;
vertical-align: bottom;
cursor: pointer;
border: 4px solid red;
display: inline-block;
}
How can I vertically align inline blocks (option) at the bottom of the container (examples) using CSS? These are a row of images inside the examples container. I tried vertical align: bottom, but that doesn't work and I want to stay away from flex because of lack of cross browser support. I also want to stay away from absolute position because the elements (option) are a row of images.
You'll probably want to use flexbox and use display: flex; justify-content: flex-end; on the container div. That should put them at the bottom.
.examples {
whitespace: nowrap;
min-height: 400px;
position: relative;
background: blue;
}
.aligner {
position: absolute;
bottom: 0;
width: 100%;
}
.option {
width: 18%;
max-width: 18%;
margin-top: 10px;
margin-bottom: 10px;
margin-right: 1%;
cursor: pointer;
border: 4px solid red;
display: inline-block;
}
<div class="examples">
<div class="aligner">
<div class="option"></div>
<div class="option"></div>
<div class="option"></div>
</div>
</div>

Should flex item overflow the flex container instead of breaking lines?

I have this layout:
A row flex container with a definite size, e.g. width: 175px
A flex item
With an indefinite flex-basis, e.g. flex-basis: content
Which is inflexible, e.g. flex: none.
Whose max-content size is larger than the available space
Whose min-content size is smaller than the available space
.flex-container {
display: flex;
width: 175px;
border: 3px solid black;
margin-bottom: 10px;
}
.flex-item {
flex: none;
border: 3px solid blue;
margin: 3px;
}
.box {
display: inline-block;
vertical-align: middle;
width: 100px;
height: 100px;
border: 3px solid red;
margin: 3px;
}
<div class="flex-container">
<div class="flex-item">
<div class="box"></div>
<div class="box"></div>
</div>
</div>
As expected, Firefox breaks lines inside the flex item and sets its width to the available space.
However, Chrome doesn't break lines and thus the flex item overflows the flex container:
Who is right? How can I fix this?
This is what happens:
The Line Length Determination algorithm determines that the flex base size of the flex item is its max-content
Size the item into the available space using its used flex
basis in place of its main size, treating a value of
content as max-content. [...] The flex base size is
the item’s resulting main size.
Since there are no min nor max size constraints, the hypothetical main size of the flex item is the same value
The hypothetical main size is the item’s flex base size
clamped according to its min and max main size properties.
The Resolving Flexible Lengths algorithm freezes the inflexible flex item and sets its target main size to its hypothetical main size
Size inflexible items. Freeze, setting its target main size to its
hypothetical main size any item that has a flex factor of zero
Finally, the main size is that value too:
Set each item’s used main size to its target main size.
Therefore, your flex item should be sized as if it had flex-basis: max-content. Chrome, Edge and IE do it correctly.
Instead, Firefox seems to size as if it had flex-basis: fit-content. IMO this is more reasonable, but it's not standard. Bug 876985 should fix this.
Meanwhile, to achieve the standard behavior on Firefox you can use
flex-basis: -moz-max-content;
.flex-container {
display: flex;
width: 175px;
border: 3px solid black;
margin-bottom: 10px;
}
.flex-item {
flex: none;
flex-basis: -moz-max-content;
border: 3px solid blue;
margin: 3px;
}
.box {
display: inline-block;
vertical-align: middle;
width: 100px;
height: 100px;
border: 3px solid red;
margin: 3px;
}
<div class="flex-container">
<div class="flex-item">
<div class="box"></div>
<div class="box"></div>
</div>
</div>
Instead, if you want Firefox's behavior on other browsers, it's not that easy.
Chrome doesn't support fit-content on flex-basis, but it does on width (prefixed)
flex-basis: auto;
width: -webkit-fit-content;
width: fit-content;
.flex-container {
display: flex;
width: 175px;
border: 3px solid black;
margin-bottom: 10px;
}
.flex-item {
flex: none;
width: -webkit-fit-content;
width: fit-content;
border: 3px solid blue;
margin: 3px;
}
.box {
display: inline-block;
vertical-align: middle;
width: 100px;
height: 100px;
border: 3px solid red;
margin: 3px;
}
<div class="flex-container">
<div class="flex-item">
<div class="box"></div>
<div class="box"></div>
</div>
</div>
However, IE/Edge doesn't support fit-content anywhere. But a max constraint should work on all browsers
max-width: 100%;
box-sizing: border-box; /* Include paddings and borders */
Note the constraint won't include margins, so you may need to correct the percentage using calc, e.g. max-width: calc(100% - 6px).
.flex-container {
display: flex;
width: 175px;
border: 3px solid black;
margin-bottom: 10px;
}
.flex-item {
flex: none;
max-width: calc(100% - 6px);
box-sizing: border-box;
border: 3px solid blue;
margin: 3px;
}
.box {
display: inline-block;
vertical-align: middle;
width: 100px;
height: 100px;
border: 3px solid red;
margin: 3px;
}
<div class="flex-container">
<div class="flex-item">
<div class="box"></div>
<div class="box"></div>
</div>
</div>

Position last flex item at the end of container

This question concerns a browser with full css3 support including flexbox.
I have a flex container with some items in it. They are all justified to flex-start but I want the last .end item to be justified to flex-end. Is there a good way to do this without modifying the HTML and without resorting to absolute positioning?
.container {
display: flex;
flex-direction: column;
outline: 1px solid green;
min-height: 400px;
width: 100px;
justify-content: flex-start;
}
p {
height: 50px;
background-color: blue;
margin: 5px;
}
<div class="container">
<p></p>
<p></p>
<p></p>
<p class="end"></p>
</div>
Flexible Box Layout Module - 8.1. Aligning with auto margins
Auto margins on flex items have an effect very similar to auto margins in block flow:
During calculations of flex bases and flexible lengths, auto margins are treated as 0.
Prior to alignment via justify-content and align-self, any positive free space is distributed to auto margins in that dimension.
Therefore you could use margin-top: auto to distribute the space between the other elements and the last element.
This will position the last element at the bottom.
p:last-of-type {
margin-top: auto;
}
.container {
display: flex;
flex-direction: column;
border: 1px solid #000;
min-height: 200px;
width: 100px;
}
p {
height: 30px;
background-color: blue;
margin: 5px;
}
p:last-of-type {
margin-top: auto;
}
<div class="container">
<p></p>
<p></p>
<p></p>
</div>
Likewise, you can also use margin-left: auto or margin-right: auto for the same alignment horizontally.
p:last-of-type {
margin-left: auto;
}
.container {
display: flex;
width: 100%;
border: 1px solid #000;
}
p {
height: 50px;
width: 50px;
background-color: blue;
margin: 5px;
}
p:last-of-type {
margin-left: auto;
}
<div class="container">
<p></p>
<p></p>
<p></p>
<p></p>
</div>
This flexbox principle also works horizontally
During calculations of flex bases and flexible lengths, auto margins
are treated as 0. Prior to alignment via justify-content and
align-self, any positive free space is distributed to auto margins in
that dimension.
Setting an automatic left margin for the Last Item will do the work.
.last-item {
margin-left: auto;
}
Code Example:
.container {
display: flex;
width: 400px;
outline: 1px solid black;
}
p {
height: 50px;
width: 50px;
margin: 5px;
background-color: blue;
}
.last-item {
margin-left: auto;
}
<div class="container">
<p></p>
<p></p>
<p></p>
<p class="last-item"></p>
</div>
Codepen Snippet
This can be very useful for Desktop Footers.
As Envato did here with the company logo.
Codepen Snippet

Flex box container width doesn't grow [duplicate]

This question already has answers here:
When flexbox items wrap in column mode, container does not grow its width
(9 answers)
Closed 6 years ago.
When using flex box in default row direction, the container height grows to contain all the flex items, even if it is absolutely positioned.
#container {
position: absolute;
display: flex;
flex-wrap: wrap;
}
#container > div {
flex: 0 0 200px;
height: 200px;
}
See http://codepen.io/tamlyn/pen/dPjLoN/?editors=110
However if the flex direction is changed to column, the container collapses to the width of a single flex item, even if the items wrap onto the next column.
#container {
position: absolute;
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
#container > div {
flex: 0 0 200px;
width: 200px;
}
See http://codepen.io/tamlyn/pen/rarbeN?editors=110
How can I make the container contain all flex items in column mode?
I've actually found a CSS-only solution to this but it isn't the most perfect thing in the world. Here it is: http://codepen.io/anon/pen/vEPBKK
The trick here is to create a visibility: collapsed container. In flex, visibility: collapsed objects take themselves out of the normal flex flow but retain their dimensions for the purpose of layout. This widens the flex container to the desired width but leaves the flex items unaffected. There are a few caveats, however:
This requires a bit of fiddling. As you can see, the magic <div> is a set width but it uses :nth-child to determine how many boxes are before it. If your actual design breaks at more or less than 3 rows, you'll have to adjust this and you'll most certainly have to adjust the width of the object.
Because of a rendering bug, this does not work in IE. Luckily, IE's incorrect implementation does exactly what you wanted in the first place without any changes so all you have to do is give IE it's own stylesheet with some conditional statements and shoot the div.magic some good old display: none.
HTML
<div id="container">
<div class="fb"></div>
<div class="fb"></div>
<div class="fb"></div>
<div class="fb"></div>
<div class="fb"></div>
<div class="fb"></div>
<div class="fb"></div>
<div class="magic"></div>
</div>
CSS
#container {
position: absolute;
display: flex;
flex-direction: column;
flex-wrap: wrap;
border: 1px solid #f00;
height: 650px;
padding: 1px;
}
#container div.fb {
border: 1px solid #555;
flex: 0 0 200px;
background-color: #ccc;
width: 200px;
margin: 1px;
height: 200px;
}
#container > div.magic {
height: 0;
margin: 0;
padding: 0;
visibility: collapsed;
}
#container > div.magic:nth-child(5),
#container > div.magic:nth-child(6),
#container > div.magic:nth-child(7) {
width: 408px;
}
#container > div.magic:nth-child(8),
#container > div.magic:nth-child(9),
#container > div.magic:nth-child(10) {
width: 612px;
}
#container > div.magic:nth-child(11),
#container > div.magic:nth-child(12),
#container > div.magic:nth-child(13) {
width: 816px;
}
I think this is the CSS you're looking for:
#container {
display: flex;
flex-flow: row wrap;
border: 1px solid #f00;
padding: 1px;
}
#container > * {
border: 1px solid #555;
background-color: #ccc;
height: 200px;
width: 200px;
margin: 1px;
}
The "Container" will always the the width of it's container, in this case the page, but now the boxes will adjust within it properly.
Let me know if I misunderstood your question.
Update
I've been playing with what you're asking for for several days now, and it really seems like it's not possible to do what you're asking... at least not in the direction that you're asking.
The container wants to be the maximum width possible. Unless you force the container to be the exact width, at which point it wont be the full width, but it wont flex with the flexing content either.
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
justify-content: space-around;
border: 1px solid #f00;
}
.flex-item {
background-color: #ccc;
padding: 5px;
width: 200px;
height: 150px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
border: 1px solid #555;
}
<div id="container" class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
The first try I do not understand what you mean
as reference material you can see this tutorial
https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Resources