How the flex box item use the full width of its parent - html

.container {
width: 400px;
border: 2px solid red;
display: flex;
flex-flow: row wrap;
}
.item {
padding: 20px;
border: 1px solid blue;
width: 70px;
}
<div class="container">
<div class=item>Box 1</div>
<div class=item>Box 2</div>
<div class=item>Box 3</div>
<div class=item>Box 4</div>
<div class=item>Box 5</div>
</div>
My question, how can "Box 1", "Box 2", "Box 3" use the full width of the "container" class? and "Box 4" and "Box 5" will line up from below to the above box "Box 1" and "Box 2".

You have several ways to go about it; here are two ways:
Use flex-grow. If you add flex-grow: 1 to the item selector then the boxes on each row will take up the full width of the container. Note: With this solution you may want to make sure you have the same number of boxes per row, if you want these boxes to appear as a uniform grid. Otherwise the line with only one or two boxes will be stretched to fill the width of the container. So keep that in mind.
.container {
width: 400px;
border: 2px solid red;
display: flex;
flex-flow: row wrap;
}
.item {
padding: 20px;
border: 1px solid blue;
width: 70px;
flex-grow: 1;
}
Second option: Add margin: 0 auto; to the item selector, and they will fill the width by centering.
.container {
width: 400px;
border: 2px solid red;
display: flex;
flex-flow: row wrap;
}
.item {
padding: 20px;
border: 1px solid blue;
width: 70px;
margin: 0 auto;
}

This was actually kind of a brainteaser until I realized you need CSS grid instead of Flexbox :). There doesn't seem to exist a solution with Flexbox without adding "ghost divs", which isn't really a good option.
.container {
width: 400px;
border: 2px solid red;
display: grid;
grid-template-columns: 110px 110px 110px;
justify-content: space-between;
}
.item {
padding: 20px;
border: 1px solid blue;
}
<div class="container">
<div class=item>Box 1</div>
<div class=item>Box 2</div>
<div class=item>Box 3</div>
<div class=item>Box 4</div>
<div class=item>Box 5</div>
</div>

Related

HTML & CSS, how to center 3 divs inside a div?

I am trying to position 3 div in the center of another div but I'm having issues with the positioning. I tried using verticle-align, and negative margins but nothing seems to be working.
.float-container {
border: 3px solid red;
padding: 250px;
position: relative;
background-color: lightblue;
}
.float-child {
width: 150px;
height: 150px;
float: left;
padding: 10px;
border: 2px solid red;
margin: 30px;
vertical-align: middle;
}
<div class="float-container">
<div class="float-child">
<div>Float Column 1</div>
</div>
<div class="float-child">
<div>Float Column 2</div>
</div>
<div class="float-child">
<div>Float Column 3</div>
</div>
</div>
example for my comment
vertical alignment is not avalaible for floatting elements. Nowdays, for this kind of layout, grid or flex are efficient, flexible and easy to put in action. This is not a float job ;)
.float-container {
border: 3px solid red;
display:flex;
align-items:center;
justify-content:center;
gap:30px;
min-height:500px;
position: relative;
background-color: lightblue;
}
.float-child {
width: 150px;
height: 150px;
padding: 10px;
border: 2px solid red;
}
<div class="float-container">
<div class="float-child">
<div>Float Column 1</div>
</div>
<div class="float-child">
<div>Float Column 2</div>
</div>
<div class="float-child">
<div>Float Column 3</div>
</div>
</div>
children only need now to be sized . alignement gap in between them is set from the flex parent. A min-height is given (500px inspirated from your padding 250px)
Remove the float: left; and in its place add display: flex;, justify-content: center;, align-items: center;, flex-direction: row;. For requirements like these, flex and grid are usually much simpler to implement.
.float-container {
display: flex;
padding: 250px;
position: relative;
align-items: center;
border: 3px solid red;
justify-content: center;
background-color: lightblue;
}
.float-child {
width: 150px;
height: 150px;
padding: 10px;
border: 2px solid red;
margin: 0 10px;
vertical-align: middle;
}
<div class="float-container">
<div class="float-child">
<div>Float Column 1</div>
</div>
<div class="float-child">
<div>Float Column 2</div>
</div>
<div class="float-child">
<div>Float Column 3</div>
</div>
</div>
An easy and "modern" way is to use Flexbox if there are no limitations being set as part of a requirement to use float. As an example:
.container {
border: 3px solid red;
padding: 20px;
background-color: lightblue;
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
}
.child {
width: 150px;
height: 150px;
padding: 10px;
border: 2px solid red;
}
<div class="container">
<div class="child">
Float Column 1
</div>
<div class="child">
Float Column 2
</div>
<div class="child">
Float Column 3
</div>
</div>

