column display using the flexbox - html

I am using the code where i have a bunch of divs, i want to show 4 columns per row and this is what i am using
.questions {
margin-bottom: 15px;
background: #e1e1e1;
display: flex;
padding: 30px;
gap: 30px;
align-items: top;
justify-content: left;
width: 100%;
flex-wrap: wrap;
.questions_divs {
display: flex;
flex-direction: column;
padding-left: 15px;
flex: 1 0 21%; /* explanation below */
}
here is the html
<div class="questions">
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
<div class="questions_div"></div>
</div>
now when the lements are 3 or 3 or 6 or 9, i want them to come to next line, but they are coming in center and too much gap, how can i make sure they are left aligned with not too much gap

You mean something like this??
.questions {
margin-bottom: 15px;
background: #e1e1e1;
display: flex;
padding: 30px;
grid-gap: 30px;
align-items: top;
justify-content: left;
width: 100%;
flex-wrap: wrap;
}
.questions_div {
padding-left: 15px;
height:100px;
width:100px;
background-color:red;
flex: 1 0 1 21%;
}
<div class="questions">
<div class="questions_div">A</div>
<div class="questions_div">B</div>
<div class="questions_div">C</div>
<div class="questions_div">D</div>
<div class="questions_div">E</div>
<div class="questions_div">F</div>
<div class="questions_div">G</div>
<div class="questions_div">H</div>
<div class="questions_div">I</div>
<div class="questions_div">J</div>
</div>

Issues i found are listed below:
Close the bracket of .questions class in css.
.questions_divs - spelling mistake. It's .questions_div
flex: 1 0 21%; /* meaning - flex-grow flex-shrink flex-basis */
change flex: 1 0 21%; to flex: 0 0 25%; /for 4 columns in a row/
remove gap property. I am not sure but I think gap property is mostly used with grid css.
no need to add flex and flex direction to .questions_div. Add only if you want to handle the child elements inside .questions_div.
CSS-
* {
box-sizing: border-box;
}
.questions {
margin-bottom: 15px;
background: #e1e1e1;
display: flex;
padding: 30px;
/* gap: 30px; */
align-items: top;
justify-content: left;
width: 100%;
flex-wrap: wrap;
}
.questions_div {
/*display: flex;*/ /*no need to add this line*/
/*flex-direction: column;*/ /*no need to add this line*/
padding-left: 15px;
flex: 0 0 25%; /* flex-grow flex-shrink flex-basis */
}
HTML
<div class="questions">
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
<div class="questions_div">some text</div>
</div>

Related

Creating a layout with Flexbox

hey I'm new in Flexbox and I'm trying to get it as best as I can. However i faces a problem with some heights and orders, maybe some here could help out.
Note: Don't suggest using Grid/tables please.
this is what I have right now:
this is what I want to get:
html:
<div class="movie-container">
<div class="upper-container">
<div class="image">Image</div>
<div class="title">Title</div>
<div class="more">More</div>
</div>
<div class="lower-container">
<div class="runtime">Runtime</div>
<div class="description">Description</div>
<div class="director">Director</div>
</div>
</div>
css:
.movie-container{
display:flex;
flex-flow: column wrap;
}
.upper-container {
display: flex;
width:80%;
margin:0 auto;
flex-flow: raw wrap;
}
.upper-container div {
border: 1px solid black;
padding: 10px;
}
.lower-container {
display: flex;
width:80%;
margin:0 auto;
flex-flow: column wrap;
}
.lower-container div {
border: 1px solid black;
padding: 10px;
}
.image {
flex: 1;
}
.title {
flex: 3;
}
.more {
flex: 0.1;
}
.runtime{
}
.description{
}
.director{
}
Maybe other stuff need to be added beside flexbox I'm not sure, that's why I ask here. Any solution will be helpful!
If you change your HTML structure slightly you can accomplish this fairly easily:
<div class="movie-container">
<div class="upper-container">
<div class="image">Image</div>
<div class="side-container">
<div class="title">Title</div>
<div class="more">More</div>
<div class="runtime">Runtime</div>
<div class="description">Description</div>
</div>
</div>
<div class="lower-container">
<div class="director">Director</div>
</div>
</div>
JSFiddle
Flex isn't very good at stretching across multiple rows / columns like tables or Grid is, while you state you don't want that solution it is typically a better option in cases like this.
I find it easiest to work with flexbox on a row-by-row basis instead of using wrapping (although you can certainly do that too).
As a starting point, I think this snippet is what you're going for?
div {
flex: 1 1 auto;
}
.box {
border: 1px solid black;
}
.flex {
display: flex;
}
.image {
width: 120px;
flex: 0 0 auto;
}
.more {
flex: 0 0 auto;
}
<div class="flex upper">
<div class="box flex image">Image</div>
<div class="upper-detail">
<div class="flex title-container">
<div class="box title">Title</div>
<div class="box more">More</div>
</div>
<div class="box runetime">Runtime</div>
<div class="box director">Director</div>
</div>
</div>
<div class="box description">Description</div>
<div class="box other">Other stuff...</div>
Hope this helps.
.upper-container{
display: flex;
height: 200px;
}
.upper-left{
background: #ddd;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.upper-right{
flex: 3;
display: flex;
flex-direction: column;
height: 100%;
}
.title-more, .runtime, .director{
flex: 1;
border: 1px solid #222;
display: flex;
align-items: center;
}
.lower-container{
border: 1px solid #222;
padding: 10px;
}
.title-more{
justify-content: space-between;
}
.more-button{
height: 30px;
width: 100px;
border: 1px solid #333;
margin-right: 5px;
display: flex;
align-items: center;
justify-content: center;
}
<div class="movie-container">
<div class="upper-container">
<div class="upper-left">
Image
</div>
<div class="upper-right">
<div class="title-more">
<div class="title-container">
Title
</div>
<div class="more-button">
More
</div>
</div>
<div class="runtime">Runtime</div>
<div class="director">Director</div>
</div>
</div>
<div class="lower-container">
Description
</div>
</div>
The key is to add some divs and remove some others:
.movie-container *{padding:.5em;}
.upper-container {
display: flex;
padding:0;
}
.image {
border: 1px solid;
flex: 1 1 25%;
}
.tmrd{flex: 1 1 75%;padding:0}
.title-more {
display: flex;
padding:0;
}
.title{flex: 1 1 75%;border: 1px solid;}
.more{flex: 1 1 25%;border: 1px solid;}
.runtime,.description,.director{border: 1px solid;}
<div class="movie-container">
<div class="upper-container">
<div class="image">Image</div>
<div class="tmrd">
<div class="title-more">
<div class="title">Title</div>
<div class="more">More</div>
</div>
<div class="runtime">Runtime</div>
<div class="description">Description</div>
</div>
</div>
<div class="director">Director</div>
</div>

How to adapt div's width to content with flexbox

I want adapt the .flexrow div's width to content but i can't set it with flex.
HTML
<div class="fullwidth">
<div class="sidebar">
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
</div>
<div class="center">
<div class="flexrow">
<div class="card">
<p>card</p>
</div>
</div>
</div>
</div>
CSS
.center {
display: flex;
justify-content: center;
}
.flexrow {
display: inline-flex;
flex-direction: row;
flex-wrap: wrap;
}
.flexrow .card {
width: 300px;
height: 60px;
background-color: red;
margin: 10px;
padding: 10px;
text-align: center;
}
I have created a snippet here
This is an example of what i want:
Any suggestion?
The main problem here is that when an item wrap, whether one use Flexbox or not, its container won't adjust its width to the new content width.
With the existing markup, here is a simple fix in 2 steps to achieve that:
Add justify-content: center; to your .flexrow rule
For every possible column you need one less ghost element to push elements on the last row all the way to the left. The added elements together with new .flexrow .card:empty rule will do the magic.
.flexrow .card:empty {
height: 0;
margin: 0 10px;
padding: 0 10px;
}
Updated codepen
Stack snippet
.fullwidth {
background-color: grey;
display: flex;
}
.sidebar {
flex: 0 0 280px;
margin: 10px;
padding: 10px;
background-color: black;
color: white;
}
.flexrow {
display: flex;
flex-wrap: wrap;
align-content: center;
justify-content: center;
}
.flexrow .card {
width: 300px;
height: 60px;
background-color: red;
margin: 10px;
padding: 10px;
text-align: center;
}
.flexrow .card:empty {
height: 0;
margin: 0 10px;
padding: 0 10px;
}
<div class="fullwidth">
<div class="sidebar">
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
</div>
<div class="center">
<div class="flexrow">
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<!-- Ghost elements, if max columns is 4 one need 3 -->
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
</div>
</div>
Try this code-example
.flexrow .card {
height: 60px;
background-color: red;
margin: 10px;
padding: 10px;
text-align: center;
}
I removed the width, so that flexrow can adapt to the content.
Is this what you wanted? If not please specify (maybe a picture?)
UPDATE
Try this one:
.flexrow {
width: 90%;
display: inline-flex;
flex-direction: row;
flex-wrap: wrap;
-webkit-align-content: center;
align-content: center;
-webkit-justify-content: space-between;
justify-content: space-between;
margin: 0 auto;
}
.flexrow:after {
content: "";
width: 300px;
margin: 10px;
padding: 10px;
text-align: center;
}
Hope that what you're looking for :)
I guess what you want is that if you want the sidebar and the content to be side by side you need to use flex on the fullwidth div, check the code below:
.sidebar {
background: black;
color: white;
}
.fullwidth {
display: flex;
}
.center {
display: flex;
justify-content: center;
align-items:center;
width:100%;
}
.flexrow {
display: inline-flex;
flex-direction: row;
flex-wrap: wrap;
width:100%;
}
.flexrow .card {
width: calc(33.33% - 20px);
box-sizing:border-box;
height: 60px;
background-color: red;
margin: 10px;
padding: 10px;
text-align: center;
}
<div class="fullwidth">
<div class="sidebar">
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
<p>sidebar</p>
</div>
<div class="center">
<div class="flexrow">
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
<div class="card">
<p>card</p>
</div>
</div>
</div>
</div>

Stretch height with flexbox align-items center

I have a div with display: flex; flex-direction: row;. The children of this div take the full height unless I specify align-items: center. Code below -
.row {
display: flex;
flex-direction: row;
width: 100%;
height: 100px;
background: beige;
border: 1px solid red;
margin: 10px 0;
}
.row2 {
align-items: center;
}
.row-item {
border: 1px solid green;
}
.item1,
.item3 {
width: 100px;
}
.item2 {
flex: 1;
}
<div class="row row1">
<div class="row-item item1">1</div>
<div class="row-item item2">
<div> 2.1 </div>
<div> 2.2 </div>
</div>
<div class="row-item item3">3</div>
</div>
<div class="row row2">
<div class="row-item item1">1</div>
<div class="row-item item2">
<div> 2.1 </div>
<div> 2.2 </div>
</div>
<div class="row-item item3">3</div>
</div>
JSFiddle
What I want to achieve is that 2.1 and 2.2 should take 50px (50%) height and should have its content middle aligned vertically. They should also stretch the full available space horizontally (like width: auto or 100%). Then if 2.1 is not present, 2.2 should take 100px height and should be vertically aligned to middle.
You need to make row-items a flex box and apply align-items: center; to them
This is the code that you should add
.row1 .row-item {
display: flex;
align-items: center;
}
See result below :
.row {
display: flex;
flex-direction: row;
width: 100%;
height: 100px;
background: beige;
border: 1px solid red;
margin: 10px 0;
}
.row2 {
align-items: center;
}
.row-item {
border: 1px solid green;
}
.row1 .row-item {
display: flex;
flex-wrap: wrap;
}
.row1 .row-item div {
width: 100%;
border: 1px solid blue;
display: flex;
align-items: center;
}
.item1,
.item3 {
width: 100px;
}
.item2 {
flex: 1;
}
<div class="row row1">
<div class="row-item item1">1</div>
<div class="row-item item2">
<div> 2.1 </div>
<div> 2.2 </div>
</div>
<div class="row-item item3">3</div>
</div>
<div class="row row2">
<div class="row-item item1">1</div>
<div class="row-item item2">
<div> 2.1 </div>
<div> 2.2 </div>
</div>
<div class="row-item item3">3</div>
</div>
You can use line-height to achieve vertical alignment. In this case since your.row1 has a height of 100px add the following to that CSS: line-height: 100px; See the updated jsfiddle and for only .row1 see this jsfiddle

CSS Flexbox - aligning cells column correctly

Traditionally, I would stick with html table, but in my app I have to add some interaction in this "table" (I will be implementing collapsible window between rows with event listener, etc).
So I decided to use flexbox and emulate like a html table.
However I am having trouble for each row to align correctly column wise.
.container {
display: flex;
flex-wrap: wrap;
border: black 1px solid;
width: 100%;
}
.row {
display: flex;
height: 40px;
width: 100%;
align-items: center;
}
.cell {
padding-right: 25px;
padding-left: 20px;
align-items: center;
font-size: 20px;
border-right: 1px solid salmon
}
<div class="container">
<div class="row">
<div class="cell">Descrption</div>
<div class="cell">Amount per Month</div>
<div class="cell">Amount per year</div>
</div>
<div class="row">
<div class="cell">Income</div>
<div class="cell">$20,000</div>
<div class="cell">$45,000</div>
</div>
</div>
As you can see, the right-border of each cells does not align correctly.
Is it possible using flex-box to achieve this? Or is my implementation is wrong?
Note: I cannot use any JavaScript nor jQuery for this one.
Since you are using display flex. you can use flex-basis property
See snippet below
.container {
display: flex;
flex-wrap: wrap;
border: black 1px solid;
width: 100%;
}
.row {
display: flex;
height: 40px;
width: 100%;
align-items: center;
}
.row .cell{
flex:0 0 30%;
}
.cell {
padding-right: 25px;
padding-left: 20px;
align-items: center;
font-size: 20px;
border-right: 1px solid salmon
}
<div class="color-div">
</div><div class="container">
<div class="row">
<div class="cell">Descrption</div>
<div class="cell">Amount per Month</div>
<div class="cell">Amount per year</div>
</div>
<div class="row">
<div class="cell">Income</div>
<div class="cell">$20,000</div>
<div class="cell">$45,000</div>
</div>
</div>
It is quite simple. Just give equal width to cell. e.g.:
.container {
display: flex;
flex-wrap: wrap;
border: black 1px solid;
width: 100%;
}
.row {
display: flex;
height: 40px;
width: 100%;
align-items: center;
}
.cell {
padding-right: 25px;
padding-left: 20px;
align-items: center;
font-size: 20px;
border-right: 1px solid salmon;
width: 33%;
}
<div class="container">
<div class="row">
<div class="cell">Descrption</div>
<div class="cell">Amount per Month</div>
<div class="cell">Amount per year</div>
</div>
<div class="row">
<div class="cell">Income</div>
<div class="cell">$20,000</div>
<div class="cell">$45,000</div>
</div>
</div>

flexbox grid under centered flex item

I would like an intro section on the left side of a .container and a side bar on the right.
On the left side underneath the .intro section I want there to be four divs equally spaced like a grid.
I'm having problems with getting the "grid set up". I think part of the problem is that the parent has some flexbox attribute effecting the children.
Requirement : The intro section should be centered in the .left-side and the "grid" should not be centered the boxes should take up as much space as necessary to fit 2 on a row with margins in between. The .intro should be 80 percent of the width of the leftside.
I don't want to do any major changes to the structure this is just a small sample of how my project is set up.
.container{
width: 80%;
margin: 0 auto;
display: flex;
}
.left-side{
flex:8;
display: flex;
justify-content:center;
flex-wrap: wrap;
}
.side-bar{
flex: 2;
height: 100vh;
background: powderblue;
}
.intro{
flex:3;
width:80%;
height: 300px;
background: skyblue;
}
.box{
background: red;
width: 45%;
height: 100px;
flex:4;
border:1px solid orange;
}
<div class="container">
<div class="left-side">
<div class="intro">
intro
</div>
<div class="recent">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
</div>
</div>
<div class="side-bar">
sidebar
</div>
Flex items can also be flex containers. This enables you to nest multiple containers, with flex-direction: row or column, in a larger container.
For your layout, you can build a column consisting of two flex items. The first item (.intro) has 80% width and can be centered horizontally. The second item (.recent) can be a flex container with four items arranged in a 2x2 grid.
.container {
width: 80%;
margin: 0 auto;
display: flex;
justify-content: center;
height: 100vh;
}
.left-side {
flex: 4;
display: flex;
flex-direction: column;
}
.side-bar {
flex: 1;
background: powderblue;
}
.intro {
flex: 3;
height: 300px;
width: 80%;
margin: 0 auto;
background: skyblue;
}
.recent {
display: flex;
flex-wrap: wrap;
background-image: url("http://i.imgur.com/60PVLis.png");
background-size: contain;
}
.box {
margin: 5px;
flex-basis: calc(50% - 10px);
height: 100px;
box-sizing: border-box;
background: red;
}
body { margin: 0; }
<div class="container">
<div class="left-side">
<div class="intro">intro</div>
<div class="recent">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
</div>
</div>
<div class="side-bar">
sidebar
</div>
</div>