CSS white-space: nowrap; not respecting max-width [duplicate] - css

This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 4 months ago.
CSS white-space: nowrap; not respecting max-width
Reproduce:
Run the below code
White-space is causing this issue where it increase the width of the right container and igroring the max-width of parent container
Current result: Width of right excees the max- width: 1680px;
Expected Result : Width should not exceed max-width: 1680px;
<!DOCTYPE html>
<html>
<head>
<title>test application</title>
<style>
body {
background-color: red;
}
div{
box-sizing: border-box;
}
.container {
align-items: stretch;
max-width: 1680px;
margin-left: auto;
margin-right: auto;
display: flex;
justify-content: flex-start;
}
.container .left {
background-color: blue;
display: flex;
width: 18em;
padding: 3em 2em 3em 2em;
position: relative;
color: white;
flex-direction: column;
margin-right: 2em;
min-height: calc(100vh - 150px);
flex-grow: 0;
flex-shrink: 0;
}
.container .right {
background-color: green;
width: 100%;
padding: 0em 3em 3em 3em;
flex: 1
}
.b2 {
width: auto;
white-space: nowrap;
overflow: hidden;
}
.abc {
display: inline-flex;
/* width: 1640px; */
overflow: hidden;
}
</style>
</head>
<body>
<div class="container">
<div class="left">left </div>
<div class="right">
<div class="b2">
<div class="abc">
rightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightright
</div>
<div class="abc">
rightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightright
</div>
</div>
</div>
</div>
</body>
</html>

The white-spacing relies on white-spaces to break the text apart. Since you don't have any, the text will not break onto the new line.
There are multiple ways to deal with this.
For example you could set overflow-wrap: anywhere and word-wrap: normal to the .abc selector. But this will also break whole-words apart ignoring standard syllable-based word wrapping.
You could also cut out the excess by forcefully setting overflow: hidden, white-space: nowrap together with a max-width and maybe text-overflow: ellipsis. But this will actually hide the information.
Caveat: The overflow-wrap: anywhere is unfortunately not supported by Safari.
It depends on what you want to achieve.
Example with 'overflow-wrap: anywhere'
<!DOCTYPE html>
<html>
<head>
<title>test application</title>
<style>
body {
background-color: red;
}
div {
box-sizing: border-box;
}
.container {
align-items: stretch;
max-width: 1680px;
margin-left: auto;
margin-right: auto;
display: flex;
justify-content: flex-start;
}
.container .left {
background-color: blue;
display: flex;
width: 18em;
padding: 3em 2em 3em 2em;
position: relative;
color: white;
flex-direction: column;
margin-right: 2em;
min-height: calc(100vh - 150px);
flex-grow: 0;
flex-shrink: 0;
}
.container .right {
background-color: green;
width: 100%;
padding: 0em 3em 3em 3em;
flex: 1
}
.b2 {
width: auto;
white-space: nowrap;
overflow: hidden;
}
.abc {
display: inline-flex;
overflow-wrap: anywhere;
white-space: normal;
overflow: hidden;
}
</style>
</head>
<body>
<div class="container">
<div class="left">left </div>
<div class="right">
<div class="b2">
<div class="abc">
rightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightright
</div>
<div class="abc">
rightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightright
</div>
</div>
</div>
</div>
</body>
</html>
Example with 'text-overflow: ellipsis'
<!DOCTYPE html>
<html>
<head>
<title>test application</title>
<style>
body {
background-color: red;
}
div {
box-sizing: border-box;
}
.container {
align-items: stretch;
max-width: 1680px;
margin-left: auto;
margin-right: auto;
display: flex;
justify-content: flex-start;
}
.container .left {
background-color: blue;
display: flex;
width: 18em;
padding: 3em 2em 3em 2em;
position: relative;
color: white;
flex-direction: column;
margin-right: 2em;
min-height: calc(100vh - 150px);
flex-grow: 0;
flex-shrink: 0;
}
.container .right {
background-color: green;
width: 100%;
padding: 0em 3em 3em 3em;
flex: 1
}
.b2 {
width: auto;
white-space: nowrap;
overflow: hidden;
}
.abc {
display: block;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
max-width: 100ch;
/* 100 characters max */
max-width: 1000px;
/* 1000px max */
}
</style>
</head>
<body>
<div class="container">
<div class="left">left </div>
<div class="right">
<div class="b2">
<div class="abc">
rightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightright
</div>
<div class="abc">
rightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightrightright
</div>
</div>
</div>
</div>
</body>
</html>

