How to set right spacing between inline-block elements - html

My example:
Its possilble to set same spacing between div inline elements. Because auto width is not working.
This is what i got so far:
HTML
<div id="frame">
<div class="block">1</div>
<div class="block">2</div>
<div class="block">3</div>
<div class="block">4</div>
</div>
</div>
CSS
#frame div {
background-color: brown;
padding-left: 20%;
padding-right: 20%;
width: auto;
margin: 5px;
display: inline-block;
}

Width of frame is full screen and width of block have to fit inside this frame, its not that important.
In that case you can avoid the not yet that well supported flex and use percentages instead:
Give 20% width to each of the .block divs
Give 4% margin-right to each of the .block divs
Give either the first .block an additional 4% margin-left or set a padding-left of 4% on #frame
Of course, you can change these values as long as they add up to a maximum of 100% of #frame.
#frame {
width: 100%;
box-sizing: border-box;
margin: 0;
padding: 0 0 0 4%;
}
#frame div {
display: inline-block;
background-color: brown;
width: 20%;
margin: 1em 4% 1em 0;
}
<div id="frame">
<div class="block">1</div>
<div class="block">2</div>
<div class="block">3</div>
<div class="block">4</div>
</div>
</div>

Flexbox may be your best approach, but be aware that older browsers do not support it.
#frame div {
background-color: brown;
width: 20%;
text-align:center;
}
#frame {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -moz-flex;
display: -webkit-flex;
display: flex;
-webkit-justify-content: space-around;
justify-content: space-around;
}
https://jsfiddle.net/02mp1yxv/

Flex makes this easy :
#frame div {
background-color: brown;
margin: 5px;
flex: 1;
padding:1em;
color:silver
}
#frame {
display: flex;
}
<div id="frame">
<div class="block">1</div>
<div class="block">2</div>
<div class="block">3</div>
<div class="block">4</div>
</div>
For a single row table does the job too for older browsers :
#frame div {
background-color: brown;
display:table-cell;
padding:1em;
color:silver
}
#frame {
display: table;
width:100%;
border-spacing: 10px 0;;
}
<div id="frame">
<div class="block">1</div>
<div class="block">2</div>
<div class="block">3</div>
<div class="block">4</div>
</div>
or grid for latest browsers (where columns number is known:
#frame div {
background-color: brown;
padding: 1em;
color: silver
}
#frame {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-column-gap: 10px;
}
<div id="frame">
<div class="block">1</div>
<div class="block">2</div>
<div class="block">3</div>
<div class="block">4</div>
</div>

Related

column display using the flexbox

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>

Have table row scrollable

