Resize flex item based on its content - css

Sorry, another flexbox related question :)
I have two flex elements :
A container (red) containing a centered div (yellow)
A footer (blue) with an undefined height
The red container has a flex-grow:1 attribute, forcing it to take the remaining space on the screen
The issue happens when the yellow element is bigger than the screen size. I would like my red container to grow based on its content. Any idea of how I could do that ?
HTML:
<div class="container">
<div class="content"></div>
</div>
<div class="footer"></div>
CSS:
body,
html {
margin: 0;
height: 100%;
display: flex;
flex-direction: column;
}
.container {
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center;
background: red;
}
.content {
background: yellow;
height: 2000px;
width: 100px;
}
.footer {
flex-shrink: 0;
height: 50px;
background-color: blue;
}
https://codepen.io/stepinsight/pen/roRVGQ
== EDIT ==
Andre helped me find the answer, thanks heaps !
The only thing you need to change in the code above is to replace height by min-height and the % by vh for the body/html tags 🎉
body,
html {
margin: 0;
min-height: 100vh;
display: flex;
flex-direction: column;
}

Simply remove the height property on the body element and add height: 100% to html
* { box-sizing: border-box; }
html {
height: 100%
}
body {
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
}
.container {
display: flex;
align-items: center;
justify-content: center;
background: red;
}
.content {
background: yellow;
height: 2000px;
width: 100px;
}
.footer {
height: 50px;
background-color: blue;
}
Corrected: https://codepen.io/ferreirandre/pen/maoVvb
Feel free to play around with the height of .content

Related

Sidebar with two flexbox navs top and bottom