Related

How to remove the empty space between elements?

I have made a calculator using one parent div and plenty of child divs, the children are in html. After that I styled it using flex-box and it is almost done; nevertheless there is an empty space between first div (.result) and the rest of the divs (.btn).
I want to remove that empty space which is shown in picture below:
I tried to use flex-box method to arrange these div elements like blocks.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
h1 {
margin: 0 auto 0 auto;
background-color: gray;
text-align: center;
margin-bottom: 5vh;
}
.kalkulator {
display: flex;
flex-wrap: wrap;
height: 50vh;
width: 30vw;
margin: 0 auto 0 auto;
}
.kalkulator .result {
flex-basis: 100%;
height: 10vh;
background-color: #333;
}
.kalkulator div {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
flex-basis: 33%;
background-color: #666;
border: 1px solid black;
}
.btn:nth-last-child(2),
.btn:nth-last-child(1) {
flex-basis: 50%;
}
<h1>kalkulator</h1>
<div class="kalkulator">
<div class="result">wynik</div>
<div class="btn">1</div>
<div class="btn">2</div>
<div class="btn">3</div>
<div class="btn">4</div>
<div class="btn">5</div>
<div class="btn">6</div>
<div class="btn">7</div>
<div class="btn">8</div>
<div class="btn">9</div>
<div class="btn">+</div>
<div class="btn">0</div>
<div class="btn">-</div>
<div class="btn">/</div>
<div class="btn">.</div>
<div class="btn">*</div>
<div class="btn">C</div>
<div class="btn">=</div>
</div>
Apply align-content: flex-start to the flex container.
The default setting is align-content: stretch, which will spread the items across the container. With flex-start, they'll be packed together at the top.
Your code:
.kalkulator {
display: flex;
flex-wrap: wrap;
height: 50vh;
width: 30vw;
margin: 0 auto 0 auto;
border: 2px dashed red;
background-color: yellow;
}
.kalkulator .result {
flex-basis: 100%;
height: 10vh;
background-color: #333;
}
.kalkulator div {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
flex-basis: 33%;
background-color: #666;
border: 1px solid black;
}
.btn:nth-last-child(2),
.btn:nth-last-child(1) {
flex-basis: 50%;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
h1 {
margin: 0 auto 0 auto;
background-color: gray;
text-align: center;
margin-bottom: 5vh;
}
<h1>kalkulator</h1>
<div class="kalkulator">
<div class="result">wynik</div>
<div class="btn">1</div>
<div class="btn">2</div>
<div class="btn">3</div>
<div class="btn">4</div>
<div class="btn">5</div>
<div class="btn">6</div>
<div class="btn">7</div>
<div class="btn">8</div>
<div class="btn">9</div>
<div class="btn">+</div>
<div class="btn">0</div>
<div class="btn">-</div>
<div class="btn">/</div>
<div class="btn">.</div>
<div class="btn">*</div>
<div class="btn">C</div>
<div class="btn">=</div>
</div>
Modified code:
.kalkulator {
display: flex;
flex-wrap: wrap;
height: 50vh;
width: 30vw;
margin: 0 auto 0 auto;
border: 2px dashed red;
background-color: yellow;
align-content: flex-start;
}
.kalkulator .result {
flex-basis: 100%;
height: 10vh;
background-color: #333;
}
.kalkulator div {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
flex-basis: 33%;
background-color: #666;
border: 1px solid black;
}
.btn:nth-last-child(2),
.btn:nth-last-child(1) {
flex-basis: 50%;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
h1 {
margin: 0 auto 0 auto;
background-color: gray;
text-align: center;
margin-bottom: 5vh;
}
<h1>kalkulator</h1>
<div class="kalkulator">
<div class="result">wynik</div>
<div class="btn">1</div>
<div class="btn">2</div>
<div class="btn">3</div>
<div class="btn">4</div>
<div class="btn">5</div>
<div class="btn">6</div>
<div class="btn">7</div>
<div class="btn">8</div>
<div class="btn">9</div>
<div class="btn">+</div>
<div class="btn">0</div>
<div class="btn">-</div>
<div class="btn">/</div>
<div class="btn">.</div>
<div class="btn">*</div>
<div class="btn">C</div>
<div class="btn">=</div>
</div>
It seems too much* for one flexbox. Create the layout with two nested ones: one for the vertical partition of the calculator to the result and the buttons, and another one for the fluid positioning of the buttons within the buttons div:
<div class="kalkulator">
<div class="result">wynik</div>
<div class="buttons">[...]</div>
</div>
.kalkulator {
display: flex;
flex-direction: column;
}
.result {
flex-basis: 10vh;
}
.buttons {
flex-grow: 1; /* Fill the rest */
display: flex;
flex-wrap: wrap;
}
.btn {
flex-grow: 1;
flex-basis: 33%;
justify-content: center;
align-items: center;
display: flex;
}
For placing the buttons under the result box you need a flexbox with a vertical main axis (flex-direction: column). For placing the buttons in a row, a flexbox with a horizontal main axis (the default flex-direction: row).
See the following code, here I removed height: 50vh; property from .kalkulator class:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
h1 {
margin: 0 auto 0 auto;
background-color: gray;
text-align: center;
margin-bottom: 5vh;
}
.kalkulator {
display: flex;
flex-wrap: wrap;
/* height: 50vh; */
width: 30vw;
margin: 0 auto 0 auto;
}
.kalkulator .result {
flex-basis: 100%;
height: 10vh;
background-color: #333;
}
.kalkulator div {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
flex-basis: 33%;
background-color: #666;
border: 1px solid black;
}
.btn:nth-last-child(2),
.btn:nth-last-child(1) {
flex-basis: 50%;
}
<h1>kalkulator</h1>
<div class="kalkulator">
<div class="result">wynik</div>
<div class="btn">1</div>
<div class="btn">2</div>
<div class="btn">3</div>
<div class="btn">4</div>
<div class="btn">5</div>
<div class="btn">6</div>
<div class="btn">7</div>
<div class="btn">8</div>
<div class="btn">9</div>
<div class="btn">+</div>
<div class="btn">0</div>
<div class="btn">-</div>
<div class="btn">/</div>
<div class="btn">.</div>
<div class="btn">*</div>
<div class="btn">C</div>
<div class="btn">=</div>
</div>
Viewport Height (vh): This unit is based on the height of the viewport. A value of 1vh is equal to 1% of the viewport height.
Height of container is 50vh and height of result is 10vh. This leaves 40vh for button panel, or 6.67vh per row. If you want to preserve container height, you can just add height: 6.67vh; to .kalkulator div. This will set button height to fixed value, so there won't be any empty space.

Restrict element height to content, and maintain collapsed overflow

I have a pop-up modal which works overall, however the one annoyance is it has a hardcoded max-height which I'd like to eliminate.
Option #1:
Initially I explored using height: auto on the modal, which does keep the modal height to the natural height of the contents. However this effects the collapsing of the modal when you scale the browser viewport to a short height. The modal overflows out of the viewport, instead of only the green image area overflowing.
Option #2: I'm aware of the possibility of max-content (for height... or even max-height ?) but I haven't been able to get it to work anywhere, and anyhow it has spotty browser support.
Option #3 (current): Setting the modal to height: 100% and max-height: 500px is good enough, however obviously the content needs to be shorter than that.
Overall, requirements are:
A - In small screens, the modal should collapse with the green image area overflowing, thereby maintaining modal title and buttons in view.
B - In large screens, the modal height should only be as big as the contents.
C - Whatever happens, the modal should never visibly go past the global padding (2em).
See #modal in CSS below:
Demo and code here (Codepen)
html, body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
#app {
background-color: gray;
width: 75%;
height: 75%;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
padding: 2em;
}
#container {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
#modal {
/* OPTION #1 */
/* FAILS in small screen: overflow of green image not invoked */
/* height: auto; */
/* OPTION #2 */
/* Not working? */
/* height: max-content; */
/* OPTION #3 */
/* WORKS but specifying a max-height is not ideal */
height: 100%;
max-height: 500px;
width: auto;
position: relative;
background-color: pink;
overflow: hidden;
}
#modal_inner {
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
padding: 2em;
box-sizing: border-box;
}
#image {
overflow-y: auto;
overflow-x: hidden;
flex: 1;
}
#image .inner {
background-color: lime;
padding: 1em;
width: 400px;
height: 200px;
}
#controls {
background-color: yellow;
display: flex;
justify-content: center;
max-width: 20em;
width: 100%;
padding: 1em;
margin-top: 1em;
}
#cta {
background-color: white;
display: flex;
justify-content: center;
max-width: 10em;
padding: 1em;
margin-top: 1em;
}
<div id="app">
<div id="container">
<div id="modal">
<div id="modal_inner">
<div id="title">TITLE</div>
<div id="image">
<div class="inner">image</div>
</div>
<div id="controls">controls</div>
<div id="cta">submit</div>
</div>
</div>
</div>
</div>
You are almost good, use max-height:100% and also add display:flex that will give the height:100% effect you are trying to achieve on the modal_inner
html, body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
#app {
background-color: gray;
width: 75%;
height: 75%;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
padding: 2em;
}
#container {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
#modal {
max-height: 100%;
display:flex;
position: relative;
background-color: pink;
overflow: hidden;
}
#modal_inner {
display: flex;
flex-direction: column;
align-items: center;
/*height: 100%; remove this*/
padding: 2em;
box-sizing: border-box;
}
#image {
overflow-y: auto;
overflow-x: hidden;
flex: 1;
}
#image .inner {
background-color: lime;
padding: 1em;
width: 400px;
height: 200px;
}
#controls {
background-color: yellow;
display: flex;
justify-content: center;
max-width: 20em;
width: 100%;
padding: 1em;
margin-top: 1em;
}
#cta {
background-color: white;
display: flex;
justify-content: center;
max-width: 10em;
padding: 1em;
margin-top: 1em;
}
<div id="app">
<div id="container">
<div id="modal">
<div id="modal_inner">
<div id="title">TITLE</div>
<div id="image">
<div class="inner">image</div>
</div>
<div id="controls">controls</div>
<div id="cta">submit</div>
</div>
</div>
</div>
</div>