Currently facing some problems with the layout I want to accomplish.
How can I divide my page in such a way that the header row gets the height it needs ( for it's content ) and all the rest is given to the images row? A bit like auto, 100% if that is possible? For testing I've given it a fixed height.
The text in the header row should be bottom alligned vertically but somehow this is not working?
And lastly, how can I get the images row scrollable in such a way that the header row stays fixed? So not sticky for the header, because then the header will also partially scroll. The complete content of the header should stay fixed and only the images content should scroll on Y value. ( so no horizontal scroll )
body {
font-size: 18px;
max-width: 820px;
margin: 0 auto;
}
.table {
display:table;
width:100%;
}
.row {
display:table-row;
}
.row.header {
height:80px;
vertical-align: bottom;
}
.row.images {
overflow: scroll;
}
.column {
display: table-cell;
width: 50%
}
.column.left {
padding-left: 10px;
}
.column.right {
text-align: right;
padding-right: 10px;
}
<body>
<div class="table">
<div class="row header">
<div class="column left">Portfolio</div>
<div class="column right">Artist</div>
</div>
<div class="row images">
<div class="grid">
<div class='grid__col-sizer'></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/orange-tree.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/submerged.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/look-out.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/one-world-trade.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/drizzle.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/cat-nose.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/contrail.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/golden-hour.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/flight-formation.jpg"></div>
</div>
</div>
</div>
</body>
Solved my own problems, using CSS grid. The complete codepen is available here: https://codepen.io/depechie/pen/jOBGrRP
body {
font-family: "Helvetica Neue", Arial, sans-serif;
font-size: 0.8rem;
margin: 0;
}
.page {
display: grid;
grid-template-rows: auto;
grid-template-columns: 1fr;
height: 100vh;
}
.panel {
display: grid;
/* grid-template-rows: var(--bar-height) 1fr; */
grid-template-rows: auto 1fr;
height: 100vh;
}
.panel-body {
overflow-y: auto;
display: grid;
justify-content: center;
}
.tabs {
display: grid;
grid-template-columns: repeat(2, 1fr);
height: 100%;
padding: 20px;
}
.tab-item.left {
text-align: left;
}
.tab-item.right {
text-align: right;
}
You can Use height: fit-content; To make the height of the div fit the height of the elements it has
code:
body {
font-size: 18px;
max-width: 820px;
margin: 0 auto;
}
.table {
display:table;
width:100%;
}
.row {
display:table-row;
}
.row.header {
/* here you can replace fixed hight with : fit-height */
height:fit-height;
display: flex;
vertical-align: bottom;
}
.row.images {
overflow: scroll;
}
.column {
display: table-cell;
width: 50%
}
.column.left {
padding-left: 10px;
}
.column.right {
text-align: right;
padding-right: 10px;
}
<body>
<div class="table">
<div class="row header">
<div class="column left">Portfolio</div>
<div class="column right">Artist</div>
</div>
<div class="row images">
<div class="grid">
<div class='grid__col-sizer'></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/orange-tree.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/submerged.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/look-out.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/one-world-trade.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/drizzle.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/cat-nose.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/contrail.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/golden-hour.jpg"></div>
<div class="grid__item"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/flight-formation.jpg"></div>
</div>
</div>
</div>
</body>

How to make Flex Grid width relative to the biggest child's width?

I have something like this :
.wrapper {
display: flex;
width: 300px;
}
.content {
flex: auto;
}
.row {
display: flex;
flex-flow: row wrap;
}
.col {
width: 25%;
padding: 5px;
border: 1px solid black;
box-sizing: border-box;
}
<div class='wrapper'>
<div class='content'>Content</div>
<div class='row'>
<div class='col'>aa</div>
<div class='col'>aaaa</div>
<div class='col'>aaaaaa</div>
<div class='col'>aaaaaaaa</div>
</div>
</div>
I can't understand how :
The width of the .row element is calculated
The width of the .col elements are calculated
Why some content overflows the box and some don't
What I want is a grid system that gets its size relative to the largest child, so that each content fits in its .col cell.
I saw that I could do that with display: grid and grid-template-columns: 1fr 1fr 1fr 1fr, but then how do you make it responsive and how well is it supported ?
To answer your 3 first questions, you simly need to remove the width:25% to have the following:
.wrapper {
display: flex;
width: 300px;
}
.content {
flex: auto;
}
.row {
display: flex;
flex-flow: row wrap;
}
.col {
padding: 5px;
border: 1px solid black;
box-sizing: border-box;
}
<div class='wrapper'>
<div class='content'>Content</div>
<div class='row'>
<div class='col'>aa</div>
<div class='col'>aaaa</div>
<div class='col'>aaaaaa</div>
<div class='col'>aaaaaaaa</div>
</div>
</div>
We didn't define any width, so each col will fit its content and the row will have the width equal to the sum of all the col.
Now since we have the width of the row defined based on the content, it won't change and it will get used as a reference for the percentage. Using 25% for the col means that each one will get 25% of the previously defined width and we will logically have some overflow since the content inside each col isn't the same.
.wrapper {
display: flex;
width: 300px;
}
.content {
flex: auto;
}
.row {
display: flex;
flex-flow: row wrap;
}
.col {
padding: 5px;
border: 1px solid black;
box-sizing: border-box;
}
.width .col {
width:25%;
}
<div class='wrapper'>
<div class='content'>before width</div>
<div class='row'>
<div class='col'>aa</div>
<div class='col'>aaaa</div>
<div class='col'>aaaaaa</div>
<div class='col'>aaaaaaaa</div>
</div>
</div>
<div class='wrapper'>
<div class='content'>after width</div>
<div class='row width'>
<div class='col'>aa</div>
<div class='col'>aaaa</div>
<div class='col'>aaaaaa</div>
<div class='col'>aaaaaaaa</div>
</div>
</div>
To obtain what you want, I think the 1fr of CSS grid is the way to go (like you already noticed). Actually CSS grid is well supported. You will simply have issues with IE and you can follow this link to see the known bugs: https://caniuse.com/#feat=css-grid
In order to make it responsive you may consider media query to switch to a column layout on small screens:
.wrapper {
display: flex;
width: 300px;
}
.row {
display: grid;
grid-auto-columns:1fr;
grid-auto-flow:column;
}
.col {
padding: 5px;
border: 1px solid black;
box-sizing: border-box;
}
#media all and (max-width:500px) {
.row {
grid-auto-flow:row;
}
}
<div class='wrapper'>
<div class='content'>Content</div>
<div class='row'>
<div class='col'>aa</div>
<div class='col'>aaaa</div>
<div class='col'>aaaaaa</div>
<div class='col'>aaaaaaaa</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>

Make flex container expand and overflow its container

How do I make a flex parent with a nowrap flex-wrap expand to fit its content even if that means overflowing whatever is wrapping the parent?
Basically, the content has a min-width, I want the flex parent not to shrink more than the space all the flex items need.
Here is a JSFiddle https://jsfiddle.net/lazamar/odat477r/
.wrapper {
background-color: yellowgreen;
display: block;
padding: 10px;
max-width: 180px;
}
.parent {
display: flex;
flex-flow: row nowrap;
background-color: yellow;
}
.child {
display: block;
background-color: orange;
margin: 10px;
min-width: 50px;
}
<div class="wrapper">
<div class="parent">
<div class="child">Content</div>
<div class="child">Content</div>
<div class="child">Content</div>
<div class="child">Content</div>
<div class="child">Content</div>
</div>
</div>
The answer is what t1m0n said. Use display: inline-flex instead of display: flex for the parent.
.wrapper {
background-color: yellowgreen;
display: block;
padding: 10px;
max-width: 180px;
}
.parent {
display: inline-flex; /* -- only change --*/
flex-flow: row nowrap;
background-color: yellow;
}
.child {
display: block;
background-color: orange;
margin: 10px;
min-width: 50px;
}
<div class="wrapper">
<div class="parent">
<div class="child">Content</div>
<div class="child">Content</div>
<div class="child">Content</div>
<div class="child">Content</div>
<div class="child">Content</div>
</div>
</div>
Using display: inline-flex instead of display: flex is your best bet.
If, for any reason, that's not an option, use CSS positioning properties.
.wrapper {
background-color: yellowgreen;
display: block;
padding: 10px;
max-width: 180px;
position: relative; /* new; set bounding box for flex container */
min-height: 40px; /* new */
}
.parent {
display: flex;
flex-flow: row nowrap;
background-color: yellow;
position: absolute; /* new; remove flex container from document flow */
}
.child {
/* display: block; <-- not necessary */
background-color: orange;
margin: 10px;
min-width: 50px;
}
<div class="wrapper">
<div class="parent">
<div class="child">Content</div>
<div class="child">Content</div>
<div class="child">Content</div>
<div class="child">Content</div>
<div class="child">Content</div>
</div>
</div>