Flexbox nested container not expanding to fill parent in safari - html

I am trying to make a nested 100% screen layout but I am running into a problem where the nested container does not fill 100% of the space of the parent cell in safari, even tho the cell itself does expand to fill all the available space. If I make the subContainer the actual flex cell as well it works, but I canĀ“t do that for practical reasons. Any ideas?
jsfiddle
HTML:
<div id="masterContainer">
<div id="header">
header
</div>
<div id="content">
<div id="subContainer">
<div id="left">
left
</div>
<div id="right">
right
</div>
</div>
</div>
</div>
CSS:
#masterContainer {
display: flex;
flex-direction: column;
width: 200px;
height: 200px;
}
#header {
background: yellow;
}
#content {
background: grey;
flex: 1;
}
#subContainer {
display: flex;
width: 100%;
height: 100%;
}
#left {
background: red;
width: 50;
}
#right {
background: green;
flex: 1;
}

This is a workaround for this problem in Safari.
Since Safari seems to avoid calculation for non-flex nested containers.
Take a look to this answer
#masterContainer {
display: flex;
flex-direction: column;
width: 200px;
height: 200px;
}
#header {
background: yellow;
}
#content {
background: grey;
flex: 1;
position: relative;
}
#subContainer {
display: flex;
width: 100%;
height: 100%;
position: absolute;
}
#left {
background: red;
width: 50px;
}
#right {
background: green;
flex: 1;
}
<div id="masterContainer">
<div id="header">
header
</div>
<div id="content">
<div id="subContainer">
<div id="left">
left
</div>
<div id="right">
right
</div>
</div>
</div>
</div>

Related

Overflow block inside flex column without min-width breaks max-width of parent wrapper

I need to place block with overflowed content inside flex column (flex-grow:1) and not to break parent wrapper max-width.
Im unable to change flex styles (so I cant set flex column min-width:0), Im able to edit only the content inside flex column.
Any thoughts?
.wrapper {
max-width: 800px;
background-color: grey;
}
.flex {
display: flex;
}
.column1 {
width: 200px;
height: 100px;
flex-shrink: 0;
background-color: green;
}
.column2 {
flex-grow: 1;
background-color: red;
/* min-width: 0; */
}
.overflow {
max-width: 100%;
overflow: auto;
}
.wideContent {
height: 100px;
width: 2500px;
}
<div class="wrapper">
<div class="flex">
<div class="column1"></div>
<div class="column2">
<div class="overflow">
<div class="wideContent"></div>
</div>
</div>
</div>
</div>
Use min-width: 100%;width: 0; on the overflow element:
.wrapper {
max-width: 800px;
background-color: grey;
}
.flex {
display: flex;
}
.column1 {
width: 200px;
height: 100px;
flex-shrink: 0;
background-color: green;
}
.column2 {
flex-grow: 1;
background-color: red;
}
.overflow {
min-width: 100%;
overflow: auto;
width: 0;
}
.wideContent {
height: 100px;
width: 2500px;
}
<div class="wrapper">
<div class="flex">
<div class="column1"></div>
<div class="column2">
<div class="overflow">
<div class="wideContent"></div>
</div>
</div>
</div>
</div>

Visible overflow on X axis, but auto/scroll on axis Y