Center flex divs horizontally [duplicate]

This question already has answers here:
Special div shrinking
(2 answers)
Closed 5 years ago.
I have three divs that have different flex-basis. In order to make page responsive I want to put them centered one under one if width of the screen is less then 1000px.
Here's my example on Codepen:
.wrapper {
display: flex;
margin: 0 auto;
max-width: 1310px;
}
.left {
flex-basis: 555px;
}
.left__nav {
display: inline-block;
padding: 5px;
text-decoration: none;
}
.wrapper .right {
flex-basis: 462px;
display: flex;
justify-content: flex-end; /* align right (at end) */
}
.wrapper .button {
flex-basis: 193px;
text-align: center;
}
/* style for this demo */
.wrapper > div {
box-sizing: border-box;
border: 1px solid black;
border-collapse: collapse;
}
.mark-center {
text-align: center;
font-size: 30px;
color: red;
}
.container-small {
text-align: center;
background-color: lightgray;
max-width: 1100px;
margin: auto;
}
<div class="wrapper">
<div class="left">
<div class="links">
<a class="left__nav" href="#">Left Nav </a>
</div>
</div>
<div class="right">
Right
</div>
<div class="button">
Button
</div>
</div>
<div class="mark-center">
↑
</div>
<div class="container-small">
Center
</div>
Help me to put them that way if width < 1000px next way:
Seems to me you don't want flex-basis, you want width since these elements don't grow or shrink.
If so, you can use a media query and change the flex-direction to column after switching the flex-basis properties to width.
#media (max-width:1100px) {
.wrapper {
flex-direction:column;
align-items: center;
}
}
.wrapper {
display: flex;
margin: 0 auto;
max-width: 1310px;
}
.left {
width: 555px;
}
.left__nav {
display: inline-block;
padding: 5px;
text-decoration: none;
}
.wrapper .right {
width: 462px;
/* display: flex; */
/* justify-content: flex-end; */
/* align right (at end) */
}
.wrapper .button {
width: 193px;
text-align: center;
}
/* style for this demo */
.wrapper>div {
box-sizing: border-box;
border: 1px solid black;
border-collapse: collapse;
}
.mark-center {
text-align: center;
font-size: 30px;
color: red;
}
.container-small {
text-align: center;
background-color: lightgray;
max-width: 1100px;
margin: auto;
}
#media (max-width:1100px) {
.wrapper {
flex-direction: column;
align-items: center;
text-align: center;
}
}
<div class="wrapper">
<div class="left">
<div class="links">
<a class="left__nav" href="#">Left Nav </a>
</div>
</div>
<div class="right">
Right
</div>
<div class="button">
Button
</div>
</div>
<div class="mark-center">
↑
</div>
<div class="container-small">
Center
</div>