Make a responsive layout using flex and css grid

I'm trying to do a responsive layout, I'm not good with css so I need help.
Here is the code:
.container {
outline: 1px solid black;
max-width: 490px;
margin: 0 auto;
}
.columns {
outline: 1px solid black;
display: inline-flex;
flex-wrap: wrap;
}
.map {
background-color: cyan;
width: 150px;
min-width: 150px;
height: 150px;
min-height: 150px;
margin-right: 20px;
}
.content {
outline: 1px solid black;
background-color: lightgray;
max-width: 320px;
}
.cards {
outline: 1px solid black;
display: inline-flex;
flex-wrap: wrap;
}
.card {
background-color: pink;
outline: 1px solid black;
width: 150px;
height: 70px;
display: inline-block;
}
.card.left {
margin-right: 20px;
}
.texts {
outline: 1px solid black;
display: inline-flex;
flex-wrap: wrap;
}
.text {
background-color: gold;
outline: 1px solid black;
width: 150px;
height: 200px;
display: inline-block;
}
.text.left {
margin-right: 20px;
}
<div class="container">
<div class="columns">
<div class="map"></div>
<div class="content">
<div class="cards">
<div class="card left">card #1</div>
<div class="card">card #2</div>
<div class="card left">card #3</div>
<div class="card">card #4</div>
</div>
<div class="texts">
<div class="text left">text #1</div>
<div class="text">text #2</div>
</div>
</div>
</div>
</div>
Basically there are two rows.
The first one contains an element with fixed width and height, and on the right four cards.
The second rows contains only two elements.
Each element of this layout has width 150px.
The code shown above works partially.
The first row is ok, the second one no because the gold elements should stay aligned with the cards so when cards are on the right of el1, contents should below the cards.
It is like if there were to be a hidden element (on the left side of contents) that has the same size as el1.
Also I would like everything to always be centered because now it is only if the window width is > 490px.
This is what I'd like to have:
How can I do that?

Flexbox - last element placement "floating" right

I have to write some grid fallback for IE11.
I want Item 4 to be placed on the lower right so Item 1 can stretch all the way down to the bottom?
I think this is impossible with flexbox, right? : https://jsfiddle.net/b7w0pc4q/4/
<div class="flexContainer">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
</div>
The SCSS:
.flexContainer {
display: flex;
background-color: #223;
min-height: 100vh;
flex-wrap: wrap;
.item {
border: solid 1px red;
padding: 20px;
&:nth-child(1) {
width: 50%;
align-self: stretch;
background-color: #a69eff;
}
&:nth-child(2), &:nth-child(3) {
width: 25%;
background-color: #ffb76f;
align-self: flex-start;
}
&:nth-child(4) {
background-color: #ffee80;
width: 51%;
margin-left: auto;
}
}
}
With a classic float layout it's fairly easy: https://codepen.io/Sepp/pen/MXBrzy?editors=1100 But I don't want to give up yet. any ideas?
So I conclude: It is not possible with flexbox without altering the html markup.
Thanks guys.

Control height of flex element within flex-grid without affecting surrounding elements

I am using a flex grid to lay out information. I want to highlight one of the cells within the grid so that it stands out to users by adjusting the height of the respective cell. However, my attempts have not gotten far as adjusting the properties of once cell will thereby affect the surrounding cells.
In my fiddle below, I have a class .highlighted within .flexbox-2 that I would like to change. Basically, the row 1 of the second column would have a taller height than the first and third column, but all the borders will still be aligned. I was thinking to apply position: absolute and change its CSS there, but this does not prove fruitful. I'm wondering if there are other routes I can take.
Check this jsfiddle
Code:
* {
box-sizing: border-box;
}
body {
font-family: helvetica, serif;
}
.container {
display: -webkit-flex;
-webkit-flex-direction: row;
}
.flex {
display: flex;
flex-direction: column;
}
.flex-row {
flex: 1;
border: 1px solid;
}
.flexbox-1 {
-webkit-flex: 1;
border: solid 3px red;
}
.flexbox-2 {
-webkit-flex: 1;
border: solid 3px green;
height: 200px;
margin-left: 10px;
position: relative;
}
.highlighted {
position: absolute;
border: 1px solid yellow;
padding-top: 20px;
}
.flexbox-3 {
-webkit-flex: 1;
border: solid 3px blue;
height: 200px;
margin-left: 10px;
}
<div class="container">
<div class="flex flexbox-1">
<div class="flex-row">row 1</div>
<div class="flex-row">row 2</div>
<div class="flex-row">row 3</div>
</div>
<div class="flex flexbox-2">
<div class="flex-row highlighted">row 1</div>
<div class="flex-row">row 2</div>
<div class="flex-row">row 3</div>
</div>
<div class="flex flexbox-3">
<div class="flex-row">row 1</div>
<div class="flex-row">row 2</div>
<div class="flex-row">row 3</div>
</div>
</div>
If you want that first row to stick out above the other two columns, you could use a negative margin-top:
.highlighted {
border: 1px solid yellow;
margin-top: -10px;
padding-bottom: 10px;
}
Working Example

