Box doesn't overflow enough with flexbox [duplicate] - html

This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Centered elements inside a flex container are growing and overflowing beyond top [duplicate]
(3 answers)
Closed 2 years ago.
I'm getting this weird issue with flex-box. See below. I should be able to scroll all the way up and all the way down (in order to see "Middle Top" and "Middle Bottom"). But I am unable to.
After further inspection, Firefox dev tools reveal that .wrapper has some minimum height. And setting min-height: 0 or height: 100% to .wrapper seems to fix the issue. I am wondering why this is? Why do I need to set a height or min height on .wrapper when .middle is set to overflow.
html,
body {
height: 100%;
margin: 0;
}
.flexi {
display: flex;
flex-direction: column;
height: 100%;
}
.flexi>div {
width: 100%
}
.top,
.bottom {
flex-basis: 40px;
min-height: 40px;
}
.top {
background: red;
}
.middle {
flex: 1;
background: green;
overflow: auto;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.spacer {
display: block;
height: 1000px;
width: 100px;
background: purple;
}
.bottom {
background: blue;
}
<div class="flexi">
<div class="top">
<span>Top</span>
</div>
<div class="middle">
<div class="wrapper">
<span>Middle Top</span>
<span class="spacer"></span>
<span>Middle Bottom</span>
</div>
</div>
<div class="bottom">
<span>Bottom</span>
</div>
</div>
html,
body {
height: 100%;
margin: 0;
}
.flexi {
display: flex;
flex-direction: column;
height: 100%;
}
.flexi>div {
width: 100%
}
.top,
.bottom {
flex-basis: 40px;
min-height: 40px;
}
.top {
background: red;
}
.middle {
flex: 1;
background: green;
overflow: auto;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.wrapper {
min-height: 0; /* why? */
}
.spacer {
display: block;
height: 1000px;
width: 100px;
background: purple;
}
.bottom {
background: blue;
}
<div class="flexi">
<div class="top">
<span>Top</span>
</div>
<div class="middle">
<div class="wrapper">
<span>Middle Top</span>
<span class="spacer"></span>
<span>Middle Bottom</span>
</div>
</div>
<div class="bottom">
<span>Bottom</span>
</div>
</div>

Related

Flexbox content not showing properly [duplicate]

This question already has answers here:
Can't scroll to top of flex item that is overflowing container
(12 answers)
Closed 10 months ago.
I like to have a div that keeps all it's children in the center (vertical and horizontal). I can easily achieve this by using flexbox. But when width of my children get bigger than the parent, a part of children is not visible.
How can I fix this?
Codepen
* {
margin: 0;
padding: 0;
}
.container {
height: 500px;
width: 500px;
background: red;
display: flex;
justify-content: center;
align-items: center;
overflow: scroll;
}
.children {
min-width: 1200px;
height: 50px;
background: blue;
}
<div class='container'>
<div class="children">
<h1>Welcome to my city, california</h1>
</div>
</div>
You just have to change the justify-content to be flex-start
See below.
And if you want the H1 to be centered, just use text-align: center
* {
margin: 0;
padding: 0;
}
.container {
height: 500px;
width: 500px;
background: red;
display: flex;
justify-content: flex-start;
align-items: center;
overflow: scroll;
}
.children {
min-width: 1200px;
height: 50px;
background: blue;
}
<div class='container'>
<div class="children">
<h1>Welcome to my city, california</h1>
</div>
</div>
Change the .container{
min-width: 100%}
* {
margin: 0;
padding: 0;
}
.container {
height: 500px;
width: 500px;
background: red;
display: flex;
justify-content: center;
align-items: center;
overflow: scroll;
}
.children {
min-width: 100%;
height: 50px;
background: blue;
}
<div class='container'>
<div class="children">
<h1>Welcome to my city, california</h1>
</div>
</div>

How to make nested flex child scrollable

I have a list of messages (which is a flex child) in a container with unknown height and want to make them scrollable. But I cannot find a proper combination of flex-grow: 1, min-height: 0 and other flex tricks to make it working - message list is still bigger than its parent.
When I add overflow-y: auto to its parent - it works but this parent besides messages list includes some content which should not scroll.
Here's my example for this case: https://jsfiddle.net/ecbtrn58/2/
<div class="page">
<div class="messages-section">
<div class="header">Your messages</div>
<div class="content">
<img src="https://http.cat/100" width="70" height="50"/>
<div class="messages-list">
<div class="message">Hi.</div>
<div class="message">Hello.</div>
<div class="message">Good morning.</div>
<div class="message">Yo!</div>
</div>
</div>
</div>
</div>
.page {
background-color: #ddd;
width: 300px;
height: 300px;
.messages-section {
display: flex;
flex-direction: column;
width: 50%;
height: 100%;
background-color: #ccc;
.header {
background: #bbb;
padding: 5px;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
padding: 5px;
.messages-list {
display: flex;
flex-direction: column;
overflow-y: auto;
/* What to add here to make it scrollable? */
.message {
height: 50px;
margin: 10px;
padding: 10px;
background: #1dc497;
}
}
}
}
}
How can I make messages list to scroll?
You have to set the height of .content to 100% and make it scrollable:
.page {
background-color: #ddd;
width: 300px;
height: 300px;
}
.page .messages-section {
display: flex;
flex-direction: column;
width: 50%;
height: 100%;
background-color: #ccc;
}
.page .messages-section .header {
background: #bbb;
padding: 5px;
}
.page .messages-section .content {
display: flex;
flex-direction: column;
align-items: center;
padding: 5px;
height: 100%;
overflow-x: scroll;
}
.page .messages-section .content .messages-list {
display: flex;
flex-direction: column;
overflow-y: auto;
/* What to add here to make it scrollable? */
}
.page .messages-section .content .messages-list .message {
height: 50px;
margin: 10px;
padding: 10px;
background: #1dc497;
}
<div class="page">
<div class="messages-section">
<div class="header">Your messages</div>
<div class="content">
<img src="https://http.cat/100" width="70" height="50" />
<div class="messages-list">
<div class="message">Hi.</div>
<div class="message">Hello.</div>
<div class="message">Good morning.</div>
<div class="message">Yo!</div>
</div>
</div>
</div>
</div>

center a div inside another div vertically [duplicate]

This question already has answers here:
Flexbox: center horizontally and vertically
(14 answers)
How can I vertically center a div element for all browsers using CSS?
(48 answers)
How can I vertically align elements in a div?
(28 answers)
Closed 2 years ago.
Lets say I have this simple html page:
<div class="main">
<div class="header">
<h1>HEADER</h1>
</div>
<div class="content">
<div class="box">
</div>
</div>
</div>
My header is fixed and the content should be beneath it and with height 100% of what ever left of the body.
I've already done that with this style:
*{
margin-left: 0;
margin-top: 0;
}
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
.header {
background-color: red;
text-align: center;
position: fixed;
width: 100%;
}
.content {
background-color: antiquewhite;
padding-top: 38px;
}
h1 {
margin-bottom: 0;
}
.main {
display: flex;
flex-direction: column;
height: 100vh;
}
.content {
flex: 1;
}
.box {
width: 150px;
height: 150px;
background-color: yellow;
}
Here's how the page looks for now: https://elbargho.github.io/sudoku/centerdiv.html
now I'm trying to center the box div horizontally and vertically in relative to the full body - the header size
what I've tried to do:
margin-top: 50% - for some reason the box went all the way down to the bottom
setting the position of content div to relative, and of box div to absolute - the content div overlapped the fixed header
You can set content class as
.content {
/* flex: 1; */
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
*{
margin-left: 0;
margin-top: 0;
}
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
.header {
background-color: red;
text-align: center;
position: fixed;
width: 100%;
}
.content {
background-color: antiquewhite;
padding-top: 38px;
}
h1 {
margin-bottom: 0;
}
.main {
display: flex;
flex-direction: column;
height: 100vh;
}
.content {
/*flex: 1; */
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
.box {
width: 150px;
height: 150px;
background-color: yellow;
}
<div class="main">
<div class="header">
<h1>HEADER</h1>
</div>
<div class="content">
<div class="box">
</div>
</div>
</div>
This is probably what you need. Documented in the code.
* {
margin-left: 0;
margin-top: 0;
}
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
/* Modified */
.header {
background-color: red;
text-align: center;
/* position: fixed; */
position: sticky;
width: 100%;
}
.content {
background-color: antiquewhite;
padding-top: 38px;
}
h1 {
margin-bottom: 0;
}
/* Modified */
.main {
display: flex;
flex-direction: column;
height: 100vh;
align-items: center;
}
/* Modified */
.content {
/*flex: 1;*/
display: flex;
align-items: center;
height: inherit;
}
.box {
width: 150px;
height: 150px;
background-color: yellow;
}
<div class="main">
<div class="header">
<h1>HEADER</h1>
</div>
<div class="content">
<div class="box">
</div>
</div>
</div>
Here solution:
.content {
display: flex;
flex: 1;
justify-content: center;
align-items: center;
}
One way is to use CSS Transform.
.box {
position: relative;
top: 50%;
transform: translateY(-50%);
/* horizontal center */
margin: 0 auto;
}
Check out this website for all CSS centering help:
http://howtocenterincss.com/

How to correctly center-align the contents of two adjacent box split in a 2:1 ratio

My use case is the following:
I've got a center-aligned layout with a max-width of say 360px.
Part of that layout is a container with two adjacent boxes. The right one contains an image that fills 33% width of the window. Left to it should be a text container. This text container should be aligned with the left border of the remaining center-aligned layout.
Here's a sketch of it:
body {
display: flex;
flex-direction: column;
}
.col {
display: flex;
flex-direction: column;
}
.row {
display: flex;
}
.items-center {
align-items: center;
}
.items-end {
align-items: flex-end;
}
.items-start {
align-items: flex-start;
}
.top {
max-width: 360px;
width: 100%;
height: 50px;
background: tomato
}
.width-2-3 {
width: 66.666%;
}
.width-1-3 {
width: 33.3333%
}
.left-content,
.right-content {
width: 100%;
height: 50px;
}
.left-content {
max-width: 240px;
background: rebeccapurple;
color: white;
}
.right-content {
background: pink;
}
<div class="col items-center">
<div class="top"></div>
</div>
<div class="row">
<div class="width-2-3 col items-end">
<div class="left-content">text</div>
</div>
<div class="width-1-3 col items-start">
<div class="right-content">[img]</div>
</div>
</div>
So basically my goal is to left align those two rows, no matter how big the window width. But after trying for some time I just can't get the math right! So any help would be greatly appreciated :)
You can consider negative margin left:
body {
display: flex;
flex-direction: column;
margin:0;
}
.col {
display: flex;
flex-direction: column;
}
.row {
display: flex;
}
.items-center {
align-items: center;
}
.top {
max-width: 360px;
width: 100%;
height: 50px;
background: tomato
}
.width-2-3 {
width: 66.666%;
}
.width-1-3 {
width: 33.3333%
}
.left-content,
.right-content {
width: 100%;
height: 50px;
}
.left-content {
max-width: 240px;
background: rebeccapurple;
color: white;
}
.right-content {
background: pink;
}
#media (min-width:360px) {
.left-content {
margin-left:calc((150% - 360px)/2); /* 150 is 3/2*100% since the width is 2/3*/
}
.right-content {
margin-left:calc(240px + ((200% - 360px)/2) - 150%); /*200% is equal to 150% of the left element */
}
}
<div class="col items-center">
<div class="top"></div>
</div>
<div class="row">
<div class="width-2-3 col">
<div class="left-content">text</div>
</div>
<div class="width-1-3 col">
<div class="right-content">[img]</div>
</div>
</div>
Thanks to #temani-afif I came up with a solution that required only one line to change
- max-width: calc(240px);
+ max-width: calc(180px + 25%);
This way the text container is always left aligned to the top container while taking all the available space until the 33% window-width image container starts. And this works for all window sizes. Thanks for your help everyone! :)
body {
display: flex;
flex-direction: column;
}
.col {
display: flex;
flex-direction: column;
}
.row {
display: flex;
}
.items-center {
align-items: center;
}
.items-end {
align-items: flex-end;
}
.items-start {
align-items: flex-start;
}
.top {
max-width: 360px;
width: 100%;
height: 50px;
background: tomato
}
.width-2-3 {
width: 66.666%;
}
.width-1-3 {
width: 33.3333%
}
.left-content,
.right-content {
width: 100%;
height: 50px;
}
.left-content {
max-width: calc(180px + 25%);
background: rebeccapurple;
color: white;
}
.right-content {
background: pink;
}
<div class="col items-center">
<div class="top"></div>
</div>
<div class="row">
<div class="width-2-3 col items-end">
<div class="left-content">text</div>
</div>
<div class="width-1-3 col items-start">
<div class="right-content">[img]</div>
</div>
</div>
Why dont you get rid of .item-end and .item-start divs so you can easily control the content.
body {
display: flex;
flex-direction: column;
}
.container {
position:relative;
max-width:360px;
width:100%;
display:flex;
justify-content:center;
}
.different-width {
max-width:450px;
}
.col {
display: flex;
flex-direction: column;
}
.row {
display: flex;
}
.items-center {
align-items: center;
}
.content-center {
justify-content:center;
}
.top {
max-width: 360px;
width: 100%;
height: 50px;
background: tomato
}
.left-content,
.right-content {
width: 100%;
height: 50px;
}
.width-2-3 {
width: 66.666%;
}
.width-1-3 {
width: 33.3333%
}
.left-content {
max-width: 240px;
background: rebeccapurple;
color: white;
}
.right-content {
background: pink;
}
<div class="col items-center">
<div class="container">
<div class="top"></div>
</div>
</div>
<div class="row content-center">
<div class="container different-width">
<div class="left-content width-1-3">text</div>
<div class="right-content width-2-3">[img]</div>
</div>
</div>
If you need to have more control over the left-content and right-content width, consider using flex-grow and flex-basis.
If you want to control the width of the second container, make another class with a different max-width value.

Height 100% inside flex item

I have a layout that is mainly divided into 3 parts and the middle one should take a full height. And it does.
However, I need an additional div which will play a role of the backdrop and here the problem comes. The child doesn't want to take 100% height.
Here .body is a div that is being stretched when there is not enough content and .bg-gray is the one I want to take its parent full height.
Is there a way achieve this without using relative + absolute positioning?
Also, I'm looking for the answer to my question: why is this happening that way.
html, body {
padding: 0;
margin: 0;
}
.container {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: stretch;
}
.header {
height: 50px;
background-color: #e6e6e6;
}
.footer {
height: 50px;
background-color: #aaa444;
}
.body {
flex: 1;
}
.bg-gray {
background-color: #eee;
min-height: 100%;
flex: 1;
}
<div class="container">
<div class="header">
</div>
<div class="body">
<div class="bg-gray">
<div>
asdasd
</div>
</div>
</div>
<div class="footer">
</div>
</div>
Apply flexbox to the .body div.
.body {
flex: 1;
display: flex;
flex-direction: column;
}
html,
body {
padding: 0;
margin: 0;
}
.container {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: stretch;
}
.header {
height: 50px;
background-color: #e6e6e6;
}
.footer {
height: 50px;
background-color: #aaa444;
}
.body {
flex: 1;
display: flex;
flex-direction: column;
}
.bg-gray {
background-color: darkgrey;
min-height: 100%;
flex: 1;
}
.bg-gray div {
background: lightblue;
}
<div class="container">
<div class="header">
</div>
<div class="body">
<div class="bg-gray">
<div>
asdasd
</div>
</div>
</div>
<div class="footer">
</div>
</div>