Nesting flexbox layout causes scrollable area to misbehave - html

I've read various questions about scrolling within flexbox but I seem to have a slightly more complicated version of what I've seen. I have an editor that uses flexbox and contains a toolbar with many components that is scrollable, and this works fine on its own. However, on the live site it's wrapped in a parent which is display:flex (for reasons I won't go into but this editor isn't the only component on the page), and as soon as the editor is put within this flex parent its scrollable area becomes full width, pushing the whole page wider than it should be.
In this snippet, all the 'Thumb Example' elements are supposed to be scrollable within their parent .image-thumbs-container respecting the page's overall width:800px limit, but they lay out and push their parent wider than that. But, if you turn off the display:flex of the .product-page element, the scrolling then works. I built this simplified example of just the editor to demonstrate the problem, and it worked fine, took me a while to realise it was a parent element that was causing the error.
[Edit] This snippet may not work as expected within StackOverflow, please see this identical Pen: https://codepen.io/neekfenwick/pen/NWbpqZg
body {
background-color: lightgrey;
}
.page-container {
width: 800px;
background-color: white;
}
.product-page {
display: flex; /* Disable me to make scrolling work */
flex-wrap: wrap;
}
.uploads-container {
text-align: left;
white-space: nowrap;
padding: 5px;
border: 1px solid black;
display: flex;
box-sizing: border-box;
}
.uploads-scroller {
overflow-x: scroll;
flex: 1 1 auto;
overflow-y: hidden;
}
.image-thumbs-container {
border: initial;
}
.image-thumb {
display: inline-block;
width: 100px;
border: solid 2px grey;
border-radius: 5px;
margin-right: 2px;
vertical-align: top;
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="mock.css">
<title>Mockup</title>
</head>
<body>
<div class="page-container">
<div class="product-page">
<div class="unrelated-content">Page contains other content required to layout by flexbox.</div>
<div class="editor">
<div class="uploads-panel">
<div class="uploads-container">
<div class="uploads-file-container">File Upload<br>Widget Goes<br>Here</div>
<div class="uploads-scroller">
<div class="image-thumbs-container">
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
</div>
</div>
</div>
</div>
<div class="workspace">
<h2>Some complicated workspace content goes here.</h2>
</div>
</div>
<div class="unrelated-content">Page contains other content required to layout by flexbox.</div>
</div>
</div>
</body>
</html>
So, please bear in mind I don't want to alter anything above the .editor div. A lot of our site relies on the .product-page CSS. I can consider it, but, is it possible to fix this scrolling problem by only modifying elements from the .editor div and down?

You can fix this one by just setting 100% width on .editor.
Since the parent already has flex-wrap: wrap, this should work out just fine for you. The content below the editor will just wrap to below it.
.editor { /* <-- add this */
width: 100%;
}
body {
background-color: lightgrey;
}
.page-container {
width: 800px;
background-color: white;
}
.product-page {
display: flex; /* Disable me to make scrolling work */
flex-wrap: wrap;
}
.uploads-container {
text-align: left;
white-space: nowrap;
padding: 5px;
border: 1px solid black;
display: flex;
box-sizing: border-box;
}
.uploads-scroller {
overflow-x: scroll;
flex: 1 1 auto;
overflow-y: hidden;
}
.image-thumbs-container {
border: initial;
}
.image-thumb {
display: inline-block;
width: 100px;
border: solid 2px grey;
border-radius: 5px;
margin-right: 2px;
vertical-align: top;
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="mock.css">
<title>Mockup</title>
</head>
<body>
<div class="page-container">
<div class="product-page">
<div class="unrelated-content">Page contains other content required to layout by flexbox.</div>
<div class="editor">
<div class="uploads-panel">
<div class="uploads-container">
<div class="uploads-file-container">File Upload<br>Widget Goes<br>Here</div>
<div class="uploads-scroller">
<div class="image-thumbs-container">
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
<div class="image-thumb">Thumb<br>Example</div>
</div>
</div>
</div>
</div>
<div class="workspace">
<h2>Some complicated workspace content goes here.</h2>
</div>
</div>
<div class="unrelated-content">Page contains other content required to layout by flexbox.</div>
</div>
</div>
</body>
</html>

Add width: 100% to your .editor element.
Or, just in case you really needed to, add max-width: 800px to any of the following elements... .editor, .uploads-container, or .uploads-container

Related

prevent popover from creating scroll in parent (in pure css)

I would like to create a simple popover that displays in place (think about a combobox list below a button). The popover should display over existing elements, i.e. not pre allocate space.
There are many examples using `position: relative -> overflow: hidden -> position: absolute' hierarchy and the work until the popover flows off the bottom of the container, in which case its size affect the parent container and creates a scroll.
Here is a codepen sample. What I'm trying to get is to have no scroll on the rightmost column.
<div class="main">
<div class="column">
<h2>no overflow</h2>
<div class="tall">x</div>
<div class="tall">x</div>
</div>
<div class="column">
<h2>basic overflow</h2>
<div class="tall">x</div>
<div class="tall">x</div>
<div class="tall">x</div>
</div>
<div class="column">
<h2>popover without overflow</h2>
<div class="tall">x</div>
<div class="overlay">
popover should be vislble below
<div class="overflow">
<div class="absolute short">
z
</div>
</div>
</div>
<div class="tall">x</div>
</div>
<div class="column">
<h2>popover with overflow</h2>
<div class="tall">x</div>
<div class="overlay">
popover should be vislble below
<div class="overflow">
<div class="absolute">
z
</div>
</div>
</div>
<div class="tall">x</div>
</div>
</div>
and the scss file:
html, body {
height: 95%;
}
.main {
display: flex;
flex-direction: row;
border: 2px solid red;
height: 100%;
.column {
margin-left: 20px;
height: 100%;
flex: 1;
border: 1px solid black;
overflow-y: auto;
.tall {
height: 300px;
border: 1px solid blue;
}
.overlay {
position: relative;
.overflow {
background: #F00;
overflow: hidden;
.absolute {
opacity: 0.5;
width: 100%;
height: 600px;
position: absolute;
background: #FF0;
&.short {
height: 200px;
}
}
}
}
}
}
I think (if I'm clear about the question) that this issue can be pretty easily resolved by simply substituting the height of your tall class with min-height and max-height If you set the min-height equal to the short height then the popover shouldn't overflow.
I made my own codepen do demonstrate (i adjusted the popover to 100 in height and set the min-height also to 100 for demo) . The code is the same as the code you posted except for the height in the .short class and min-/max-heights in the .tall class. I added overflow:hidden; to the short class in the event that the the height of the content in the popover being greater than the height assigned.
I have commented out the columns with no popovers but feel free to comment them in.
Hope this helps

Troubleshooting CSS Layout

I have built a template to layout what I intend to accomplish. Everything seems to work well with what I have learned from the stackoverflow community.
However, the Footer which is its own container and has "section7" as another DIV is not displaying as 150 pixels in height. Basically all sections have fixed height except for Section 5 and Section 6 which have to scale in height depending on the browser window size or content that will be placed inside the section. So if content is sparse, I just want the height to be 100% of the remaining browser space so that the website is top to bottom. However if there is content that is lengthy obviously I want the middle section to adapt and continue as required. Hope I am making sense.
The challenge is I don't know where I am wrong and thus do not know how to pose the question in the search function as I imagine it is an easy task for those with experience. Any help is appreciated.
The HTML:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Website</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<div class="header">
<div class="section1">section 1</div>
<div class="section2">section 2</div>
<div class="section3">section 3</div>
<div class="section4">section 4</div>
</div>
<div class="middle">
<div class="section5">section 5</div>
<div class="section6">section 6</div>
</div>
<div class="footer">
<div class="section7">section 7</div>
</div>
</div>
</body>
</html>
The CSS:
#charset "utf-8";
/* CSS Document */
body {
margin-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
padding: 0px;
background-color:#DBDBDB
}
div.container {
width: 1200px;
background-color:#FFFFFF;
margin-left:auto;
margin-right:auto;
}
div.header {
height: 100px;
}
div.middle {
min-height: 400;
}
div.footer {
height: 150px;
}
div.section1 {
background-color:#FF0004;
height: 100px;
width: 275px;
float:left;
position:relative;
}
div.section2 {
background-color:#FFA600;
height: 100px;
width: 100px;
float:left;
position:relative;
}
div.section3 {
background-color:#00C304;
height: 50px;
}
div.section4 {
background-color:#DFDD00;
height: 50px;
}
div.section5 {
background-color:#0A00FF;
width: 275px;
height: 400px;
float:left;
height: 100vh;
}
div.section6 {
background-color:#CB05B1;
width: 925px;
height: 400px;
float:right;
height: 100vh;
}
div.section7 {
background-color:#9E9E9E;
height: 150px;
}
Floating elements need to be cleared so that elements following align correctly and do not move into the elements you have floated. Section 5 and Section 6.
Add the following class definition to your stylesheet
.clearfix:before, .clearfix:after {
content: " ";
display: table;
}
Change the following tag <div class="middle"> to <div class="middle clearfix">
HTML5 also includes <header> and <footer> elements, as well as <article> tags to make the document language more semantic. So for HTML5 you can use
<header>
<div class="section1">section 1</div>
<div class="section2">section 2</div>
<div class="section3">section 3</div>
<div class="section4">section 4</div>
</header>
And
<footer>
<div class="section7">section 7</div>
</footer>
https://jsfiddle.net/raythcael/s49o4rjz/2/
To make .section7 have a height of 150px add display: inline-block;
div.section7 {
background-color: #9E9E9E;
height: 150px;
display: inline-block;
}
See: https://jsfiddle.net/zvkxj6v8/
The reason why the height isn't working as it should is because the Div's above it is set to "float". Add "clear: both;" to div.section7 to clear the floats.
https://jsfiddle.net/2L55g0f9/1/
because section 5 and 6 are floated, you're not seeing the height of section 7. All i did was clearfix it, and you got your height :)
.clearfix:after {
clear: both;
content: ".";
display: block;
height: 0;
visibility: hidden;
}
.clearfix {
display: inline-block;
}

How to make a grid span the remaining height of the page

I am just trying to create a basic website using Material Design Light that responds to the size of the screen and I am having trouble making the grid fill all of the available height. I have tried to look for solutions to this problem online but I cant find any that work.
Here is the source code for one the grids I will use:
<main class="mdl-layout__content">
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--4-col" style="text-align:center; background-color:gray;">size 4</div>
<div class="mdl-cell mdl-cell--4-col" style="text-align:center; background-color:gray;">size 4</div>
<div class="mdl-cell mdl-cell--4-col" style="text-align:center; background-color:gray;">size 4</div>
</div>
</main>
Here is a link to the full Html page: Example MDL Page
Here is an image of the problem: Page Example
I'm assuming that your page height is the view height, which you can only use w/ modern browsers. See view height
Basically what we're doing here is we already know how high our footer and header are going to be (in the fiddle i just set it to 50px each). Then we use the calc CSS property to set the view height (vh) to 100% - 100px (meaning the footer and header's height put together (50+50 = 100)
Check the fiddle
<div id="main-body">
<div class="header"></div>
<div class="content clearfix">
<div class="a">1</div>
<div class="a">2</div>
<div class="a">3</div>
<div class="a">4</div>
</div>
<div class="footer"></div>
</div>
* {
box-sizing: border-box; /* add for browser prefixes */
}
#main-body {
height: 100%;
overflow: hidden;
}
.header, .footer {
background-color: blue;
height: 50px;
}
.content .a {
height: calc(100vh - 100px);
background-color: red;
width: 25%;
float: left;
}
.clearfix:after {
content: "";
clear:both;
display:table;
}
Note that you'll also need the viewport meta tag in your <head> for this to work.
<meta name="viewport" content="width=device-width, initial-scale=1">
OP added the he would like the ability to center the text within these content divs
<div id="main-body">
<div class="header"></div>
<div class="content clearfix">
<div class="a"><p>1</p></div>
<div class="a"><p>2</p></div>
<div class="a"><p>3</p></div>
<div class="a"><p>4</p></div>
</div>
<div class="footer"></div>
</div>
#main-body {
height: 100%;
overflow: hidden;
}
.header, .footer {
background-color: blue;
height: 50px;
}
.content .a {
height: calc(100vh - 100px);
background-color: red;
width: 25%;
float: left;
position: relative;
}
.content .a p {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin: 0;
}
.clearfix:after {
content: "";
clear:both;
display:table;
}
Th way I did it was to over-ride a couple of the mdl styles, notably to make main display as flex rather than inline-block. It would probably make sense to add an Id to restrict the impact of this override across the rest of your site
.mdl-layout__content {
display: flex;
flex-direction: column;
.mdl-grid {
width: 100%;
flex-grow: 2;
}
}
Try to fool around with the CSS height attribute. Like so:
<div class="mdl-cell mdl-cell--4-col" style="text-align:center; background-color:gray; height:100%;">size 4</div>
<div class="mdl-cell mdl-cell--4-col" style="text-align:center; background-color:gray; height:100%;">size 4</div>
<div class="mdl-cell mdl-cell--4-col" style="text-align:center; background-color:gray; height:100%;">size 4</div>
More information here: http://www.w3schools.com/cssref/pr_dim_height.asp

Make inline-blocks stretch container horizontally

I want to make it so if the inline blocks inside a container exceed the width of the container they make it stretch rather than dropping down below.
I made a codepen of what I mean: http://codepen.io/anon/pen/pJQWbR
<div class="container">
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
</div>
css
.container{
overflow: scroll;
}
.content{
height: 100px;
margin: 5px;
background: blue;
display: inline-block;
width: 25%;
}
Trying to make the blue boxes all be on one line.
Add
white-space: nowrap
to the container
So container style becomes:
.container{
overflow-x: scroll;
white-space: nowrap;
}
white-space: nowrap means Sequences of whitespace will collapse into a single whitespace. Text
will never wrap to the next line. The text continues on the same line until a < br > tag is encountered
See the link : "http://codepen.io/anon/pen/xGQXRz"
Try this one. Just change the width of .content class.
.container{
overflow: scroll;
}
.content{
height: 100px;
margin: 5px;
background: blue;
display: inline-block;
width: 17%;
}
<div class="container">
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
</div>

Two Sections 100% Height of Parent Div

I have a specific layout that is causing me HUGE headaches. Here is an image:
My goal is to have the "Side panel" ALWAYS equal the height of the container. The "Enrollment Application" section is at 100% height already.
Current Markup
<body>
<div id="container" class="pure-g">
<div class="pure-u-md-1-4 pure-u-1 panel" id="left-panel">
<div class="panel-row">
<div class="panel p">
<div class="inner-panel">
<div class="panel-logo">
"Logo here text"
</div>
</div>
</div>
</div>
<div class="panel-row">
<div class="panel p">
<div class="inner-panel">
<nav class="panel">
</nav>
</div>
</div>
</div>
</div>
<div id="right-panel" class="pure-u-md-3-4 pure-u-1 panel p">
<div class="inner-panel">
<header class="pure-g">
<div class="pure-u-md-1-4 pure-u-1 header-logo">
LOGO Would go here, of course.
</div>
<div class="pure-u-md-3-4 pure-u-1 header-title">
<h1>Consumers Energy</h1>
<h1><strong>CARE 3.0 Program</strong></h1>
<h1>Enrollment Application</h1>
</div>
</header>
<div id="content">
"Enrollment application text..."
</div>
</div>
</div>
</div>
</body>
Current CSS
.panel {
box-sizing: border-box;
height: 100%;
display: table-cell;
}
.panel.p {
padding: 3px;
}
.panel .panel-row {
display: table-row;
}
.panel .inner-panel {
border-radius: 5px;
padding: 10px;
width: 100%;
box-sizing: border-box;
background-color: red;
}
Here is an alternative fiddle to play with: http://jsfiddle.net/3c3tqo3e/ but I really don't want to use a table...
Q How can we stack two divs and make their heights = 100% of parent? The "Logo here.." section will be an auto height.
NOTE I would really prefer an answer that is responsive-friendly. I am using PureCSS for the sections. (This means that absolute positioning is not preferred) Also, strongly prefer just css/html. Thanks!
I have created a demo for you, but it will work on all modern browsers only. and you might have to read flexbox and its demos in details to make your work more meaningful in terms of performance and maintenance.
Also read on calc() here
HTML:
<main>
<aside>
<div class="logo">Logo</div>
<div class="aside-content">Other Content</div>
</aside>
<section>Section</section>
</main>
CSS:
html, body{ height: 100%; }
main{
height: 100%; background: teal; padding: 2em; box-sizing: border-box;
display: flex; flex-direction: row;
}
aside{
height: inherit; margin: 0 1em 0 0; width: 200px;
}
aside .logo{
background: #fff; height: 140px;
}
aside .aside-content{
background: #fff; height: calc(100% - 150px); margin: 10px 0 0 0;
}
main section{
height: inherit; background: #fff; flex-grow: 2;
}
Demo Fiddle: http://jsfiddle.net/vpqqyo9L/1/
Edit:
Here's one for IE9: http://jsfiddle.net/vpqqyo9L/3/