CSS flex filling 100% of vertical space - html

There is a layout, the scroll is disabled for the parent element and the height is set to 100%.
<https://codepen.io/cefiro/pen/LYBjBmm>
In order for flex to fill 100% of the vertical space, you need to remove "height: 100%" from the parent tags.
But I can't do this, because scrolling is disabled for the parent elements and enabled in the child with the ".content" class
Problem
If there is a way around this without changing the HTML layout markup?
html, body, .app {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
overflow: hidden;
}
.app {
display: flex;
flex: 1 1 auto;
max-height: 90%;
max-width: 90%;
}
.sidebar {
background: green;
width: 40px;
color: #fff;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
}
.sidebar .logo {
flex: 0 0 auto;
height: 50px;
display: flex;
align-items: center;
}
.sidebar .logo > span {
border: 1px solid #fff;
border-radius: 50%;
width: 1em;
}
.sidebar .menu {
flex: 1 0 auto;
writing-mode: vertical-rl;
letter-spacing: 0.5em;
text-transform: uppercase;
}
.main {
display: flex;
flex-direction: column;
background: gray;
width: 100%;
}
.main .top-bar {
flex: 0 0 50px;
display: flex;
align-items: center;
justify-content: center;
background: pink;
}
.main .content {
display: flex;
overflow: auto;
}
.main .content .left-side {
flex: 0 0 10em;
background: orange;
margin-right: 2em;
}
.main .content .right-side {
flex: 1 0 auto;
background: white;
min-width: 110%;
}
<html>
<head></head>
<body>
<div class="app">
<div class="sidebar">
<div class="logo"><span>L</span></div>
<div class="menu">menu items</div>
</div>
<div class="main">
<div class="top-bar">TOP BAR</div>
<div class="content">
<div class="left-side">
Left Side Area
</div>
<div class="right-side">
Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br />
</div>
</div>
</div>
</div>
</body>
</html>

Is this what you're looking for? I've changed the height of the content to 100% to fill the container then used overflow-y scroll on the right side to give you the scroll bar for this element only. The min-width:110% on your right side wasn't doing anything other than overflowing your content and adding an x scrollbar so I've removed it. Your content doesn't overflow in to your gray section now. Marked up css below:
If it's not what you're looking for then pop me a comment and I'll tweak accordingly.
html,
body,
.app {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
overflow: hidden;
}
.app {
display: flex;
flex: 1 1 auto;
max-height: 80%;
max-width: 50%;
}
.sidebar {
background: green;
width: 40px;
color: #fff;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
}
.sidebar .logo {
flex: 0 0 auto;
height: 50px;
display: flex;
align-items: center;
}
.sidebar .logo>span {
border: 1px solid #fff;
border-radius: 50%;
width: 1em;
}
.sidebar .menu {
flex: 1 0 auto;
writing-mode: vertical-rl;
letter-spacing: 0.5em;
text-transform: uppercase;
}
.main {
display: flex;
flex-direction: column;
background: gray;
width: 100%;
}
.main .top-bar {
flex: 0 0 50px;
display: flex;
align-items: center;
justify-content: center;
background: pink;
}
.main .content {
display: flex;
height: 100%; /* added this */
overflow: auto;
}
.main .content .left-side {
flex: 0 0 10em;
background: orange;
margin-right: 2em;
}
.main .content .right-side {
flex: 1 0 auto;
background: white;
/*min-width: 110%;*/
overflow-y: scroll; /* added this */
}
<div class="app">
<div class="sidebar">
<div class="logo"><span>L</span></div>
<div class="menu">menu items</div>
</div>
<div class="main">
<div class="top-bar">TOP BAR</div>
<div class="content">
<div class="left-side">
Left Side Area
</div>
<div class="right-side">
Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area
<br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right
Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br
/> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side
Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br />
</div>
</div>
</div>
</div>

