I'm using flexbox to place some elements side by side
<div class="artist-wrapper">
<div class="artist"></div>
<div class="artist"></div>
<div class="artist"></div>
</div>
.artist-wrapper {
display: flex;
height: 100%;
width: 100%;
}
.artist {
flex: 1;
height: 100%;
}
It works quite well! On small screens (like mobile) the `.artist-elements shouldn't stay side by side but rather among each other. Is there a way to do this by using flexbox?
You need media queries and then allow wrapping in the parent.
JSFiddle Demo
.artist-wrapper {
display: flex;
height: 100%;
width: 100%;
}
.artist {
flex: 1;
height: 100px;
border: 1px solid grey;
}
#media screen and (max-width: 480px) {
.artist-wrapper {
flex-wrap: wrap;
}
.artist {
flex: 0 0 100%
}
}
<div class="artist-wrapper">
<div class="artist"></div>
<div class="artist"></div>
<div class="artist"></div>
</div>
Is this what you are after? This is using display: inline-block
But here is a solution using flexbox, the property for this is flex-wrap: wrap, if you remove min-width and min-height you can have a more fluid layout.
You may use min-width instead or with mediaqueries.
(see comments)
.artist-wrapper {
display: flex;
flex-wrap:wrap;
}
.artist {
flex:1;
min-width:250px;/* whatever breaking points you look for : here we have for 3 elements a first-breakpoint at 500px then another at 250 */
min-height: 50px;/* demo purpose use content instead*/
box-shadow:0 0 0 1px gray;
}
/* extra */
.artist-wrapper {
margin:1em;
}
.artist {
color:#444;
font-size:1.5em;
font-family:'lucida console', courier;
background:tomato;
display:flex;
align-items:center;
justify-content:center;
}
.artist:nth-child(odd) {
background:orange
}
.artist:nth-child(4n) {
background:turquoise;
min-width: 500px;
max-width:100%;/* allows it to shrink on small device , can be set to all of them */
}
<div class="artist-wrapper">
<div class="artist"></div>
<div class="artist">breaks at 250px;</div>
<div class="artist"> breaks at 500px </div>
</div>
<div class="artist-wrapper">
<div class="artist"></div>
<div class="artist">breaks at 250px;</div>
<div class="artist">breaks at 500px;</div>
<div class="artist"> breaks at 1250px;</div>
<div class="artist"> and so on ... </div>
<div class="artist"></div>
<div class="artist"></div>
<div class="artist"></div>
<div class="artist"></div>
<div class="artist"></div>
<div class="artist"></div>
<div class="artist"></div>
</div>
Related
so I have X divs and I want to put 2 divs in one row next to each other. If the screen size width is below n px there should be 1 div per row.
Currently I have this
#container {
display: flex;
}
.box {
width: 50px;
background: red;
}
#media(max-width: 300px) {
#container {
display: block;
}
}
<div id="container">
<div class="box"> 1 </div>
<div class="box"> 2</div>
<div class="box"> 3 </div>
<div class="box"> 4 </div>
</div>
How can I limit the flex box to two divs per row?
Add 50% width on .box and flex-wrap:wrap on the container
Additionally, what you did by changing display: flex to block was not required. Just change the .box elements width to 100%
#container {
display: flex;
flex-wrap: wrap;
}
.box {
width: 50%;
background: red;
}
#media(max-width: 300px) {
.box {
width: 100%;
}
}
<div id="container">
<div class="box"> 1 </div>
<div class="box"> 2</div>
<div class="box"> 3 </div>
<div class="box"> 4 </div>
</div>
Just add a property in your container class like
.container {
display: flex;
flex-wrap: wrap;
}
And in box class just specify the width of your box as 50% like
.box {
width: 50%;
background: red;
}
That should do the trick.
Flex will do a trick for you. flex-wrap: wrap for #container will make children wrap when necessary. .box with 50% and after breakpoint 100%.`
According to MDN:
The CSS flex-wrap property specifies whether flex items are forced into a single line or can be wrapped onto multiple lines. If wrapping is allowed, this property also enables you to control the direction in which lines are stacked.
If you are new to flexbox I recommend this guide.
Snippet
#container {
display: flex;
flex-wrap: wrap;
}
.box {
width: 50%;
background: red;
}
#media(max-width: 300px) {
.box {
width: 100%;
}
}
<div id="container">
<div class="box"> 1 </div>
<div class="box"> 2 </div>
<div class="box"> 3 </div>
<div class="box"> 4 </div>
</div>
I have a header with 2 rows of 2 Foundation columns of content, as below:
<div class="wrapper">
<div class="header row">
<div class="large-6 columns">
HEADER
</div>
<div class="large-6 columns">
menu
</div>
</div>
<div class="row">
<div class="large-5 none show-for-medium columns info">
Some information to the left
</div>
<div class="large-7 columns">
<div class="image-container">
<div class="image">
image to the right
</div>
</div>
</div>
</div>
</div>
The .header height is dynamic and not set. I want the .image element to take up 100% of the remaining vertical space.
eg:
To that affect I have tried using flex and flex-grow, eg:
.wrapper {
display: flex;
flex-direction: column;
min-height: 100vh;
width: 100%;
}
.image-container {
flex-grow: 1;
}
but had no luck, see fiddle: https://jsfiddle.net/9kkb2bxu/46/
Would anyone know how I could negate the dynamic height of the header from the 100vh of the image container?
.wrapper {
display: flex;
flex-direction: column;
min-height: 100vh;
width: 100%;
border: 1px solid black;
background-color: #ccc;
}
.row {
width: 100%;
}
.header {
background-color: green;
}
.info {
background-color: yellow;
border: 1px solid #ccc;
}
.image-container {
border: 1px solid black;
display: flex;
}
.image {
background-color: red;
flex-grow: 1;
width: 100%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.1/css/foundation.min.css" rel="stylesheet"/>
<div class="wrapper">
<div class="header row">
<div class="large-6 columns">
<h1>
HEADER
</h1>
</div>
<div class="large-6 columns">
<h1>
menu
</h1>
</div>
</div>
<div class="row">
<div class="large-5 none show-for-medium columns info">
Some information to the left
</div>
<div class="large-7 columns">
<div class="image-container">
<div class="image">
image to the right
</div>
</div>
</div>
</div>
</div>
Set the second row to take up the rest of the remaining height with flex: 1 and make sure you nest that flex with display: flex:
.row.target-row {
flex: 1;
display: flex;
}
Set the .image-container to 100% height of its column parent.
.image-container {
height: 100%;
}
By default both columns will expand. Stop the left column from expanding with:
.large-5 {
align-self: flex-start;
}
(flex-start reference: https://stackoverflow.com/a/40156422/2930477)
Complete Example
.wrapper {
display: flex;
flex-direction: column;
min-height: 100vh;
width: 100%;
border: 1px solid black;
background-color: #ccc;
}
.row {
width: 100%;
}
.header {
background-color: green;
}
.info {
background-color: yellow;
border: 1px solid #ccc;
}
.image-container {
height: 100%;
background-color: red;
}
.large-5 {
align-self: flex-start;
}
.row.target-row {
flex: 1;
display: flex;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.1/css/foundation.min.css" rel="stylesheet" />
<div class="wrapper">
<div class="header row">
<div class="large-6 columns">
<h1>
HEADER
</h1>
</div>
<div class="large-6 columns">
<h1>
menu
</h1>
</div>
</div>
<div class="row target-row">
<div class="large-5 none show-for-medium columns info">
Some information to the left
</div>
<div class="large-7 columns">
<div class="image-container">
<div class="image">
image to the right
</div>
</div>
</div>
</div>
</div>
flex-grow only applies to flex children.
.image-container isn't a direct child of a display: flex element, so that property has no effect.
Plus, it affects the flex axis, which is not what you want.
Instead, you need to put those two elements in their own flex row, and use align-items (on the parent) and align-self (on either child) so that the first one aligns (on the cross axis) to flex-start (stick to top) and the second one to stretch.
You'll also want that flex row (parent) to have flex-grow: 1 so that it stretches along the vertical flex axis of its parent (.wrapper) to fill the rest of the page (otherwise, the grandchild will have nothing to stretch to).
For more information, read a good flex tutorial.
div.wrapper > div:not(.header).row {
flex: 1; /* 1 */
display: flex; /* 1 */
}
div.large-7.columns {
display: flex; /* 2 */
}
div.image-container { /* 3 */
flex: 1;
}
div.large-5.show-for-medium { /* 4 */
align-self: flex-start;
}
jsFiddle
Notes:
flex container and items consume all remaining height of respective parents
give children full height (via align-items: stretch initial setting)
flex item consumes all available width
yellow box does not need to expand to full height; now set to content height
I have a responsive website with a two-column layout in large browser windows. The two-column layout is currently implemented using float. On smaller screens I'd like to have just one column. The content of the other column should be displayed between the two elements of the main column, like shown here:
<div class="two-columns">
<div class="main-column">
<div class="red-element"></div>
<div class="yellow-element"></div>
</div>
<div class="sidebar-column">
<div class="green-element"></div>
</div>
</div>
I tried using a flex-box-based approach, basically the one described in this question, but flex-basis still seems to be unsupported in Safari when flex-direction is column. Proper Safari support is a must as Safari is the main browser of my visitors.
Is there a way this can be achieved using CSS only without having to place the green element twice in my markup?
Here's a general solution using one flex container:
<div class="container">
<div class="box"> ... </div><!-- red box -->
<div class="box"> ... </div><!-- green box -->
<div class="box"> ... </div><!-- yellow box -->
</div>
Starting with small screens (for no particular reason), stack them in a column:
.container {
display: flex;
flex-direction: column;
}
.box {
height: 100px;
width: 100%;
}
Re-arrange the layout for wider screens:
#media (min-width: 800px) {
.container {
flex-direction: row;
flex-wrap: wrap;
}
.box {
flex-basis: 45%;
}
}
On screens wider than 800px, the container lines the items in a row and enables wrapping. Each box is given a large enough width (flex-basis) for only two to fit on a line.
Full demo:
* {
box-sizing: border-box;
}
.container {
display: flex;
flex-direction: column;
padding: 5px 0;
background-color: #f5f5f5;
border: 1px solid #aaa;
}
.box1 { background-color: red; }
.box2 { background-color: lightgreen; }
.box3 { background-color: yellow; }
.box {
height: 100px; /* `flex-basis: 100px` would also work */
width: calc(100% - 20px);
margin: 5px 10px;
border: 1px solid #ccc;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.2em;
}
#media (min-width: 800px) {
.container {
flex-direction: row;
flex-wrap: wrap;
}
.box {
flex-basis: 45%;
}
}
<div class="container">
<div class="box box1"><span>1</span></div>
<div class="box box2"><span>2</span></div>
<div class="box box3"><span>3</span></div>
</div>
jsFiddle
From your question:
...but flex-basis still seems to be unsupported in Safari when flex-direction is column
I'm not sure this is correct (caniuse.com).
However, you can always use width or height properties instead of flex-basis (more details: What are the differences between flex-basis and width?).
Using Bootstrap,
<div class="row">
<div class="col-md-8">
<div class="red-element"></div>
</div>
<div class="col-md-4">
<div class="green-element"></div>
</div>
<div class="col-md-8">
<div class="yellow-element"></div>
</div>
<div class="clearfix"></div>
</div>
This uses float methods and works on all browsers.
you should using #media via margin-top.on specific screen width (via #media), change margin-top of the green-element to -200%. and change margin-top of yellow-element to 100%.they change their position very nice :)
please see this link:
http://jsbin.com/xozeviseka/edit?html,output
You need to change some html structure so then you can do this.
*,*:after,*:before {
box-sizing:border-box;
}
.two-columns {
position:relative;
background:#EFEFEF;
border:1px solid #000;
}
.red-element,
.green-element,
.yellow-element {
margin-bottom:30px;
}
.red-element {
height:70px;
background:#FF0004;
}
.green-element {
height:70px;
background:#7ED321;
}
.yellow-element {
height:100px;
background:#F8E71C;
}
#media (min-width:767px) {
.main-column {
width:70%;
padding:10px;
}
.sidebar-column {
position:absolute;
right:0;
top:0;
width:30%;
padding:10px;
}
}
<div class="two-columns">
<div class="main-column">
<div class="red-element"></div>
<div class="sidebar-column">
<div class="green-element"></div>
</div>
<div class="yellow-element"></div>
</div>
</div>
Or if you don't want to change html structure you have to take another element that only show in mobile for example
*,*:after,*:before {
box-sizing:border-box;
}
.two-columns {
background: #EFEFEF;
border: 1px solid #000;
overflow: hidden;
}
.red-element,
.green-element,
.yellow-element {
margin-bottom:30px;
}
.red-element {
height:70px;
background:#FF0004;
}
.green-element {
height:70px;
background:#7ED321;
}
.yellow-element {
height:100px;
background:#F8E71C;
}
.hideMobile{
display:none;
}
#media (min-width:767px) {
.main-column {
width: 70%;
float: left;
padding: 10px;
}
.sidebar-column {
float: right;
width: 30%;
padding: 10px;
}
.showMobile {
display:none;
}
.hideMobile {
display:block;
}
}
<div class="two-columns">
<div class="main-column">
<div class="red-element"></div>
<div class="green-element showMobile"></div><!--only for mobile-->
<div class="yellow-element"></div>
</div>
<div class="sidebar-column hideMobile"><!--hide in mobile-->
<div class="green-element"></div>
</div>
</div>
I'm facing a bootstrap problem.
In my html page, I used different containers but I'm not able to re-arrange and re-organize them as I want in mobile screens.
Here my Bootply.
And to be more clear, I want it to look like this:
Containers 1 and 5 are fluid, instead 2, 3, 4 are not.
How can I move container 1 and 2 after 3 and 4 in small screens?
Thank you in advance for your reply!
Cheers!
This is not possible without rearranging your content.
One way is to make two versions of the area you want to rearrange and hide them based on the width of the browser. This is bad practice, especially if you have a whole website you want to rearrange on resize, but for a small div with 5 divs inside it would be an acceptable solution.
Here is the adapted HTML
<div class="desktopwrapper"> <!-- added a desktop wrapper -->
<div class="container-fluid green"></div>
<div class="container red"></div>
<div class="container ">
<div class="row">
<div class="col-sm-8 yellow"></div>
<div class="col-sm-4 fuxia"></div>
</div>
</div>
<div class="container-fluid blue"></div>
</div>
<div class="mobilewrapper"> <!-- added a mobile wrapper and rearranged content -->
<div class="container ">
<div class="row">
<div class="col-sm-8 yellow"></div>
<div class="col-sm-4 fuxia"></div>
</div>
</div>
<div class="container-fluid green"></div>
<div class="container red"></div>
<div class="container-fluid blue"></div>
</div>
And I have added these lines to CSS:
#media screen and (max-width: 766px) {
.desktopwrapper {
display:none;
}
}
#media screen and (min-width: 767px) {
.mobilewrapper {
display:none;
}
}
What this basically does, is hide one arrangement when the screen gets resized to 766px wide and will display the other. And of course the other way around.
You can try it out here.
Another way would be to put everything in a wrapper, position the wrapper relative, all the divs inside absolute and just place them with using px. This is however really not useful when divs have changing heights depending on the content. The best way would be to do like the example I have.
flexbox proof of concept.
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
color: white;
text-align: center;
}
body {
height: 100%;
}
h2 {
display: inline-block;
background: #000;
padding: .25em;
}
.page {
min-height: 100%;
display: flex;
flex-direction: column;
}
header {
flex: 0 0 75px;
background: darkgreen;
}
.banner {
flex: 0 0 100px;
width: 80%;
margin: auto;
background: darkred;
}
main {
flex: 1;
width: 80%;
margin: auto;
display: flex;
}
.content {
width: 75%;
background: yellow;
}
aside {
width: 25%;
background: fuchsia;
}
footer {
flex: 0 0 100px;
background: lightblue;
}
#media screen and (max-width: 768px) {
.banner,
main {
width: 100%;
}
main {
flex-direction: column;
order: -1;
}
.content,
aside {
flex: 1;
width: 100%;
}
aside {
flex: 0 0 150px
}
}
<div class="page">
<header>
<h2>1</h2>
</header>
<div class="banner">
<h2>2</h2>
</div>
<main>
<div class="content">
<h2>3</h2>
</div>
<aside>
<h2>4</h2>
</aside>
</main>
<footer>
<h2>5</h2>
</footer>
</div>
Codepen Demo
I have three 3 child div's with class span2, span7 and span3 respectively. When my browser width is below 763px I want it to be in this order span2, span3 and span7. How will I do that through css?
Here is my initial code:
<div class="row-fluid">
<div class="span2">
</div>
<div class="span7">
</div>
<div class="span3">
</div>
</div>
You could achieve this by using flexible boxes layout and flex order like this:
JSFiddle - DEMO
.row-fluid > div {
width: 100px;
height: 100px;
border: 1px solid red;
}
#media (max-width: 763px) {
.row-fluid {
display: flex;
flex-wrap: wrap;
flex-direction: column;
}
.span2 {
order: 1;
}
.span7 {
order: 3;
}
.span3 {
order: 2;
}
}
<div class="row-fluid">
<div class="span2">span2</div>
<div class="span7">span7</div>
<div class="span3">span3</div>
</div>