Prevent element from overflowing container - html

I have the following structure, where the number of names (.name) in .list is dynamic. What i would like to achieve is when content (depending on n of .names) is longer than .parent's fixed height, both .children fit inside the .parent (inherit height). Lack of space would be solved with .list getting a scrollbar (overflow:auto).
Height inheritance works well with single child, but I am having huge problems when there are two or more.
JSFIDDLE HERE
HTML
<div id="grandparent">
<div id="parent">
<div id="list" class="children">
<div class="name">john</div>
<div class="name">mike</div>
<div class="name">jack</div>
<div class="name">terry</div>
</div>
<div id="footer" class="children">
<div>footer</div>
</div>
</div>
</div>
CSS
body, html {
margin: 0;
width: 100%;
height: 100%;
}
div {
box-sizing: border-box;
}
#grandparent {
background-color:yellow;
display:flex;
align-items:center;
width:100%;
height: 100%;
flex: 1;
}
.children, .children div {
padding: 5px;
}
.children {
max-height: inherit;
}
.children div {
width: 100%;
max-height: inherit;
}
#list {
overflow: auto;
padding-bottom:0;
}
#footer {
padding-top:0;
}
.name {
background-color: green;
}
#footer div {
background-color: pink;
}
#parent {
background-color: blue;
margin: 0 auto;
max-height: 100px;
}
P.S. sorry for the code mess, i was just testing out different options.

Add this to your code:
#parent {
display: flex;
flex-direction: column;
}
body,
html {
margin: 0;
width: 100%;
height: 100%;
}
div {
box-sizing: border-box;
}
#grandparent {
background-color: yellow;
display: flex;
align-items: center;
width: 100%;
height: 100%;
flex: 1;
}
.children,
.children div {
padding: 5px;
}
.children {
max-height: inherit;
}
.children div {
width: 100%;
max-height: inherit;
}
#list {
overflow: auto;
padding-bottom: 0;
}
#footer {
padding-top: 0;
}
.name {
background-color: green;
}
#footer div {
background-color: pink;
}
#parent {
background-color: blue;
margin: 0 auto;
max-height: 100px;
/* new */
display: flex;
flex-direction: column;
}
<div id="grandparent">
<div id="parent">
<div id="list" class="children">
<div class="name">john</div>
<div class="name">mike</div>
<div class="name">jack</div>
<div class="name">terry</div>
</div>
<div id="footer" class="children">
<div>footer</div>
</div>
</div>
</div>
jsFiddle demo
Because flex items are set to flex-shrink: 1 by default, they will reduce their size in order to not overflow the container.

Related

Fitting everything within a static flex column

I am trying to fit 4 divs within the view bounds of a non-scrolling column flexbox but I can't seem to get it working.
What I want:
What I experience:
I have no idea what I am doing and just randomly permutating flex-related CSS fields to try and fix it haha. If someone could point out what is wrong I would love you forever.
Here is the gist of my code:
body {
overflow: hidden;
margin: 0;
width: 100%;
height: 100%;
}
#flexcontent {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
#header #firstContent #secondContent {
flex: 1 1 auto;
}
#header {
background-color: green;
font-weight: 700;
align-content: center;
font-size: 7rem;
}
#firstContent {
background-color: red;
}
#secondContent {
background-color: yellow;
}
#picture {
background-color: blue;
flex: 0 1 auto;
}
<body>
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg"/></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>
</body>
Try this below. And use object-fit if image doesn't expand or shrink as expected or aspect ratio changes.
#flexcontainer {
display: flex;
flex-direction: column;
height: 100vh;
}
#picture {
flex: 1;
min-height: 0;
}
body {
margin: 0;
}
img {
object-fit: contain;
height: 100%;
width: auto;
}
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" /></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>
Please check your container div id
<div id="flexcontainer">
change
#flexcontent {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
to
#flexcontainer {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
try object-fit for img
img {
object-fit: contain;
height: 100%;
}
there is a few thing to fix in your CSS, typo and value used
html, /* to inherit height */
body {
margin: 0;
width: 100%;
height: 100%;
}
#flexcontainer {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
min-height: 0; /* force size calculation*/
}
#header,/* you meant each one of them */
#firstContent,
#secondContent {
flex: 1;
margin: 2px 5vw;/* for demo */
}
#header {
background-color: green;
font-weight: 700;
/* align-content: center; or did you forget display:flex here */
font-size: calc(1rem + 2vw);
}
#firstContent {
background-color: red;
}
#secondContent {
background-color: yellow;
}
#picture {
display: flex;
min-height: 0; /* force size calculation*/
}
img {
max-height: 90%;/* whatever */
margin: auto;/* or align-content + justify-content : center on flex parent*/
}
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" /></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>
Allow the item holding the image to shrink below its content size.
Define the parameters of the image.
(Tested in Chrome, Firefox and Edge.)
#flexcontainer {
display: flex;
flex-direction: column;
height: 100vh;
}
#picture {
min-height: 0;
background-color: blue;
}
#picture>img {
width: 100%;
max-height: 100%;
object-fit: contain;
}
#header {
background-color: green;
font-weight: 700;
font-size: 7rem;
}
#firstContent {
background-color: red;
}
#secondContent {
background-color: yellow;
}
body {
margin: 0;
}
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" /></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>
jsFiddle demo
I've tidied up your html a little and simplified the CSS. You want to take the overflow: hidden off of the body tag, and give each of your elements a class instead of an id. Finally, simplify the image section by making the image tag itself a flexbox item:
html,
body {
height: 100%
}
body {
/*overflow: hidden;*/
margin: 0;
}
.flexContainer {
display: flex;
flex-direction: column;
height: 100%;
}
.flexContainer__header,
.flexContainer__firstContent,
.flexContainer__secondContent {
flex: 1 1 auto;
}
.flexContainer__header {
background-color: green;
font-weight: 700;
align-content: center;
font-size: 7rem;
}
.flexContainer__firstContent {
background-color: red;
}
.flexContainer__secondContent {
background-color: yellow;
}
.flexContainer__picture {
display: block;
width: 100%;
}
<div class="flexContainer">
<div class="flexContainer__header">Title</div>
<img class="flexContainer__picture" src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" />
<div class="flexContainer__firstContent">first</div>
<div class="flexContainer__secondContent">second</div>
</div>

