How to create flexible div items that break after the line? - html

I am trying to create "shopping items" embedded in a div that have a certain fixed width and height. I know that you can do display: inline !important; to keep the div's on one line.
However, how can I make it such that it breaks when the window size becomes smaller, preferably when the outer div is smaller?
Here is an illustration:
Here is what I tried:
<div class="row">
<div class="col-sm-12">
<div class="items">
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
</div>
</div>
</div>
and css:
.items {
display: flex !important;
flex-wrap: wrap !important;
-webkit-flex-wrap: wrap !important;
-moz-flex-wrap: wrap !important;
-o-flex-wrap: wrap !important;
-ms-flex-wrap: wrap !important;
}
.item {
width: 200px !important;
height: 500px !important;
margin: 10px !important;
text-align: center !important;
}

With flex you can also set a breaking point (without mediaquerie) when boxes reaches 200px of width and also span them on the whole line:
(bootstrap included in snippet , i do not really see troubles there)
.row {
text-align: center;
}
.items {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-justify-content: space-around;
-ms-flex-pack: distribute;
justify-content: space-around;
}
.item {
/* with a breaking point at 200px width */
min-width: 200px;
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
/* or without min-width nor flex, just:
width:200px; it will wrap everytime needed and boxes will keep a static width */
height: 150px;/* none or whatever*/
margin: 10px 30px;/* whatever*/
text-align: center;
border: solid;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
<div class="col-sm-12">
<div class="items">
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
</div>
</div>
</div>

So easy like that;
float: left;

You can use CSS Flexbox. Its handles it easily.
Have a look at the snippet below (resize your browser to see them in action):
.outer {
display: flex;
flex-wrap: wrap;
}
.item {
width: 100px;
height: 100px;
padding-top: 10px;
text-align: center;
background: #eee;
border: 3px solid #aaa;
margin: 20px;
}
body {
padding: 20px;
}
<div class="outer">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
Hope this helps!

As an alternative to the other options I would suggest a look at isotope (http://isotope.metafizzy.co/). The benefits of using this over a pure css solution would become more apparent if you decided to include any filtering or sorting of your shopping items.

You can use flex-basis to ensure your elements are always 200px if it cannot grow nor shrink.
Using the flex shorthand property:
flex: 0 0 200px; /* 'flex-grow: 0' 'flex-shrink: 0' 'flex-basis: 200px' */
.items {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
}
.item {
box-sizing: border-box;
flex: 0 0 200px; /* <'flex-grow'> <'flex-shrink'> <'flex-basis'> */
height: 100px;
margin-bottom: .5em; /* Space between flex-items vertically*/
text-align: center;
border: 2px dashed grey;
}
<div class="row">
<div class="col-sm-12">
<div class="items">
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
<div class="item">
<p>Hello</p>
</div>
</div>
</div>
</div>
Notes:
In the demo we use the recommended syntax, which is using
the flex shorthand property.
Do not overuse the !important flag. It should not be needed in any of your classes.
Removed vendor prefixes for demo simplicity.

Related

How to align multiple divs vertically on the left and one big div in the right?

I have been trying so hard to find a solution to this but I couldnt achieve the desired solution.
I want to have the following:
and this is what I have tried so far:
#outer-div {
width: 100%;
text-align: left;
background-color: #027DB4;
}
#inner-div {
display: inline-block;
margin: auto;
padding: 3px;
}
<div id="outer-div">
<div id="inner-div" class="input-group">
<label>1</label>
<select>
</select>
</div>
<div id="inner-div" class="input-group">
<label>2</label>
<input>
</div>
</div>
<div id="outer-div">
<div id="inner-div" class="input-group">
<label>3</label>
<input>
</div>
</div>
<div id="outer-div">
<div id="inner-div" class="input-group">
<label>4</label>
<input>
</div>
</div>
P.S. I don't want to use float because it ruins everything else in that page.
use flexbox for this kind of stuff
#container {
display: flex;
}
#left {
display: flex;
flex-direction: column;
}
#right {
display: flex;
flex: 1;
margin-left: 5vw;
flex-direction: column;
}
div {
border: solid 2px black;
}
<div id='container'>
<div id='left'>
<div> one</div>
<div> two</div>
<div> three</div>
</div>
<div id='right'>
<div>right</div>
<div>another right</div>
</div>
</div>
DCR is right on with flexbox. You can also use CSS grid and avoid nesting items https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout.
#outer-div {
text-align: left;
background-color: #027DB4;
display: grid;
}
.right-column {
grid-column: 2 / 2;
grid-row: 1 / 4;
}
<div id="outer-div">
<div class="input-group">1</div>
<div class="input-group">2</div>
<div class="input-group">3</div>
<div class="input-group right-column">4</div>
</div>
.box1{
display:flex;
justify-content: space-between;
}
<div class="box1">
<div class="box2">
<div class="div1">1</div>
<div class="div2">2</div>
<div class="div3">3</div>
</div>
`<div class="div4">4</div>`
</div>
If you do want to try CSS Grid, this is a route to try. .right and .left class properties are added to allow more targeted styling, if needed, and borders are added to the parent and container elements to highlight them.
.outer-div {
display: grid;
grid-template-columns: auto auto;
grid-gap: 1em;
padding: 1em;
border: 1px solid red;
}
.inner-div.left {
grid-column: 1;
border: 1px solid blue;
}
.inner-div.right {
grid-column: 2;
grid-row: 1 / span 3;
border: 1px solid green;
}
<div class="outer-div">
<div class="inner-div left">
<label>1</label>
<select>
</select>
</div>
<div class="inner-div left">
<label>2</label>
<input>
</div>
<div class="inner-div left">
<label>3</label>
<input>
</div>
<div class="inner-div right">
<label>4</label>
<input>
</div>
</div>