Element to take remaining height of viewport

Please consider this style:
.root {
display: flex;
flex-direction: column;
height: 100%;
}
.header {
width: 100%;
background-color: red;
display: flex;
height: 100px;
justify-content: space-between;
.logo-pane {
width: 100px;
height: 100px;
background-color: green;
}
.user-actions {
width: 100px;
height: 100px;
background-color: blue;
}
}
.content {
flex-grow: 1;
background-color: pink;
}
What I want to achieve is that the content element will take the remaining height of the viewport, but it takes only his content height.
HTML:
<div class="root">
<div class="header">
<div class="logo-pane">Logo</div>
<div class="user-actions">User Actions</div>
</div>
<div class="content">
content
</div>
</div>
Codepen
The problem is the surrounding .root. You have to increase the height of the .root to the remaining space. So you have to set the height:100vh; on .root. Try the following solution:
body, html {
margin:0;
padding:0;
}
.root {
display: flex;
flex-direction: column;
height: 100vh;
align-items:stretch;
align-content:stretch;
}
.header {
width: 100%;
background-color: red;
display: flex;
height: 100px;
justify-content: space-between;
}
.logo-pane {
width: 100px;
height: 100px;
background-color: green;
}
.user-actions {
width: 100px;
height: 100px;
background-color: blue;
}
.content {
flex-grow:1;
background-color: pink;
}
<div class="root">
<div class="header">
<div class="logo-pane">Logo</div>
<div class="user-actions">User Actions</div>
</div>
<div class="content">content</div>
</div>
.content {
flex-grow: 1;
background-color: pink;
height: 100vh;
}
Set the :root to 100vh (100% of the viewport height) instead 100%
You can simply add
height: 100% to html, body
add height to 20% for root div
add height to 80% for content div
will solve your problem
html,body {
height: 100%;
}
Here is the jsFiddle
Hope it helps :)
I think your misunderstanding what flex does. Flex is used to align its children, not to fill a viewport. Heres another solution.
https://jsfiddle.net/rob_primacy/1wnpr50s/
<div class="root">
<div class="header">
<div class="logo-pane">Logo</div>
<div class="user-actions">User Actions</div>
</div>
</div>
<div class="content">
content
</div>
and the css
.root {
display: flex;
flex-direction: column;
height: 100%;
position: relative;
}
.header {
width: 100%;
background-color: red;
display: flex;
height: 100px;
justify-content: space-between;
position: relative;
}
.user-actions {
width: 100px;
height: 100px;
background-color: blue;
}
.logo-pane {
width: 100px;
height: 100px;
background-color: green;
}
.content {
background-color: pink;
position: absolute;
height: 100%;
left: 8px;
right: 8px;
}
Use like this
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Untitled 1</title>
<style type="text/css">
body{
margin:0;
}
.root {
display: flex;
flex-direction: column;
height: 100%;
}
.header {
width: 100%;
background-color: red;
display: flex;
height: 100px;
justify-content: space-between;
.logo-pane {
width: 100px;
height: 100px;
background-color: green;
}
.user-actions {
width: 100px;
height: 100px;
background-color: blue;
}
}
.content {
flex-grow: 1;
background-color: pink;
height:100%;
width:100%;
position: fixed;
}
</style>
</head>
<body>
<div class="root">
<div class="header">
<div class="logo-pane">Logo</div>
<div class="user-actions">User Actions</div>
</div>
<div class="content">
content
</div>
</div>
</body>
</html>
Your codepen linked works fine. I do not understand where you get stuck.
You could basicly build your template from 2 containers :example with header and main
html,
body {
height: 100%;/* or just : 100vh; for body only */
margin: 0;
}
body {
display: flex;
flex-direction: column;
/* width and margin:auto is avalaible */
}
header {
/* height: 50px;or do not set any and let grow from its content */
background: gray;
}
main {
flex: 1;/* will fill up all space left */
background: lightblue;
/* overflow:auto; optionnal if you do not want html to scroll and keep header fixed */
}
<header>
whatever <br/> sizes me
</header>
<main>
content
</main>
Make it simple to start with :)