I found a solution with a small change in the layout
Added the ".content-inner" tag after the ".content" tag
.main .content .content-inner {
display: flex;
flex: 1;
height: fit-content;
}
Snippet edited. It is fully working..
html, body, .app {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
overflow: hidden;
}
.app {
display: flex;
flex: 1 1 auto;
max-height: 90%;
max-width: 90%;
}
.sidebar {
background: green;
width: 40px;
color: #fff;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
}
.sidebar .logo {
flex: 0 0 auto;
height: 50px;
display: flex;
align-items: center;
}
.sidebar .logo > span {
border: 1px solid #fff;
border-radius: 50%;
width: 1em;
}
.sidebar .menu {
flex: 1 0 auto;
writing-mode: vertical-rl;
letter-spacing: 0.5em;
text-transform: uppercase;
}
.main {
display: flex;
flex-direction: column;
background: gray;
width: 100%;
}
.main .top-bar {
flex: 0 0 50px;
display: flex;
align-items: center;
justify-content: center;
background: pink;
}
.main .content {
display: flex;
overflow: auto;
}
.main .content .content-inner {
display: flex;
flex: 1;
height: fit-content;
}
.main .content .left-side {
flex: 0 0 10em;
background: orange;
margin-right: 2em;
}
.main .content .right-side {
flex: 1 0 auto;
background: white;
min-width: 110%;
}
<html>
<head></head>
<body>
<div class="app">
<div class="sidebar">
<div class="logo"><span>L</span></div>
<div class="menu">menu items</div>
</div>
<div class="main">
<div class="top-bar">TOP BAR</div>
<div class="content">
<div class="content-inner">
<div class="left-side">
Left Side Area
</div>
<div class="right-side">
Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br /> Right Side Area <br />
</div>
</div>
</div>
</div>
</div>
</body>
</html>

Related

How to remove white space on the right side of a div because of word wrap?

When rescaling the browser window to a really small size there are always sizes that are causing the text on the right side to create some space because of the word wrap to the new line. How can I right align it with word wrap?
What I've tried:
display: inline;
display: inline-block;
float: left;
white-space: nowrap; // not giving me the expected results as I want to keep the padding and the breaks
.page-container {
padding: 160px 48px 48px 48px;
margin: 0 auto;
max-width: calc(1080px + 96px);
height: 90%;
width: 100%;
display: flex;
justify-content: end;
align-items: flex-end;
}
.title-container {
background-color: red;
max-width: 60vw;
text-align: left;
}
<div className="page-container">
<div className="title-container">
<h1>
Text <br /> More Text
</h1>
<br />
<h3>Item1 / Item2 / Item3 / Item4 / Item5</h3>
<br />
<h2>Element1 / Element2 / Element3</h2>
</div>
</div>
https://codesandbox.io/s/hungry-bash-f98ckp?file=/src/App.js:67-359

100% height dependent on height of brother element