Fix flex element in the end of first row

I need to fix some elements always at the end of the first row on flex container (with flex-wrap: wrap).
Examples (pay attention on button "Expand" ):
I tried to use 'row-reverse' + 'order: -1', but in this case, elements moved to the new row from left to right (when I need from right to left).
Here is my snippet: https://jsbin.com/divavosafu/1/edit?html,css,output
Any ideas?
Just nest the numbered buttons in an element and make both it and the main container a flex container:
.container {
display: flex;
flex-flow: row nowrap;
align-items: flex-start;
resize: horizontal;
overflow: auto;
}
.numbers {
display: flex;
flex-flow: row wrap;
}
.expand {
flex: 1 1 auto;
}
.right {
flex: 0 0 auto;
}
.item {
display: inline-block;
margin: 4px;
padding: 8px;
border: 1px solid gray;
}
<div class="container">
<div class="numbers">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>
<div class="expand">
<div class="item">Expand</div>
</div>
<div class="right">
<div class="item right1">Right 1</div>
<div class="item right2">Right 2</div>
</div>
</div>
Looks like I found something similar to solution, but button "Expand" should be in the left "container"
.container {
display: inline-block;
width: 100%;
}
.right {
float: right;
}
.item {
display: inline-flex;
padding: 8px;
border: 1px solid #CECECE;
}
.item:not(:last-child) {
margin-right: 8px;
margin-top: 8px;
}
<div class="container">
<div class="right">
<div class="item expand">Expand</div>
<div class="item ">Right 1</div>
<div class="item ">Right 2</div>
</div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>

issue with horizontal scrolling div using flexbox

I am using flexbox css to make a container with number of divs to scroll horizontally but the problem is when I try to add more divs to the container, it moves to the left side and the divs left to the display are hidden.
I don't understand what's happening
here is the code snippet and codepen
.scroll{
display: flex;
flex-wrap: nowrap;
overflow-x: auto;
justify-content: space-evenly;
-webkit-overflow-scrolling: touch;
-ms-overflow-style: -ms-autohiding-scrollbar;
}
.item{
flex: 0 0 auto;
background: #e4e4e4;
width: 150px;
height: 150px;
margin: 10px;
}
<div class="scroll">
<div class="item">
</div>
<div class="item">
</div> <div class="item">
</div> <div class="item">
</div> <div class="item">
</div> <div class="item">
</div>
<div class="item">
</div> <div class="item">
</div>
<div class="item">
</div> <div class="item">
</div>
</div>
Thank you
The main issue here is that for some justify-content values, the overflow distribution will overflow the flex parent at both its left and right edge.
https://www.w3.org/TR/css-align-3/#distribution-values
Therefor a new keyword has been introduced, safe, where one can control how that overflow should behave.
https://www.w3.org/TR/css-align-3/#overflow-values
As this is a quite new addition to the Flexbox model, it won't work cross browsers yet, nor does space-evenly.
When it does (and for browsers that support it), this CSS line will fix the issue
justify-content: space-evenly safe;
A possible workaround, to achieve both evenly spaced items when they won't fill their parent, and only overflow at the right edge when too many, could be to use auto margins.
Stack snippet
.scroll{
display: flex;
/*flex-wrap: nowrap; this is the default, can be removed */
overflow-x: auto;
/*justify-content: space-evenly; removed */
-webkit-overflow-scrolling: touch;
-ms-overflow-style: -ms-autohiding-scrollbar;
}
.item{
flex: 0 0 auto;
background: #e4e4e4;
width: 150px;
height: 75px;
margin: 10px;
}
.item{
margin-left: auto; /* added */
}
.item:last-child{
margin-right: auto; /* added */
}
Too many
<div class="scroll">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<br>Too few
<div class="scroll">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Remove justify-content: space-evenly; from .scroll.
Demo:
.scroll{
display: flex;
flex-wrap: nowrap;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
-ms-overflow-style: -ms-autohiding-scrollbar;
}
.item{
flex: 0 0 auto;
background: #e4e4e4;
width: 150px;
height: 150px;
margin: 10px;
}
<div class="scroll">
<div class="item">
</div><div class="item">
</div><div class="item">
</div><div class="item">
</div><div class="item">
</div><div class="item">
</div><div class="item">
</div><div class="item">
</div><div class="item">
</div><div class="item">
</div><div class="item">
</div><div class="item">
</div><div class="item">
</div><div class="item">
</div><div class="item">
</div><div class="item">
</div>
</div>
This will stop the elements from being out of bounds on both sides.
All div's get displayed in a row this way.
.Wrapper {
display: flex;
flex-direction: row;
overflow-x: auto;
max-width: 100%; //this will solve issue
}
.TagWrapper:{
display: flex;
flex-shrink: 0;
}
You can set the position of the Parent or Container to be Relative and the child inside them to be absolute.
.Parent{
display: flex;
// and use any flexbox property
width: 100%;
height: 100%
position: relative; // important point
overflow: auto;
}
.Child{
position: absolute; // important point
}