Flexbox element height 100% going outside of parent?

So because of design reasons I had to use flexbox here and I needed the btn p elements to act like display block, which I managed to through another stack post, but now when I make the "other divs" class 100%, it goes out of the main parent, I cannot figure out why?
#outterWrapper {
display: inline-block;
height: 200px;
border: 1px solid red;
}
#container {
display: flex;
height: 200px;
flex-wrap: wrap;
}
#menu {
display: flex;
flex-basis: 100%;
}
#menu p {
margin: 0;
padding: 8px;
padding-bottom: 0;
}
.otherDivs {
height: 100%;
width: 25%;
background-color: grey;
margin-right: 5px;
}
<div id="outterWrapper">
<div id="container">
<div id="menu">
<p>Btn</p>
<p>Btn</p>
<p>Btn</p>
</div>
<div class="otherDivs"></div>
</div>
</div>
As from the example above the grey box goes outside of the red border?
You can switch to column direction and have something like this :
#outterWrapper {
display: inline-block;
height: 200px;
border: 1px solid red;
}
#container {
display: flex;
height: 200px;
flex-direction:column;
}
#menu {
display: flex;
}
#menu p {
margin: 0;
padding: 8px;
padding-bottom: 0;
}
.otherDivs {
height: 100%;
width: 25%;
background-color: grey;
margin-right: 5px;
}
<div id="outterWrapper">
<div id="container">
<div id="menu">
<p>Btn</p>
<p>Btn</p>
<p>Btn</p>
</div>
<div class="otherDivs"></div>
</div>
</div>

canvas having odd behaviour with width and height

So I'm having some issues using <canvas>. It's taking up too much room when at 100% height and width and when it's set at only 100% height, it still causes and overflow for some reason.
Examples
With width and height at 100%, canvas takes up way too much room
.flex {
display: flex;
flex-direction: column;
height: 100vh;
}
.upper {
background-color: blue;
height: 10%;
}
.lower {
flex: 1;
background-color: orange;
}
html, body {
padding: 0;
margin: 0;
}
canvas {
height: 100%;
width: 100%;
background-color: red;
padding: 0;
margin: 0;
}
.inner {
width: 100%;
height: 100%;
background-color: yellow;
position: relative;
}
<div class="flex">
<div class="upper">
</div>
<div class="lower">
<div class='inner'>
<canvas></canvas>
</div>
</div>
</div>
Here, canvas is set at 100% height, yet it causes an overflow for some reason.
.flex {
display: flex;
flex-direction: column;
height: 100vh;
}
.upper {
background-color: blue;
height: 10%;
}
.lower {
flex: 1;
background-color: orange;
}
html, body {
padding: 0;
margin: 0;
}
canvas {
height: 100%;
background-color: red;
padding: 0;
margin: 0;
}
.inner {
width: 100%;
height: 100%;
background-color: yellow;
}
<div class="flex">
<div class="upper">
</div>
<div class="lower">
<div class='inner'>
<canvas></canvas>
</div>
</div>
</div>

How to make inner div of Flexbox height of parent