I need the element cnt-right to be height 100% of its sibling.
It doesn't have a parent element, only siblings.
Is it possible to accomplish this with CSS? Or do I have to use javascript?
I have this estructure: jsFiddle
.column {
display: block;
min-height: 50px;
background-color: #ccc;
text-align: center;
float: left;
}
.decktop-12 {
width: 100%;
}
.decktop-8 {
width: 66%;
}
.decktop-4 {
width: 33%;
}
.cnt {
background-color: #995595;
}
.cnt-right {
background-color: #559959;
}
<div class="mobile-12 decktop-12 cnt-top column">
Content top
</div>
<div class="mobile-12 decktop-8 cnt column">
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
</div>
<div class="mobile-12 decktop-4 cnt-right column">
Content - right
</div>
<div class="mobile-12 decktop-12 cnt-bottom column">
Content bottom
</div>
You can use only CSS creating a grid layout, javascript is not necessary: https://css-tricks.com/snippets/css/complete-guide-grid/
This is an example of what you could do:
.grid{
display: grid;
grid-template-columns: 2fr 1fr;
grid-template-areas:
"header header"
"content right"
"footer footer"
}
.header {
grid-area: header;
}
.content {
grid-area: content;
background-color: #995595;
}
.right {
grid-area: right;
background-color: #559959;
}
.footer {
grid-area: footer;
}
.header, .footer{
min-height: 50px;
background-color: #ccc;
}
.grid > * {
text-align: center;
}
<div class="grid">
<div class="header">
Content top
</div>
<div class="content">
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
<br /> <br />
Content - main
</div>
<div class="right">
Content - right
</div>
<div class="footer">
Content bottom
</div>
</div>
You can use css grid or flex displays.
I recommand you to have a look at :
https://css-tricks.com/snippets/css/complete-guide-grid/
https://css-tricks.com/snippets/css/a-guide-to-flexbox
And also at how Bootstrap 4 implemented their grid using flex :
https://getbootstrap.com/docs/4.0/layout/grid/
You will have more control over how your grid behaves and possibilities than with float.
I made you an example with using flex. In this example flex evens the columns height by default and looks similar to code written with float :
<div class="row">
<div class="mobile-12 desktop-12 column c1">
Content top
</div>
<div class="mobile-12 desktop-8 column c2">
Content - main
<br><br><br>
</div>
<div class="mobile-12 desktop-4 column c3">
Content - right
</div>
<div class="mobile-12 desktop-12 column c1">
Content bottom
</div>
</div>
<style>
.row {
display: flex;
flex-wrap: wrap; /* Allow multi-line */
}
.column {
flex-grow: 0; /* Prevents column from auto growing */
flex-shrink: 0; /* Prevents column from auto shrinking */
}
.mobile-12 {
flex-basis: 100%;
}
.desktop-8 {
flex-basis: 66.66666%;
}
.desktop-4 {
flex-basis: 33.33333%;
}
.c1 { background-color: grey; }
.c2 { background-color: purple; }
.c3 { background-color: green; }
</style>

make element cover whole available space when there isn't enough content inside css

I have an HTML toolbar with some arbitrary height (which I am not explicitly controlling) and main content div (inside a container div) displayed below the toolbar. The quantity of content inside the main content can vary.
I want if the content's available isn't enough to cover the whole screen then the main content div should cover remaining height available on screen below toolbar. If the content is more than the screen size then it should display a proper vertical scrollbar to display complete content.
my structure is like:
<html>
<body>
<toolbar></toolbar>
<container>
<main div>...</main div>
</container>
</body>
</html>
currently my css for main body and html looks like:
* {
margin: 0;
}
html,
body {
height: 100%;
}
#container{
height: 100%
width:100%
}
#main-div{
// how to make it full screen when there isn't enough content
}
Use Flexbox, where you make the body a flex container with column direction, give the container flex: 1 to fill the remaining height and make that one also a flex container, with row direction, and finally give the main flex: 1 to fill the remain horizontally.
* {
margin: 0;
}
html, body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
}
.container {
flex: 1;
display: flex;
}
main {
flex: 1;
background: lightblue;
}
<div class="toolbar">
toolbar
</div>
<div class="container">
<main>main</main>
</div>
You can use flex with column direction to achieve the desired result
* {
margin: 0;
}
html,
body {
display: flex;
flex-flow: column nowrap;
height: 100%;
}
#container {
height: 100%;
width:100%;
}
#main-div {
flex: 1 1 auto;
background-color: green;
}
<html>
<body>
<toolbar>
Content of toolbar with unknow height and you have no control of it
</toolbar>
<main id="main-div">
Some content <br />
Some content <br />
Some content <br />
Some content <br />
Some content <br />
Some content <br />
Some content <br />
Some content <br />
Some content <br />
Some content <br />
Some content <br />
</main>
</body>
</html>

I need scrollbar on inner element, not browser window (viewport)

