I have 3 div 1 header, Sidebar and main content. I have used flexbox. .main has 100vh height and .sidebar has 100px height and .main-content has 100% height. But it is viewed on mobile then empty space is shown between sidebar and main-content.
.main {
min-height: 100vh;
background-color: red;
display: flex;
flex-wrap: wrap;
}
.sidebar {
background-color: blue;
height: 100px;
width: 100%;
}
.main-content {
background-color: yellow;
height: 100%;
width: 100%;
}
#media (min-width: 768px) {
.main-content{
width: 80%;}
.sidebar {
width: 20%
}
}
<div>Header</div>
<div class="main">
<div class="sidebar">
sidebar
</div>
<div class="main-content">
main-content
</div>
</div>
You need to add flex-direction: column to main. And use flex-grow: 1 to main-content so it covers the remaining space ( if you want that )
The default property value is row. So main and sidebar are side by side and equal in height which is equal to the height of their container( default flex behavior )
.main {
min-height: 100vh;
background-color: red;
display: flex;
flex-wrap: wrap;
flex-direction:column;
}
.sidebar {
background-color: blue;
height: 100px;
width: 100%;
}
.main-content {
background-color: yellow;
flex-grow:1;
width: 100%;
}
#media (min-width:768px) {
.main-content{
width: 80%;}
.sidebar {
width: 20%
}
.main {
flex-direction:row;
}
}
<div>Header</div>
<div class="main">
<div class="sidebar">
sidebar
</div>
<div class="main-content">
main-content
</div>
</div>
Try this
#media (min-width: 768px) {
.main-content,
.sidebar {
width: 100%
height: 100%
}
}
For a height setting with a percentage value ( as in .sidebar and .main-content) the parent element of these (.main) needs to have a height setting defined, as a reference for their percentage value. min-height isn't sufficient in this case.
So, in .main, you could change min-height: 100vh to height: 100vh and add overflow-y: visible to allow it to get larger.
.main {
height: 100vh;
overflow-y:visible;
background-color: red;
display: flex;
flex-wrap: wrap;
}
.sidebar {
background-color: blue;
height: 100px;
width: 100%;
}
.main-content {
background-color: yellow;
height: 100%;
width: 100%;
}
#media (min-width: 768px) {
.main-content{
width: 80%;}
.sidebar {
width: 20%
}
}
<div>Header</div>
<div class="main">
<div class="sidebar">
sidebar
</div>
<div class="main-content">
main-content
</div>
</div>
Just remove "min-height: 100vh;" from the .main and your problem will be solved! :)
Related
I am trying to create a responsive navigation bar, similar to the one on Stack Overflow. I have attached an image of the layout I'm trying to achieve.
For simplicity, I added some values to make it easier to follow. There is the outer div that encapsulates the whole page, outer-wrapper and the main div that encapsulates the main content (navigation bar, main content, and footer), main-wrapper.
Now suppose that outer-wrapper is 1000px wide and main-wrapper is 800px wide, then there is 100px of buffer on the left and right side. When the window shrinks, I want the buffer to be used up before any of the main content changes.
CSS
.outer-wrapper {
width: 100%;
}
.main-wrapper {
width: 800px;
display: flex;
flex-direction: column;
margin-left: auto;
margin-right: auto;
position: relative;
}
.nav-home {
position: fixed;
top: -30px;
left: -30px;
height: 60px;
width: 100%;
padding: 20px 20px 0px 20px;
display: flex;
justify-content: space-around;
}
}
HTML
<div class='outer-wrapper'>
<div class='main-wrapper'>
<div class='nav-bar'>...</div>
<div class='main-content'>...</div>
<div class='footer'>...</div>
</div>
</div>
The problem is when the window shrinks to match the width of main-wrapper at 800px, there is still a left and right margin in the navigation bar. How would I ensure the width of the navigation bar matches the width of the main content and footer when the left and right margin is shrunk to 0?
Thanks.
I stripped out some of your styles from the .nav-bar class and it seems to be performing as you require - am I missing something?
I've added colours to help visualise the resizing.
.outer-wrapper {
background-color: yellow;
width: 100%;
}
.main-wrapper {
background-color: blue;
width: 800px;
display: flex;
flex-direction: column;
margin-left: auto;
margin-right: auto;
position: relative;
}
.nav-bar {
background-color: red;
justify-content: space-around;
}
.main-content {
background-color: green;
}
.footer {
background-color: purple;
}
<div class='outer-wrapper'>
<div class='main-wrapper'>
<div class='nav-bar'>Nav Bar</div>
<div class='main-content'>Main Content</div>
<div class='footer'>Footer</div>
</div>
</div>
.outer-wrapper {
width: 100%;
}
.main-wrapper {
width: 800px;
display: flex;
flex-flow: row wrap;
font-weight: bold;
text-align: center;
margin: 0 auto;
}
.main-wrapper > * {
padding: 10px;
flex: 1 100%;
}
.nav-bar {
background: tomato;
}
.footer {
background: lightgreen;
}
.main-content {
background: deepskyblue;
}
.aside-1 {
background: gold;
}
.aside-2 {
background: hotpink;
}
#media all and (min-width: 600px) {
.aside {
flex: 1 0 0;
}
}
#media all and (min-width: 800px) {
.main-content {
flex: 3 0px;
}
.aside-1 {
order: 1;
}
.main-content {
order: 2;
}
.aside-2 {
order: 3;
}
.footer {
order: 4;
}
}
body {
padding: 2em;
}
<div class="outer-wrapper">
<div class="main-wrapper">
<nav class="nav-bar">Navbar</nav>
<main class="main-content">content</main>
<aside class="aside aside-1">aside 1</aside>
<aside class="aside aside-2">aside 2</aside>
<footer class="footer">footer</footer>
</div>
</div>
this is the code that I made, hopefully it will help you and what you expect
I'm attempting to create a 2 column layout, with a header and footer. I want the page to initially be full height (100vh), with the ability to expand its height if the content was long.
Here's a CodePen showing part of what I'm attempting to achieve:
https://codepen.io/realslimsutton/pen/eYWzavw
The problem with the above CodePen, is that its height is fixed to 100vh. If I change the height of the container to be min-height: 100vh; instead of height: 100vh;, then the 2 columns reset their height back to 0.
An example of it not working with min-height set can be found at this CodePen: https://codepen.io/realslimsutton/pen/xxdONjO.
I've already tried the following things:
height: 100%; on all child elements of .container .content
align-self: stretch; on all child elements of .container .content
align-items: stretch; on all parent elements inside .container .content
None of the above attempts worked, the columns never filled the height of the parent.
Changed only a couple things. Don't forget the default is display: block
* {
box-sizing: border-box;
}
html, body {
margin: 0;
padding: 0;
}
.container {
min-height: 100vh;
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.container > .header, .container > .footer {
height: 10vh;
width: 100%;
}
.container .header {
background-color: rgb(239, 68, 68);
}
.container .footer {
background-color: rgb(59, 130, 246);
}
.container .content {
/*Line added since the default is block it wasn't working with
flex grow*/
display: flex;
flex-grow: 1;
}
.container .grid {
/*Now that your content "grows" you can inherit its height*/
height: inherit;
width: 100%;
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.container .grid > div {
height: 100%;
width: 100%;
}
.container .grid .left, .container .grid .right {
height: 100%;
width: 100%;
}
.container .grid .left {
background: rgb(16,185,129);
}
.container .grid .right {
background: rgb(139,92,246);
}
<div class="container">
<div class="header"></div>
<div class="content">
<div class="grid">
<div>
<div class="left">
</div>
</div>
<div>
<div class="right">
</div>
</div>
</div>
</div>
<div class="footer"></div>
</div>
I have the following code structure
.parent {
display: flex;
flex-direction: column;
}
.img {
width: 100%
}
.content {
flex: 1;
overflow-y: scroll;
}
.container {
border: 1px solid;
display: flex;
flex-direction:column;
margin:20px;
}
<div class="parent">
<img src="https://www.everythingcarers.org.au/media/1982/sample.jpg"/>
<div class="content">
</div>
<div class="footer">
<div class="container">
<div><button>Button1</button><div>
<div><button>Button2</button><div>
</div>
</div>
</div>
What I want is the footer to occupy its original width and height(height: 144px) , and make the content scrollable based on the available space according to screen resolution.Currently, the footer is getting cut off on some screens. I've tried changing the flex values for content and footer, but it doesn't work.Thanks
If you want to limit your parent to the height of the screen so the footer is always visible, you need to set a height of 100% on your div (and body and html) and also move the image inside your content container (or have a seperate one that will scroll if it too large for the screen)
body,
html {
margin: 0;
height: 100%;
}
.parent {
height: 100%;
display: flex;
flex-direction: column;
}
img {
display:block;
width: 100%
}
.content {
flex: 1;
overflow-y: scroll;
}
.container {
border: 1px solid;
display: flex;
flex-direction: column;
margin: 20px;
}
<div class="parent">
<div class="content">
<img src="https://www.everythingcarers.org.au/media/1982/sample.jpg" />
</div>
<div class="footer">
<div class="container">
<div><button> Button1 </button></div>
<div><button> Button2 </button></div>
</div>
</div>
</div>
I think setting your parent height to 100vh and giving your footer a fixed height should fix it:
https://codepen.io/chrishalley/pen/zbwRMw
body {
margin: 0;
}
.parent {
display:flex;
flex-direction:column;
background-color: orangered;
height: 100vh;
}
.content {
flex: 1;
overflow-y: scroll;
}
img {
width: 300px;
}
.footer {
height: 144px;
}
I have a navbar with a fixed height, underneath a control div with also a fixed height and below that I have another div calendar. calendar is scrollable. I want the calendar height to have the remaining screen height below control and the bottom of the screen. This way the window is not scrollable, only the calendar is scrollable. However setting height: 100% does not work and flex: 1 neither.
This is what I have when I set the height of calendar to a fixed height but as I explained I want the height to be the rest of the screen size.
Any Idea?
.navbar {
height: 50px;
background-color: indianred;
}
.window {
display: flex;
flex-direction: column;
flex: 1;
}
.control {
height: 100px;
background: khaki;
}
.calendar {
height: 200px;
width: 100%;
bottom: 0;
left: 0;
}
.wrapper {
position: relative;
background-color: lightgray;
width: 100%;
height: 100%;
overflow: scroll;
}
.main {
width: 1500px;
height: 1500px;
background-color: rosybrown;
display: flex;
flex-direction: column;
}
<nav class="navbar"></nav>
<div class="window">
<div class="control">
</div>
<div class="calendar">
<div class="wrapper">
<div class="main">
</div>
</div>
</div>
</div>
Run this Code below:
I used height: calc() method full height of the screen minus 150px for nav and controls.
.navbar {
height: 50px;
background-color: indianred;
}
.window {
display: flex;
flex-direction: column;
flex: 1;
}
.control {
height: 100px;
background: khaki;
}
.calendar {
height: calc(100vh - 150px);
width: 100%;
bottom: 0;
left: 0;
}
.wrapper {
position: relative;
background-color: lightgray;
width: 100%;
height: 100%;
overflow: scroll;
}
.main {
width: 1500px;
height: 1500px;
background-color: rosybrown;
display: flex;
flex-direction: column;
}
<nav class="navbar"></nav>
<div class="window">
<div class="control">
</div>
<div class="calendar">
<div class="wrapper">
<div class="main">
</div>
</div>
</div>
</div>
I'd like to achieve the following with CSS only (left is mobile layout, right is desktop after breakpoint):
The challenge here obviously is that from a float point of view the element order changes: on mobile the green item is the second, but on desktop it's the first.
Is this possible to achieve with pure CSS? Possibility would be flex-box but I don't have enough experience to recreate this layout.
#container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 400px; /* 1 */
}
.box {
width: 50%;
}
.box1 {
background-color: lightgreen;
height: 400px;
}
.box2 {
background-color: orangered;
height: 200px;
}
.box3 {
background-color: aqua;
height: 200px;
}
#media (max-width: 600px) {
#container { height: auto; } /* 2 */
.box { width: 100%; }
.box2 { order: -1; } /* 3 */
}
/* purely decorative styles */
.box {
border: 1px solid #ccc;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.5em;
}
* { box-sizing: border-box; }
<div id="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
Notes:
Without a fixed height in a column wrap container, flex items don't know where to wrap. So, for your larger screen, define a height which forces the second item to a new column.
Now you're in a mobile layout and wrapping is no longer necessary. The container needs to be twice the height of the desktop layout. Release the height.
Tell the red box to re-position itself first on the list. (The initial order value for flex items is 0.)
Yes you can do this if you can set fixed height on flex-container. You just need to use flex-direction: column and flex-wrap: wrap and then change order with media-queries.
.content {
display: flex;
flex-wrap: wrap;
flex-direction: column;
}
.a {
height: 200px;
background: #00FF02;
}
.b {
height: 100px;
background: red;
}
.c {
height: 100px;
background: blue;
}
#media(min-width:768px) {
.content {
height: 200px;
}
.content > div {
width: 50%;
}
}
#media(max-width:768px) {
.b {
order: -1;
}
}
<div class="content">
<div class="a">A</div>
<div class="b">B</div>
<div class="c">C</div>
</div>
There is also no-flex solution, fiddle (just replace media-query min-width with whatever breakpoint you consider phone width ends):
HTML:
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
CSS:
div {
width: 50%;
}
.div1 {
background-color: red;
float: right;
height: 200px;
}
.div2 {
background-color: green;
float: left;
height: 400px;
}
.div3 {
background-color: blue;
float: right;
height: 200px;
}
#media (max-width: 500px) {
.div1, .div2, .div3 { width: 100%;}
}