I am using the flexbox to lay out a web app. It works, except for the main content area. The "router-view" is the expected full height. But the div inside of this is NOT full height of the router-view?
How do I make the div with id of "make-full-height" full height?
I have tried setting the height to 100%, but this has no effect.
html
<div class="full-screen flex-container-column">
<div class="header no-flex">
Fixed Header
</div>
<!--The router-view IS full height-->
<router-view class="flexible">
<div id="make-full-height">
How do I make this div full height?
</div>
</router-view>
<div class="footer no-flex">
Fixed Footer
</div>
</div>
css
.full-screen {
height: 100vh;
}
.flex-container-column {
display: flex;
flex-direction: column;
}
.no-flex {
flex: 0 0 auto;
overflow: auto;
}
.footer {
height: 30px;
background: #555;
color: white;
}
.header{
height: 50px;
background: #555;
color: white;
}
.flex-container {
flex: 1 1 auto;
display: flex;
overflow: hidden;
}
.left, .right {
width: 200px;
background: #eee;
}
.flexible {
flex: 1 1 auto;
}
Set the <router-view to have display: flex, and set flex:1 for the #make-full-height. This way #make-full-height will fill it's container since there are no other children.
.full-screen {
height: 100vh;
}
.flex-container-column {
display: flex;
flex-direction: column;
}
.no-flex {
flex: 0 0 auto;
overflow: auto;
}
.footer {
height: 30px;
background: #555;
color: white;
}
.header{
height: 50px;
background: #555;
color: white;
}
.flex-container {
flex: 1 1 auto;
display: flex;
overflow: hidden;
}
.left, .right {
width: 200px;
background: #eee;
}
.flexible {
flex: 1 1 auto;
background-color: #88F;
display: flex;
}
#make-full-height {
flex : 1;
background-color: #8F8;
}
<div class="full-screen flex-container-column">
<div class="header no-flex">
Fixed Header
</div>
<!--The router-view IS full height-->
<router-view class="flexible">
<div id="make-full-height">
How do I make this div full height?
</div>
</router-view>
<div class="footer no-flex">
Fixed Footer
</div>
</div>

How to make inner div full height with unknown height parent?

I need .col to be 100% of .row height but you can see that the second .col falls short. How can I get this to work without using any "magic numbers"?
http://jsfiddle.net/b21g6fme/
.row {
position: relative;
background: #f99;
}
.col {
margin: 0 0 0 8px;
display: inline-block;
width: 40%;
position: relative;
vertical-align: top;
background: #999;
height: 100%;
}
.col:first-child {
margin: 0;
}
.item {
display: block;
position: relative;
top: 0;
margin: 12px 0 0 0;
min-height: 80px;
width: 100%;
outline: 4px solid black;
}
.item:first-child {
margin: 0;
}
.item.large {
min-height: 120px;
height: 100%;
}
.item.red {
background: #f00;
}
.item.blue {
background: #0f0;
}
.item.green {
background: #00f;
}
<div class="row">
<div class="col">
<div class="item red"></div>
<div class="item blue"></div>
</div>
<div class="col">
<div class="large item green"></div>
</div>
</div>
This can be achieved by using flexbox:
Add display: flex; to .row. This tells its children to use the flexbox model
Add flex-direction: row; to .row as we want the children to align horizontally
Add display: flex; to .col. This tells its children to use the flexbox model
Add flex-direction: column; to .col as we want the children to align vertically
Add flex: 1; to .item to allow it to grow and fill the available space if required
A number of styles can be removed from your original version as they are no longer required when using flexbox
.row {
background:#f99;
display: flex;
flex-direction: row;
}
.col {
background: #999;
display: flex;
flex-direction: column;
margin:0 0 0 12px;
width:40%;
}
.col:first-child {
margin:0;
}
.item {
flex: 1;
margin: 12px 0 0 0;
min-height: 80px;
outline:4px solid black;
width: 100%;
}
.item:first-child {
margin:0;
}
.item.red {
background:#f00;
}
.item.blue {
background:#0f0;
}
.item.green {
background:#00f;
}
<div class="row">
<div class="col">
<div class="item red"></div>
<div class="item blue"></div>
</div>
<div class="col">
<div class="large item green"></div>
</div>
</div>
flexbox support is pretty good, although it isn't supported by older versions of IE. http://caniuse.com/#feat=flexbox
You can do it via flexbox if you don't care about any IE below 11.
I showed how it can be done here.
.row {
position: relative;
background:#f99;
display: flex;
}
.col {
margin:0 0 0 8px;
display:inline-block;
width:40%;
position: relative;
vertical-align:top;
background: #999;
}
.col:first-child {
margin:0;
}
.col:last-child {
display:flex;
}
.item {
display:block;
position: relative;
top:0;
margin: 12px 0 0 0;
min-height: 80px;
width: 100%;
outline:4px solid black;
}
.item:first-child {
margin:0;
}
.item.large {
min-height:120px;
}
.item.red {
background:#f00;
}
.item.blue {
background:#0f0;
}
.item.green {
background:#00f;
}
Here is the simplified CSS table layout, the trick is set the full height div to absolute position with top and bottom both set to 0.
JsFiddle Demo
.row {
display: table;
}
.col {
display: table-cell;
vertical-align: top;
position: relative;
}
.item.large {
position: absolute;
top: 0;
bottom: 0;
}
.item.red {
background: red;
}
.item.blue {
background: blue;
}
.item.green {
background: green;
}
<div class="row">
<div class="col">
<div class="item red">r<br/>e<br/>d</div>
<div class="item blue">blue</div>
</div>
<div class="col">
<div class="large item green">green</div>
</div>
</div>
Children item height in percentage value will only work if parent item have height defined.
Otherwise you can achieve it with jQuery
$(".col").height($(".row").height());
Try out this
.large.item {
height:100%;
}
If you can make the parent relative positioned, and the child absolute possitioned, giving the child a value of 0 for top an bottom will make it stretch to the parents full height.