To keep things neat and short:
https://jsfiddle.net/m53ockLu/
.container {
max-height: 500px;
background: grey;
}
.sidebar {
height: 100vh;
width: 150px;
overflow-x: scroll;
overflow-y: auto;
background: red;
}
.element {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
margin: 5px;
height: 200px;
width: 20px;
background: green;
}
.first {
position: relative;
display: block;
height: 20px;
width: 100px;
background: pink;
}
.second {
display: inline-block;
}
.second-absolute {
position: absolute;
height: 20px;
width: 250px;
background: purple;
}
<div class="container">
<div class="sidebar">
<div class="element">
<div class="first"></div>
<div class="second">
<div class="second-absolute"></div>
</div>
</div>
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
</div>
Is it possible to keep the red container scrollable on vertical axis, and at the same time make the purple (.second-absolute) element overflow this red container horizontally? I'm totally out of ideas, I thought that overflow-x & overflow-y should do the trick, but no dice.
Thank you very much for any help.
Is it possible to keep the red container scrollable on vertical axis, and at the same time make the purple (.second-absolute) element overflow this red container horizontally?
No.
I tried Ethan's suggestion and couldn't get the purple box to visibly overflow the scrollbar:
.container {
max-height: 500px;
background: grey;
}
.sidebar {
height: 100vh;
width: 150px;
overflow-y: scroll;
background: red;
}
.element {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
margin: 5px;
height: 200px;
width: 20px;
background: green;
}
.first {
position: relative;
display: block;
height: 20px;
width: 100px;
background: pink;
}
.second {
display: inline-block;
}
.second-absolute {
position: absolute;
height: 20px;
width: 250px;
background: purple;
}
<div class="container">
<div class="sidebar">
<div class="element">
<div class="first"></div>
<div class="second">
<div class="second-absolute"></div>
</div>
</div>
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
</div>
I don't think the browser will let you overflow the scrollbar, I even put z-index, explicitly said to visibly overflow, played around with the position property etc.
Consider this example of letting the content dictate the size:
.container {
max-height: 500px;
background: grey;
}
.sidebar {
height: 100vh;
width: max-content;
overflow-y: auto;
background: red;
}
.element {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
margin: 5px;
height: 200px;
background: green;
}
.first {
display: block;
height: 20px;
background: pink;
}
.second {
display: inline-block;
}
.second-absolute {
height: 20px;
width: 250px;
background: purple;
}
<div class="container">
<div class="sidebar">
<div class="element">
<div class="first"></div>
<div class="second">
<div class="second-absolute"></div>
</div>
</div>
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
</div>
You made the parent div sidebar have overflow-x: scroll;, overflow-y: auto;. Instead, make each child have its own overflow properties instead of the parent.

Header, footer and scrollable content with inner footer and full height scrollbar

I am trying to have a header/footer and a scrollable div#middle. Within the scrollable div, another (inner) footer div#middle-bottom should be placed at the bottom of div#used-for-swipe-animation and always be visible.
This is my current code using flex-container (using flex is not a requirement):
html, body {
margin: 0
}
.wrapper {
display: flex;
flex-direction: column;
height: 100vh;
width: 100%;
overflow-y: auto;
}
.top {
background: lightgreen;
}
.middle {
flex-grow: 1;
overflow: auto;
}
.middle-bottom {
background: red;
}
.bottom {
background: lightblue;
}
<body>
<div class="wrapper">
<div class="top">top</div>
<div id="used-for-swipe-animation">
<div class="middle">
middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle
</div>
<div class="middle-bottom">
middle-bottom<br>middle-bottom<br>middle-bottom<br>middle-bottom<br>
</div>
</div>
<div class="bottom">bottom</div>
</div>
</body>
Problem: Without the div#used-for-swipe-animation it works as expected. However, as the id suggests, div#used-for-swipe-animation is needed to perform some animation.
Nice-to-Have: Is it possible to have the scrollbar of div#middle to be displayed over full height of div#wrapper?
As per I understand your Que, you need fixed Header & Footer and scroll div in middle
html,
body {
margin: 0
}
.wrapper {
display: flex;
flex-direction: column;
height: 100vh;
width: 100%;
overflow-y: auto;
}
.top {
position: fixed;
top: 0;
width: 100%;
height: 30px;
background: lightgreen;
}
.main_center {
margin: 30px 0;
}
.middle {
flex-grow: 1;
overflow: auto;
}
.middle-bottom {
background: red;
}
.bottom {
position: fixed;
bottom: 0;
width: 100%;
height: 30px;
background: lightblue;
}
<body>
<div class="wrapper">
<div class="top">top</div>
<div id="used-for-swipe-animation" class="main_center">
<div class="middle">
middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle<br>middle
</div>
<div class="middle-bottom">
middle-bottom<br>middle-bottom<br>middle-bottom<br>middle-bottom<br>
</div>
</div>
<div class="bottom">bottom</div>
</div>
</body>
Replay can lead perfection :)

child container still go outside of parent 100vh