Flex-box ignores wrapped children's margin (margin collapse)

Given the following HTML:
<div class="outer">
<div>
<div class="inner">A</div>
</div>
</div>
<div class="outer">
<div class="inner">B</div>
</div>
and the following CSS (prefix free):
.outer {
display: box;
box-orient: vertical;
height: 100px;
width: 100px;
background: red;
margin: 10px;
}
.inner {
height: 50px;
margin-top: 10px;
background: green;
}
Here is a CodePen.
A is wrapped in a <div> so it's margin gets ignored.
Q: How can I achieve B's behavior for A (margin) with the flex box model?
Note: The div wrappers can go multiple levels deep
Targeting: latest Chrome/Safari/iOS
Thank you very much for your help!
Edit: Thanks to #JoséCabo I came up with this:
.outer {
display: flex;
flex-direction: column;
height: 100px;
width: 100px;
background: red;
margin: 10px;
}
.inner {
height: 50px;
margin-top: 10px;
background: green;
}
CodePen
Chrome:
Safari:
Unfortunately it doesn't work in Safari as mentioned by #cimmanon, so I still need some help.
What you're looking at actually has nothing to do with Flexbox, but what's called margin collapse
.outer div {
border: 1px solid;
}
The addition of the border has prevented the margin from collapsing. Rather than relying on margins, I would recommend placing a padding on the parent container:
.outer {
padding-top: 10px;
}
Example:
.wrapper {
background: #eef;
border: 1px solid darkgray;
}
.container {
display: flex;
flex-wrap: wrap;
margin: -1em;
}
.item {
flex-grow: 1;
margin: 1em;
border: 1px solid black;
padding: 1em;
min-width: 6em;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class="wrapper">
<div class='container'>
<div class='item'>item</div>
<div class='item'>item</div>
<div class='item'>item</div>
<div class='item'>item</div>
<div class='item'>item</div>
<div class='item'>item</div>
</div>
</div>
</body>
</html>
Now, to cover all of your prefixes, you need something like this:
.outer {
display: -moz-box;
display: -webkit-flexbox;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-moz-box-orient: vertical;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
height: 100px;
width: 100px;
background: red;
margin: 10px;
}
Finally I came up with the right solution (for my specific problem).
.outer {
display: flex;
flex-direction: column;
height: 100px;
width: 100px;
background: red;
margin: 10px;
}
.inner {
height: 50px;
margin-top: 10px;
background: green;
display: inline-block;
width: 100%;
}
CodePen
I'm using display: inline-block on .inner to disable margin collapsing and then compensate for the lost width with width: 100%.
All the credit goes to cimmanon for pointing me in the right "margin collapse" direction

Resources