align-self: flex-end not moving item to bottom [duplicate]

This question already has answers here:
Align div element to bottom of container [duplicate]
(1 answer)
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
(6 answers)
How does flex-wrap work with align-self, align-items and align-content?
(2 answers)
Closed 5 years ago.
As you can see here: JSFiddle
I want author div to be at the bottom of his parent container. I tried with align-self: flex-end; but it's not working. What am I doing wrong?
.flexbox {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.item {
display: flex;
flex-direction: column;
width: 100px;
border: 1px solid #000;
padding: 10px;
}
.item .author {
width: 100%;
align-self: flex-end;
border: 1px solid #000;
}
<div class="flexbox">
<div class="item">
<div class="title">
Title
</div>
<div class="content">
Content
</div>
<div class="author">
Author
</div>
</div>
<div class="item">
<div class="title">
Title
</div>
<div class="content">
Content<br>Content
</div>
<div class="author">
Author
</div>
</div>
<div class="item">
<div class="title">
Title
</div>
<div class="content">
Content<br>Content<br>Content
</div>
<div class="author">
Author
</div>
</div>
</div>
Try add to .author
margin-top: auto;
You also need to remove flex-end.
You can make a wrapper div around the divs which have to float from flex start. And the author outside the wrapper and give to .item justify-content: space-between;.
https://jsfiddle.net/0zq5a5xu/2/
.flexbox {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.item {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100px;
border: 1px solid #000;
padding: 10px;
}
.wrapper {
display: flex;
flex-direction: column;
}
.author {
width: 100%;
border: 1px solid #000;
}
<div class="flexbox">
<div class="item">
<div class="wrapper">
<div class="title">
Title
</div>
<div class="content">
Content
</div>
</div>
<div class="author">
Author
</div>
</div>
<div class="item">
<div class="wrapper">
<div class="title">
Title
</div>
<div class="content">
Content<br>Content
</div>
</div>
<div class="author">
Author
</div>
</div>
<div class="item">
<div class="wrapper">
<div class="title">
Title
</div>
<div class="content">
Content<br>Content<br>Content
</div>
</div>
<div class="author">
Author
</div>
</div>
</div>
Hope this helps.

css flex shrink container width to fit its items

I'm displaying a list of same sized items in a flex div. I've aligned them to the left. However I'd like the list to be centred as a whole. Any suggestions about how to do this?
Please try to snipped below.
$('button').click(function(){
$('.list').toggleClass('hack')
});
.item {
width: 40px;
height: 40px;
background-color: skyblue;
border: 1px solid black;
}
.list-container {
width: 100px;
background-color: grey;
flex-direction: row;
display: flex;
}
.spacer {
flex: 1;
}
.list.hack {
width: 84px;
}
.list {
display: inline-flex;
flex-direction: row;
flex-wrap: wrap;
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='list-container'>
<div class='spacer'></div>
<div class='list'>
<div class='item'></div><div class='item'></div>
<div class='item'></div><div class='item'></div>
<div class='item'></div>
</div>
<div class='spacer'></div>
</div>
<button>Toggle fixed list width (hack)</button>
I believe the best way is to insert the "item" elements to a new div, setting:
<div style="margin:0 auto;width: 85px;">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
and also applying .item{float:left;}
It's not enough when you set justify-content: center; to .list?
Then if you need to make the standalone item to be aligned to left, you can set its margin-right: 42px; (to compensate the space next to it)
You can do the same without using flex
HTML
<div class='list'>
<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 class='item'>item 5</div>
</div>
CSS
.list{
display:inline-block;
background-color: grey;
width:100px;
clear:both;
justify-content: center;
}
.list .item{
float:left;
width:48%;
background-color: skyblue;
height: 40px;
border: 1px solid black;
}
.list .item:last-child{
margin-left:25%;
}
Click here for JSFiddle sample