I´m trying to align two navigations inside a sidebar –with 100% viewport height – by use of flexbox.
the red box should be placed on the top of it´s sidebar parent
the blue box on the bottom.
In case the red navigation grows and the space between both is to little the sidebar should be scrollable in y-axis. What I´ve tried is setting top and bottom margin for both without luck. Can somebody help me out ?
Thanks!
html, body {
margin: 0;
}
* {
box-sizing: border-box;
}
.sidebar {
height: 100vh;
width: 300px;
background: #ccc;
padding: 10px;
overflow-y: scroll;
}
.sidebar__top {
background: red;
height: 200px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.sidebar__bottom {
background: blue;
height: 100px;
margin-top: auto;
}
<aside class="sidebar">
<nav class="sidebar__top"></nav>
<nav class="sidebar__bottom"></nav>
</aside>
Here is my fiddle: http://jsfiddle.net/1dw7h2sp/1/
There are probably other ways to do this. In short I did the following:
Wrap your elements with a parent that is able to grow in size (.sidebar__wrapper)
Set the min-height instead of height so it can grow
Use flex-grow if you want an element to fill out the remaining space.
html, body {
margin: 0;
}
* {
box-sizing: border-box;
}
.sidebar {
height: 100vh;
width: 300px;
background: #ccc;
overflow-y: scroll;
margin: 0;
padding: 0;
}
/* set up a wrapper that can grow in size */
.sidebar__wrapper {
height: auto;
min-height: 100vh;
width: 100%;
background: #808080;
padding: 10px;
margin: 0;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.sidebar__top {
background: red;
min-height: 200px;
margin-bottom: 10px;
/* this fills up the remaining space */
flex-grow: 1;
}
.sidebar__bottom {
background: blue;
min-height: 100px;
}
<aside class="sidebar">
<div class="sidebar__wrapper">
<nav class="sidebar__top" contenteditable="true">
<p>test</p>
</nav>
<nav class="sidebar__bottom"></nav>
</div>
</aside>

Why flexbox not working responsive design with flex-direction?

i have doing my portfolio but i'm not good with CSS.
I'm using the Flexbox to do the design desktop and mobile but it not working...
It is like this, as i want, using flex-direction: column,:
Code of the div parent:
display: flex;
justify-content:center;
align-items:center;
background-color:#C4C4C4;
min-height: 100vh;
flex-direction: column;
But when i put in responsive, it stay like this:
The elements outside of div parent..
The code is the same, only changes the background-color.
background-color: red;
width:800px;
height:650px;
margin: 30px;
It not stay corrects.
If i dont use the flex-direction: column, it stay like this:
Someone why?
Your main issue was missing max-width: 100%; in the children so the width:800px would not overflow the container parent, take a look at the snippet
section {
display: flex;
justify-content: center;
align-items: center;
background-color: #C4C4C4;
min-height: 100vh;
padding: 15px 30px;
box-sizing: border-box;
}
#media(max-width:800px) {
section {
flex-direction: column;
}
}
div {
max-width: 100%;
width: 800px;
height: 650px;
margin: 15px
}
div:first-of-type {
background-color: red;
}
div:last-of-type {
background-color: blue
}
<section>
<div>red</div>
<div>blue</div>
</section>
max-width not set the width of the children elements.
Make sure you set a width to all of your containers; it looks like you want the gray container to fill the viewport, and the blocks to be evenly distributed.
Here's a working example:
.container {
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
text-align: center;
background-color: gray;
width: 100vw;
height: 100vh;
}
.block {
background-color: #C4C4C4;
min-height: 33vh;
width: 90vw;
}
<div class="container">
<div class="block" style="background-color: red">
A
</div>
<div class="block" style="background-color: blue">
B
</div>
</div>

calculate remaining height using CSS calc()

I need the .content div use all the available space
body {
height: 100%;
}
.nav {
padding: 20px;
}
.content {
height: 100%;
}
<body>
<div class="nav">nav</div>
<div class="content">content</div>
</body>
Since I don't know the height of the .nav I can't use height: calc(100%-Xpx)
is there any other way to make .content use the remaining height of the page?
Thanks
Use min-height: 100vh on body, then set the parent (body in this case) to display: flex; flex-direction: column and use flex-grow: 1 on .content for it to use the available space.
body {
min-height: 100vh;
display: flex;
flex-direction: column;
margin: 0;
}
.nav {
padding: 20px;
}
.content {
flex-grow: 1;
background: #eee;
}
<div class="nav">nav</div>
<div class="content">content</div>

Breaking a line with flexbox centering?

I'm trying to vertically/horizontally center my Title with the Subtitle directly beneath it. Here was my attempt:
html, body, h1 {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
#container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
<div id="container">
<h1>Main Title</h1>
<span>Subtitle</span>
</div>
As you can see, the subtitle is in the same line as the h1, I'm trying to get it to go beneath it. I've tried setting h1 to display: block; but that seems to not work when using display: flex on the container. Any help would be appreciated.
Set flex-direction: column on container
html, body, h1 {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
#container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
}
<div id="container">
<h1>Main Title</h1>
<span>Subtitle</span>
</div>
Setting flex-direction to column is one solution. It's already provided in another answer.
In some cases, if flex-direction: row is preferred (or a necessity), you can add flex-wrap: wrap to the container and give the first item a 100% width, which forces the second item to the next line.
body, h1 {
margin: 0;
padding: 0;
}
#container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
flex-wrap: wrap; /* NEW */
align-content: center; /* NEW */
text-align: center; /* NEW */
}
h1 { flex: 0 0 100%; } /* NEW */
<div id="container">
<h1>Main Title</h1>
<span>Subtitle</span>
</div>

Make flex child element occupy 100% height of parent flex [duplicate]

This question already has answers here:
HTML5 flexible box model height calculation
(2 answers)
Closed 4 years ago.
I have a container flex with content flexes. How do i make content flex occupy full width and height of container flex.
<div id="main">
<div id="main-nav">
</div>
<div class="container">
<div class="content"></div>
<div class="content"></div>
</div>
</div>
#main{
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
}
#main-nav{
width: 100%
height: 50px;
}
.container{
display: flex;
flex-direction: row;
flex-wrap: wrap;
flex: 1;
}
.content{
display: flex;
width: 100%;
height: 100%;
}
The above code makes content to occupy 100% width of container but height is based on the text within the content. I tried the solutions mentioned from similar questions but had no luck and it was still the same.
Basically, I want each of the content to occupy the same height as occupied by the container in the viewport height. I also tried jQuery,
var rht = $("#container").height();
$(".content").height(rht);
It changes the height properly but adds a horizontal scroll bar with increase in width.
After several updates to the original question:
* {
box-sizing: borderbox;
margin: 0;
padding: 0;
}
#main {
display: flex;
flex-direction: column;
border: 1px solid red;
min-height: 100vh;
}
#main-nav {
flex: 0 0 50px;
}
.container {
display: flex;
flex-direction: column;
flex: 1;
border: 1px solid green;
}
.content {
flex: 1;
border: 1px solid orange;
}
<div id="main">
<div id="main-nav"></div>
<div class="container">
<div class="content"></div>
<div class="content"></div>
</div>
</div>
JSfiddle Demo
You cannot set width or height of flex's child is bigger (size of flex)/(number of flex's childs) but you can add position: absolute into .content and position: relative into .container then set width and height for .content. First .content is under second .content, you can use propety z-index or display: none to control.
* {
box-sizing: borderbox;
margin: 0;
padding: 0;
}
#main {
display: flex;
flex-direction: column;
background: red;
min-height: 100vh;
}
#main-nav {
flex: 0 0 50px;
}
.container {
position: relative;
display: flex;
flex: 1;
background: green;
}
.content {
position: absolute;
left: 0px;
top: 0px;
height: 100%;
width: 100%;
flex: 1;
background: orange;
}
<div id="main">
<div id="main-nav"></div>
<div class="container">
<div class="content">left</div>
<div class="content">right</div>
</div>
</div>

Resources