Center div on wrapping (when it doesn't fit on the line)

I am trying to create this layout using only CSS:
When title fits:
When title doesn't fit:
The btn on the right should be centered if it wraps.
I tried this:
.container {
width: 100%;
border: 1px solid grey;
padding: 5px;
}
.block {
padding: 5px;
border: 1px solid orange;
float: left;
}
.right-block {
float: right;
}
<div class="container">
<div class="block">Logo</div>
<div class="block">Title that is too long</div>
<div class="block right-block">right-btn</div>
<div style="clear: both"></div>
</div>
But obviously, the btn is still on the right after it wraps. Any idea how to center it when it wraps ? And I'd like to avoid javascript.
Fiddle here: http://jsfiddle.net/b7rvhwqg/
Pure CSS solution using a flexbox layout:
Updated Example Here
The trick is to add justify-content: center/flex-wrap: wrap to the parent .container element for horizontal centering. Then adjust the first element's margin-right value to auto in order to prevent the last element from being centered when it's on the same line.
(You may need to resize the browser to see how it adjusts).
.container {
width: 100%;
border: 1px solid grey;
padding: 5px;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.logo-text {
display: flex;
margin-right: auto;
}
.block {
padding: 5px;
border: 1px solid orange;
}
.center-block {
white-space: nowrap;
margin-right: auto;
}
<div class="container">
<div class="logo-text">
<div class="block logo">Logo</div>
<div class="block text">This title is short.</div>
</div>
<div class="block right-block">right-btn</div>
</div>
<div class="container">
<div class="logo-text">
<div class="block logo">Logo</div>
<div class="block text">This title is slightly longer than the other one. This title is longer than the other one...</div>
</div>
<div class="block right-block">right-btn</div>
</div>
There is an issue to achieve this via Pure CSS. The div is already having a float and you want to have a "long title" to accommodate that float and at the same time, you want the other right float to jump and become center. This is currently not possible. I believe, you need to consider media queries, but again, that will be a dependent solution, but your title looks like independent of expanding/contracting.
is it ok for you if the title will just fit depending on what width u want?.. for example:
{Logo}Title is toooooooooooooooooooooooooooooooooolong {btn}
it will become like this:
{Logo}Title is tooo... {btn}
it will be cut, then only ". . ." will continue
Flexbox is the most suitable for this task:
<div class="container">
<div class="block logo">Logo</div>
<div class="block title">Title that is too long Title that is too long</div>
<div class="block right-block">right-btn</div>
<div style="clear: both"></div>
</div>
.container {
display: flex;
flex-wrap: wrap;
width: 100%
border: 1px solid grey;
}
.block.logo {
flex-grow: 1;
border: 1px solid orange;
}
.block.title{
flex-grow: 10;
border: 1px solid orange;
}
.right-block {
flex-grow: 1;
border: 1px solid orange;
text-align: center;
}
http://jsfiddle.net/gmrash/7b8w982t/
.container {
width: 100%;
border: 1px solid grey;
padding: 5px;
}
.block {
padding: 5px;
border: 1px solid orange;
float: left;
}
.ellipsis{
text-overflow: ellipsis;
/* Required for text-overflow to do anything */
white-space: nowrap;
overflow: hidden; width: 75%;
}
.right-block {
float: right;
}
<div class="container">
<div class="block">Logo</div>
<div class="block ellipsis">Title that is too long Title that is too long Title that is too long that is too long Title that is too long</div>
<div class="block right-block">right-btn</div>
<div style="clear: both"></div>
</div>
jsFiddle