Can I get flexbox sidebars to share a new row, after a media query?
Before (on wide screens)
+---+-------+---+
| | | |
| L | Main | R |
| | | |
+---+-------+---+
After (on narrow screens)
+-------+
| |
| Main |
| |
+-------+
| | |
| L | R |
| | |
+-------+
HTML (not changeable after media query)
<div class="container">
<div class="sideLeft">L</div>
<div class="MainContent">Main</div>
<div class="sideRight">R</div>
</div>
You can change order: -1 on main div with media queries. You also need to set flex-wrap: wrap on container element. Also calc(% - 10px) is for margin of 5px on both sides but if you don't want margins you can just use % as you can se here
* {
box-sizing: border-box;
}
.container {
display: flex;
flex-wrap: wrap;
height: 200px;
border: 1px solid gray;
padding: 5px
}
.container > div {
display: flex;
border: 1px solid black;
margin: 5px;
flex: 1;
}
div.main {
flex: 3;
}
#media(max-width: 480px) {
div.main {
order: -1;
flex: 0 0 calc(100% - 10px);
}
.container > div:not(.main) {
flex: 0 0 calc(50% - 10px);
}
}
<div class="container">
<div class="sideLeft">L</div>
<div class="main">Main</div>
<div class="sideRight">R</div>
</div>
Related
Let's say I have a flexbox set up like this:
<div class="flexbox">
<div id="item-1"></div>
<div id="item-2"></div>
<div id="item-3"></div>
</div>
I currently have the flex items set up using CSS like so:
-------------------------------------------------
| 1 | 2 | 3 |
-------------------------------------------------
I want the items to change to this layout when the screen reaches a certain size:
--------------------
| 3 | 1 |
-----------------------------
| 2 |
-----------------------------
I know I can use #item-3 {order:-1} to move it to the beginning, but the part I'm having trouble with is floating element 1 to the right, above 2.
Any help is appreciated, thanks!
min-width is solution:
.flexbox {
display: flex;
flex-wrap: wrap;
}
.flexbox div {
border: 1px solid #ddd;
padding: 10px;
box-sizing: border-box;
}
#item-1, #item-3 {flex: 1;}
#item-2 {flex: 2;}
#media(max-width: 768px) {
#item-1, #item-3 {
order: 1;
}
#item-2 {
order: 2;
border-top: 0;
min-width: 100%;
}
}
<div class="flexbox">
<div id="item-1"></div>
<div id="item-2"></div>
<div id="item-3"></div>
</div>
I need the appropriate Html and CSS for the following
Here is the layout of the app
Detailed Figure General Figure
------------------------- -------------------------
| App Header | | App Header |
------------------------- -------------------------
| Module Header| Sub | | | |
|--------------| Module | | | |
| |--------| | | |
| Module | Sub | | Main | Sub |
| Content | Module | | Module | Module |
| |--------| | Space | Space |
| | Sub | | | |
|--------------| Module | | | |
| Module |--------| | | |
| Footer | | | | |
------------------------- -------------------------
App Header is a static 60px
Module Header is a static 35px
Module Content is dynamic and overflows
Module Footer is dynamic and needs to always display everything on screen (it would never be more than say 500px)
What is the appropriate way to setup the Main Module Space and children?
How do I get the Headers and Footers to understand they're in containers and should not cover the entire width of the screen?
(I've used absolute position for the footer but that causes Module Content to hide behind the Module Footer)
I figured it out for the most part
https://jsfiddle.net/jackyFrosty/46mjtghv/47/
<div class='mainApp'>
<div class='appHeader'>
Header
</div>
<div class='contentContainer'>
<div class='leftContainer'>
<div class='moduleContainer'>
<header class='header'>
Header
</header>
<main class='content'>
<div>Content 1</div><div>Content 2</div><div>Content 3</div><div>Content 4</div>
<div>Content</div><div>Content</div><div>Content</div><div>Content</div><div>Content</div>
<div>Content</div><div>Content</div><div>Content</div><div>Content</div><div>Content</div>
<div>Content</div><div>Content</div><div>Content</div><div>Content</div><div>Content</div>
<div>Content 96</div><div>Content 97</div><div>Content 98</div><div>Content 99</div>
</main>
<footer class='footer'>
<div>Footer</div><div>Footer</div><div>Footer</div><div>Footer</div>
<!--div>Footer</div><div>Footer</div><div>Footer</div><div>Footer</div-->
</footer>
</div>
</div>
<div class='rightContainer'>
Right Content
</div>
</div>
</div>
* {
box-sizing: border-box;
border-style: solid;
border-color: white;
padding: 0px;
margin: 0px;
}
.mainApp {
height: 100%;
}
.appHeader {
height: 60px;
border-color: black;
}
.contentContainer {
height: calc(100vh - 60px);
}
.leftContainer {
float: left;
width: 75%;
height: 100%;
overflow: auto;
border-color: black;
}
.rightContainer {
float: left;
width: 25%;
height: 100%;
overflow: auto;
border-color: black;
}
/* /////////// Important part ////////// */
.moduleContainer {
border-color: orange;
display: -webkit-flex;
display: flex;
flex-direction: column;
height: calc(100vh - 60px);
}
.header {
border-color: red;
height: 35px;
-webkit-flex: 0 0 auto;
flex: 0 0 auto;
}
.content {
border-color: green;
overflow-y: scroll;
-webkit-flex: 1 1 auto;
flex: 1 1 auto;
}
.footer {
border-color: blue;
}
I'm not totally sure this is possible, but I figured I'd ask.
I'm wondering to move a sidebar in-between some content when it hits a breakpoint.
So, for example something like this:
+---------------------+ +-------------+
| | | |
| Top Content | | |
| | | Sidebar |
| | | |
+---------------------+ | |
+---------------------+ | |
| | | |
| | | |
| | | |
| Other | | |
| Content | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
+---------------------+ +-------------+
To this:
+-------------------------+
| |
| Top Content |
| |
+-------------------------+
+-------------------------+
| |
| |
| Sidebar |
| |
| |
| |
+-------------------------+
+-------------------------+
| |
| |
| |
| |
| Other |
| Content |
| |
| |
| |
| |
+-------------------------+
So I know that I can set the orders, but I'm not quite sure how to get the "flow" to correctly set.
I'm wondering something like this:
.flex-container {
display: flex;
flex-direction: row;
}
.top-content {
order: 1;
}
.sidebar {
order: 3;
justify-self: flex-end;
}
.other-content {
order: 2;
}
#media screen and (max-width: 767px) {
.flex-container {
flex-direction: column;
}
.sidebar {
order: 2;
}
.other-content {
order: 3;
}
}
<div class="flex-container">
<div class="top-content">
...
</div>
<div class="sidebar">
...
</div>
<div class="other-content">
...
</div>
</div>
But I'm not sure if that's even plausible? Wondering if this is something that needs to be done with CSS Grid instead? Anyways, just a thought. Was hoping to use the same content structure without having to hide/show the same thing with breakpoints and writing more markup on the page.
It's simpler and easier with CSS Grid.
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 3fr;
grid-gap: .5em;
height: 100vh;
background-color: gray;
}
.top-content {
grid-column: 1;
background-color: orangered;
border: 1px dashed black;
}
.sidebar {
grid-column: 2;
grid-row: 1 / -1;
background-color: aqua;
border: 1px solid black;
}
.other-content {
grid-column: 1;
background-color: lightgreen;
border: 1px dashed black;
}
body {
margin: 0;
}
#media (max-width: 500px) {
.grid-container {
grid-template-columns: 1fr;
grid-template-rows: auto;
}
.sidebar {
grid-column: 1;
grid-row: 2;
}
}
<div class="grid-container">
<div class="top-content">top content</div>
<div class="sidebar">sidebar</div>
<div class="other-content">other content</div>
</div>
jsFiddle demo
Well, I figured out how to achieve this, see:
.flex-container {
display:flex;
flex-flow: row wrap;
box-sizing: border-box;
}
#media screen and (max-width: 600px) {
break {display:none;}
}
div {
border: 1px black solid;
}
.flex-container > div {
box-sizing: border-box;
}
.flex-container > div, break{
display: inline-block;
}
break{
flex-basis: 100%;
width: 0px;
height: 0px;
overflow: hidden;
}
<div class="flex-container">
<div class="top-content" style="width: 350px; height: 500px;">
...
</div>
<div class="sidebar" style="width: 350px; height: 500px;">
...
</div>
<break></break>
<div class="other-content" style="width: 350px; height: 500px;">
...
</div>
</div>
The only thing I did was creating a custom HTML5 tag called <break>. This tag creates a new line between the divs that you specify. So, if you media-query is reached (due to lower resolutions) you only need to hide it.
The original idea was taken from: https://codepen.io/hrgdavor/pen/waXEqz
EDIT:
I realized about the leaking rowspan behaviour on my example. So I decided to search and I found this, and I created this demo:
.flex-container {
display:flex;
flex-flow: row wrap;
box-sizing: border-box;
flex-direction: column;
flex-wrap: wrap;
height: 1000px;
}
#media screen and (min-width: 600px) {
.top-content, .other-content {flex: 0 0 50%;}
.sidebar {flex: 0 0 100%; order: 1;}
}
#media screen and (max-width: 600px) {
.flex-container {flex-direction: row;}
.top-content, .other-content, .sidebar {flex: 0 0 100%;}
.other-content {order:2;}
}
.flex-container > div {
box-sizing: border-box;
}
/* Only for doing example */
.flex-container > div {
border: 1px black solid;
}
<div class="flex-container">
<div class="top-content">
...
</div>
<div class="sidebar">
...
</div>
<div class="other-content">
...
</div>
</div>
Note: box-sizing: border-box; is important.
Hope this helps!
I got four divs.
Div two is half the height of div 1, div 3 & 4 is half the height of div 2.
On a large display the placement of the divs are fine:
---------------- ---------- -------- --------
| | | Div 2 | | Div 3| | Div 4 |
| Div 1 | |________| ------- -------
| |
| |
----------------
On smaller screens I want the following layout:
---------------- ----------
| | | Div 2 |
| Div 1 | |________|
| | | Div 3 |
| | ----------
---------------- | Div 4 |
i.e. div 3 and 4 are placed under div 2.
But instead they are placed under div 1:
---------------- ----------
| | | Div 2 |
| Div 1 | |________|
| |
| |
----------------
-------- --------
| Div 3| | Div 4 |
------- -------
Is it possible to get the second alternative in some way? In my own attempts I have never got both the large screen and the smaller screen alternatives to work with the same code.
You could use the CSS property flexbox (MDN reference) to achieve this. See the example below (in full screen and stretch your screen).
While starting mobile first, you can work your way up and with setting media queries, you can easily modify the visual hierarchy of the boxes. First, put a display: flex; on the wrapper div and then on the desired breakpoint (here 480px), add another display: flex; on the .inner-wrapper.
Note: this is just a quick setup and there are many ways to do this.
.wrapper {
width: 100%;
height: 100vh;
display: flex;
}
.inner-wrapper {
width: 50%;
}
.box-large {
width: 50%;
height: 50%;
}
.box {
width: 100%;
height: 25%;
}
.box-small {
width: 100%;
height: 12.5%;
}
#media screen and (min-width: 480px) {
.inner-wrapper {
display: flex;
}
}
/* Visual stuff */
body {
margin: 0;
padding: 0;
}
.box-one {
background-color: red;
}
.box-two {
background-color: blue;
}
.box-three {
background-color: green;
}
.box-four {
background-color: yellow;
}
<div class="wrapper">
<div class="box-one box-large">red</div>
<div class="inner-wrapper">
<div class="box-two box">blue</div>
<div class="box-three box-small">green</div>
<div class="box-four box-small">yellow</div>
</div>
</div>
This is a question based on this question:
Twitter bootstrap 3 two columns full height
I have the same layout. But, when I try to put a DIV in the content part, it pushes the content of the sidebar down. Here's a Fiddle
<header>Header</header>
<div class="container">
<div class="row">
<div class="col-md-3 no-float">Navigation</div>
<div class="col-md-9 no-float"><div><div style="width=100%;height:55px;background:red"></div>Content</div></div>
</div>
CSS:
html,body,.container
{
height:100%;
}
.container
{
display:table;
width: 100%;
margin-top: -50px;
padding: 50px 0 0 0; /*set left/right padding according to needs*/
-moz-box-sizing: border-box;
box-sizing: border-box;
}
header
{
background: green;
height: 50px;
}
.row
{
height: 100%;
display: table-row;
}
.col-md-3.no-float, .col-md-9.no-float {
float: none; /* thanks baxabbit */
}
.col-md-3
{
display: table-cell;
background: pink;
}
.col-md-9
{
display: table-cell;
background: yellow;
float: none;
}
If you have other suggestions, I need to do the following layout using Bootstrap and Angular, keeping the idea of having full-height columns from the upper post:
+-------------------------------------------------+
| Header |
+------------+------------------------------------+
| Nav.Header | ContentHeader | < |
|------------|------------------------------------|
|Navigation | Content | T |
| | | E |
| | | X |
| | | T |
| | | |
| | | |
| | | |
+------------+------------------------------------+
Thank you