This is sort of a two in problem.
I have a body with height: 100vh similar to how my example is in the jsFiddle (except in there I put 20vh.
I have a similar structure as this, where the innerRight container can be quite large compared to the rest of the content, and only that conatiner is to obtain it's own scroll bar. I sort of got this working in my main project, but the outer container (similar to how I displayed outer in the example) still expands past the the parents height container main. Be it 100vh, or 20vh it doesn't matter it doesn't stay within with display:flex.
.main {
height: 20vh;
}
.outer {
display: flex;
overflow: hidden;
}
.innerLeft {
height: 200px;
width: 50px;
display: flex;
flex-direction: column;
flex-grow: 1;
background-color: green;
}
.innerRight {
overflow: auto;
height: 500px;
background-color: red;
width: 100%;
}
<div class="main">
<div class="header">
some random text
</div>
<div class="outer">
<div class="innerLeft">
</div>
<div class="innerRight">
</div>
</div>
</div>
Can you please check the below code? Hope it will work for you.
You have to set height:100vh; in .main and set width:calc(100% - 50px); to .innerRight.
Remove height from innerleft and innerright element.
Please refer to this link: https://jsfiddle.net/yudizsolutions/9Lsyzg64/1/
body {
margin: 0;
}
.main {
height: 100vh;
}
.outer {
display: flex;
height: calc(100vh - 19px);
overflow: hidden;
}
.innerLeft {
width: 50px;
background-color: green;
}
.innerRight {
overflow: auto;
background-color: red;
width: calc(100% - 50px);
}
<div class="main">
<div class="header">
some random text
</div>
<div class="outer">
<div class="innerLeft">
</div>
<div class="innerRight">
</div>
</div>
</div>
You need to set height to outer class.
.main {
height: 20vh;
}
.outer {
display: flex;
height: 200px;
overflow:hidden;
}
.innerLeft {
width: 50px;
display: flex;
flex-direction: column;
flex-grow: 1;
background-color: green;
}
.innerRight {
overflow: auto;
height: 500px;
background-color: red;
width:100%;
}
<div class="main">
<div class="header">
some random text
</div>
<div class="outer">
<div class="innerLeft">
</div>
<div class="innerRight">
</div>
</div>
</div>

How can I put two <div> that has the same width and height next to each other without having to scroll?

I'm currently making a simple html page with two sections with content inside of each of them but the last content of the second div .right is going on the bottom of the page and make the page scrollable.
I tried making another div and put a flex-direction: column but it doesn't work:
body {
margin: 0;
}
.main-container {
display: flex;
flex-direction: column;
}
.left {
background: #ecece9;
width: 50%;
height: 100vh;
}
.right {
background: #ffffff;
width: 50%;
height: 100vh;
}
<div class="main-container">
<div class="left">
<h2>content</h2>
</div>
<div class="right">
<h2>content should be on top</h2>
</div>
</div>
How can I put two <div> that has the same width and height next to each other without having to scroll?
You need to use flex-direction: row and not flex-direction: column.
To avoid repeating width: 50%; height: 100vh; for both .left and .right, I would also create another class, such as .box, which is applied to both and contains these properties.
body {
margin: 0;
}
.main-container {
display: flex;
flex-direction: row;
}
.box {
width: 50%;
height: 100vh;
}
.left {
background: #ecece9;
}
.right {
background: #ffffff;
}
<div class="main-container">
<div class="left box">
<h2>content</h2>
</div>
<div class="right box">
<h2>content should be on top</h2>
</div>
</div>
Change the flex direction from column to row
body {
margin: 0;
}
.main-container {
display: flex;
flex-direction: row;
}
.left {
background: #ecece9;
width: 50%;
height: 100vh;
}
.right {
background: #ffffff;
width: 50%;
height: 100vh;
}
<div class="main-container">
<div class="left">
<h2>content</h2>
</div>
<div class="right">
<h2>content should be on top</h2>
</div>
</div>
Use CSS Grid to build Layouts it is very powerful. See I changed only two lines and the layout is ready.
.main-container {
display: grid;
grid-template-columns: 50% 50%
}
body {
margin: 0;
}
.main-container {
display: grid;
grid-template-columns: 50% 50%
}
.left {
background: #ecece9;
height: 100vh;
}
.right {
background: #ffffff;
height: 100vh;
}
<div class="main-container">
<div class="left">
<h2>content</h2>
</div>
<div class="right">
<h2>content should be on top</h2>
</div>
</div>
Try only display flex on large screen and and block on mobile
body {
margin: 0;
}
.main-container {
display: flex;
}
.left {
background: #ecece9;
width: 50%;
height: 100vh;
padding:20px;
}
.right {
background: #ddd;
width: 50%;
height: 100vh;
padding:20px;
}
/* For mobile screen
#media only screen and (max-width: 768px) {
.main-container{
display: block;
}
.left, .right{
width: 100%;
}
}
*/
<div class="main-container">
<div class="left">
<h2>content</h2>
</div>
<div class="right">
<h2>content should be on top</h2>
</div>
</div>