In the code below, how do I make the article container auto grow to consume the remaining vertical space below it, but the scroll bar to remain only for that element.
In other words, I want only the inside of article to scroll and not the entire browser window.
Is there a pure css solution? Or do I need javascript to detect the size of the browser window and adjust the height property of article dynamically?
html, body {
//height: 100%;
}
#outer_container {
display: flex;
flex-direction: row;
}
#outer2 {
flex: 1 0 auto;
}
#outer2 {
flex: 1 0 auto;
}
#container {
display: flex;
flex-direction: column;
height: 100%;
width: 50%;
background-color: red;
}
#container header {
background-color: gray;
}
#container article {
flex: 1 1 auto;
overflow-y: auto;
height: 0px;
}
#container footer {
background-color: gray;
}
<div id="outer_container">
<div id="outer1">
<h2>Outer 1</h2>
</div>
<section id="container">
<header id="header">This is a header</header>
<article id="content">
This is the content that
<br />With a lot of lines.
<br />With a lot of lines.
<br />This is the content that
<br />With a lot of lines.
<br />
<br />This is the content that
<br />With a lot of lines.
<br />
<br />This is the content that
<br />With a lot of lines.
<br />
</article>
<footer id="footer">This is a footer</footer>
</section>
<div id="outer2">
<h2>Outer 2</h2>
</div>
</div>
http://jsfiddle.net/ch7n6/907/
It was originally based on the answer to this question:
Flexbox and vertical scroll in a full-height app using NEWER flexbox api
You can try setting position:fixed to your outer container (http://jsfiddle.net/ch7n6/909/):
#outer_container{
display:flex;
flex-direction:row;
top:0;
bottom:0;
position:fixed;
}
If it doesn't work for your design, you can change the container dimensions using window.onresize event.
In your code you commented out:
html, body {
//height: 100%;
}
But I think you were on the right track.
By uncommenting that rule, and adding height: 100% to .outer_container, your layout may be complete.
Try this:
html, body {
height: 100%; /* uncommented */
margin: 0; /* removes default margin */
}
#outer_container {
height: 100%; /* new; see details below */
display: flex;
flex-direction: row;
}
#outer2 {
flex: 1 0 auto;
background-color: lightblue; /* just for demo */
}
#outer1 { /* correction to duplicate ID */
flex: 1 0 auto;
background-color: lightgreen; /* just for demo */
}
#container {
display: flex;
flex-direction: column;
height: 100%;
width: 50%;
background-color: red;
}
#container header {
background-color: gray;
}
#container article {
flex: 1 1 auto;
overflow-y: auto;
height: 0px;
}
#container footer {
background-color: gray;
}
<div id="outer_container">
<div id="outer1">
<h2>Outer 1</h2>
</div>
<section id="container">
<header id="header">This is a header</header>
<article id="content">
This is the content that
<br />With a lot of lines.
<br />With a lot of lines.
<br />This is the content that
<br />With a lot of lines.
<br />
<br />This is the content that
<br />With a lot of lines.
<br />
<br />This is the content that
<br />With a lot of lines.
<br />
</article>
<footer id="footer">This is a footer</footer>
</section>
<div id="outer2">
<h2>Outer 2</h2>
</div>
</div>
jsFiddle
To understand how this solution works, and what may have held you up, take a look at these posts:
Working with the CSS height property and percentage values
Chrome / Safari not filling 100% height of flex parent

Nested Flexbox Flex-Basis Not Working in Chrome or Opera

I have a row which is a flexbox filled with 3 columns which are also flexboxes. One of the columns is taller than the others so the shorter ones stretch to match it's height. However when I set flex-direction: column on the columns and fill one with elements with percentage based flex-basis it doesn't work in Chrome or Opera.
It works in Firefox and IE. It also works if I set a specific height on the column but I can't do that. I also don't want to use the flex-grow property to try and do this because the size would change if you add or take away elements. Does anyone know a workaround to make this work in Chrome and Opera?
<div class="row">
<div class="column col-1">
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
1<br />
</div>
<div class="column col-2">
<div class="cell cell-1">1</div>
<div class="cell cell-2">2</div>
<div class="cell cell-3">3</div>
</div>
<div class="column col-3">
3
</div>
</div>
.row {
display: flex;
}
.column {
background: blue;
display: flex;
flex-direction: column;
margin: 5px;
}
.col-1 {
flex: 0 1 16.666%;
}
.col-2 {
flex: 0 1 33.333%;
}
.col-3 {
flex: 0 1 50%;
}
.cell {
background: gold;
margin: 5px;
}
.cell-1 {
flex: 0 1 16.666%;
}
.cell-2 {
flex: 0 1 33.333%;
}
.cell-3 {
flex: 0 1 50%;
}
Here is an example:
http://codepen.io/anon/pen/ZGZNjY