Restrict element height to content, and maintain collapsed overflow - css

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>

Related

How to let a Flex column on the bottom keeping the items order using CSS? [duplicate]

This question already has answers here:
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
(6 answers)
Closed 4 months ago.
I have a horizontally centered column of Flex items ordered from 1 to 5 that are aligned from the top of the container like this:
body, html {
height: 100%;
position: relative;
margin: 0;
padding: 0;
}
.container {
display: inline-flex;
flex-wrap: wrap;
flex-direction: column;
align-items: flex-end;
align-content: center;
width: 100%;
height: 100%;
background: pink;
}
.item {
margin: 1px;
width: 30px;
height: 30px;
background: green;
}
<div class=container><div class=item>1</div><div class=item>2</div><div class=item>3</div><div class=item>4</div><div class=item>5</div></div>
I would like to let it aligned by the bottom of the container instead. I manage to do it with flex-direction: column-reverse; like in the next Snippet:
body, html {
height: 100%;
position: relative;
margin: 0;
padding: 0;
}
.container {
display: inline-flex;
flex-wrap: wrap;
flex-direction: column-reverse;
align-items: flex-end;
align-content: center;
width: 100%;
height: 100%;
background: pink;
}
.item {
margin: 1px;
width: 30px;
height: 30px;
background: green;
}
<div class=container><div class=item>1</div><div class=item>2</div><div class=item>3</div><div class=item>4</div><div class=item>5</div></div>
However, as you see, the items get out of order! Is there a way to let a flex column on the bottom without reversing the items order using CSS? I tried every Flex property that I know so far without success.
You can use justify-content: end;
.container {
width: 150px;
height: 150px;
border: 1px solid black;
display: flex;
flex-direction: column;
align-items: center;
justify-content: end;
}
.content {
width: 25px;
height: 25px;
border: 1px solid black;
}
<div class="container">
<div class="content">1</div>
<div class="content">2</div>
<div class="content">3</div>
<div class="content">4</div>
<div class="content">5</div>
</div>
You need to use the justify-content property to align content along the main axis (in your case vertically). You are using align-items which defines how the items should be aligned along the cross axis.
body, html {
height: 100%;
position: relative;
margin: 0;
padding: 0;
}
.container {
display: inline-flex;
flex-wrap: wrap;
flex-direction: column;
justify-content: flex-end;
align-content: center;
width: 100%;
height: 100%;
background: pink;
}
.item {
margin: 1px;
width: 30px;
height: 30px;
background: green;
}
<div class=container>
<div class=item>1</div>
<div class=item>2</div>
<div class=item>3</div>
<div class=item>4</div>
<div class=item>5</div>
</div>

css not working when trying to center self

I'm trying to make an item center,but somehow it not work
Here is html part:
<div>
<div className={styles.unanswerQuestionContainer}>
<div className={styles.headerContainer}>
<div>Unanswered Questions</div>
<div>Answered Questions</div>
</div>
</div>
</div>
Here is css part:
.unanswerQuestionContainer {
height: 60vh;
width: 60vw;
border: 1px solid;
display: flex;
margin: 20px 0 0 0;
align-self: center;
}
.headerContainer {
display: flex;
flex-direction: row;
justify-content: space-between;
width: 100%;
}
But it show something like this:
It do not center the div, how can i center this ??
Edit: When i try to inspect then it show all of this is margin:
You need to add following style to outer div(parent) unanswerQuestionContainer
display: flex;
justify-content: center;
align-items: center;
height: 100%;
body{
height: 100vh;
margin: 0;
}
.unanswerQuestionContainer {
height: 60vh;
width: 60vw;
border: 1px solid;
display: flex;
margin: 20px 0 0 0;
align-self: center;
}
.headerContainer {
display: flex;
flex-direction: row;
justify-content: space-between;
width: 100%;
}
.outer{
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
<div class="outer">
<div class="unanswerQuestionContainer">
<div class="headerContainer">
<div>Unanswered Questions</div>
<div>Answered Questions</div>
</div>
</div>
</div>
You will have to adjust which css properties you will use in order to prevent the two h1 from overlapping.
<div className={styles.unanswerQuestionContainer}>
<div class="Questions">
<p id="question-type">Answered Question</p>
<p id="question-type">Unanswered Question</p>
</div>
</div>
.questions h1 {
width: 100px;
height: 100px;
position: absolute;
top:0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}

How can I use flexbox to make two items one center one bottom

https://i.stack.imgur.com/e2n5o.png
I want to achieve a layout like this by flexbox. body is flex container and there are only two flex items, one card and one footer. Here is a simplified codepen link. How can I make the footer at the bottom of the page while the card position center as it is now.
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.container {
width: 400px;
height: 300px;
background-color: green;
}
.footer {
margin-bottom: 20px;
background-color: yellow;
width: 200px;
height: 50px;
}
<div class="container"></div>
<div class="footer"></div>
if I add margin-top:auto, the footer's position will be right, but the container will go to the top.
if I add gap to body, the container will not be at the center
Use another element for the green card and make the .container fill all the available space using flex-grow: 1.
Use display: flex and align-items:center on the .container to center the card vertically.
body{
display:flex;
flex-direction:column;
align-items:center;
height:100vh;
}
.container{
flex-grow: 1;
display: flex;
align-items: center;
}
.card {
width:400px;
height:300px;
background-color:green;
}
.footer{
margin-bottom:20px;
background-color:yellow;
width: 200px;
height:50px;
}
<div class="container">
<div class="card"></div>
</div>
<div class="footer"></div>
The body does not need justify-content:center; so you should remove it too.
Another approach if you want that .container to have 100% width.
body {
display: flex;
flex-wrap: wrap;
height: 100vh;
}
.container {
width: 100%; /* NEW */
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center; /* NEW */
}
.card {
width: 400px;
height: 300px;
background-color: green;
}
.footer {
margin-bottom: 20px;
background-color: yellow;
width: 200px;
height: 50px;
margin: auto; /* NEW */
}
<div class="container">
<div class="card"></div>
</div>
<div class="footer"></div>
You can use grid to center the container, and position to stick the footer.
body {
display: grid;
place-content: center; /* center the container */
height: 100vh;
margin: 0;
}
.container {
width: 400px;
height: 300px;
background-color: green;
}
.footer {
justify-self: center; /* center the footer */
margin-bottom: 20px;
background-color: yellow;
width: 200px;
height: 50px;
/* push the footer to the bottom */
position: sticky;
top: 100vh;
}
<div class="container"></div>
<div class="footer"></div>

I have trouble replicating a design of a background in CSS

I have a design that I need to replicate with CSS.
The background should be centered in the div
I tried using gradients, but they are not looking good on different browsers.
You can do it this way with Flexbox :
Codepen
section {
border: #f00 solid 2px;
display: flex;
align-items: flex-end;
height: 400px;
}
section .aligner {
border: #00f dashed 1px;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 80%;
position: relative;
}
section .aligner .background {
background: #ff0;
width: 100%;
height: 60%;
}
section .aligner .square {
position: absolute;
width: 300px;
height: 100%;
background: #008000;
}
<section>
<div class="aligner">
<div class="background"></div>
<div class="square"></div>
</div>
</section>

How to make full height sidebar with dynamic main content?

I have an angular2 app with left a sidebar and dynamic main content.
HTML:
<body>
<div class="full_height">
<div class="sidebar">Some content</div>
<div class="main">Some dynamic content</div>
</div>
</body>
CSS:
body{
width: 100%;
height: 100%;
margin: 0;
}
.full_height{
display: flex;
flex-direction: row;
align-items: stretch;
}
.sidebar{
background: black;
color: white;
width: 150px;
flex: 0 0 auto;
}
.main{
flex: 1 1 auto;
}
I need the sidebar grow to 100% height of the browser body if no information in the main block. And I need the sidebar and the main block have equal height when a big amount of information have been loaded to the main block via AJAX.
How to make the first part work?
JSFiddle
I think you just forgot to assign a 100% height to the HTML element. Is this what you tried to do ?
html, body{
width: 100%;
height: 100%;
margin: 0;
}
.full_height{
display: flex;
flex-direction: row;
align-items: stretch;
height: 100%;
}
.sidebar{
background: black;
color: white;
width: 150px;
flex: 0 0 auto;
}
.main{
flex: 1 1 auto;
}
<body>
<div class="full_height">
<div class="sidebar">Some content</div>
<div class="main">Some dynamic content</div>
</div>
</body>
If you want to make full height sidebar then sidebar will be fixed position and rest of the content will be relative position. Please check the below Snippet.
html{
box-sizing: border-box;
height: 100%;
width: 100%;
}
*,
*:after,
*:before{
box-sizing: inherit;
}
body{
margin: 0;
padding: 0;
}
.full_height{
background-color: white;
display: flex;
flex-direction: column;
}
#media (min-width: 992px){
.full_height{
padding-left: 330px;
}
}
.sidebar{
background-color: #5c5c5c;
color: white;
display: flex;
flex-direction: column;
margin-bottom: 30px;
padding: 20px;
width: 100%;
}
#media (min-width: 992px){
.sidebar{
height: 100%;
left: 0;
overflow-x: hidden;
overflow-y: auto;
position: fixed;
top: 0;
width: 310px;
z-index: 1030;
}
}
.main{
background-color: #009688;
color: white;
font-size: 20px;
margin-bottom: 30px;
padding: 20px;
width: 100%;
}
<div class="full_height">
<div class="sidebar">Some content</div>
<div class="main">Some dynamic content</div>
</div>
Snippet two This relative content
html{
box-sizing: border-box;
height: 100%;
width: 100%;
}
*,
*:after,
*:before{
box-sizing: inherit;
}
body{
height: 100%;
margin: 0;
padding: 0;
width: 100%;
}
.full_height{
background-color: black;
display: flex;
flex-direction: column;
padding: 20px;
}
#media (min-width: 992px){
.full_height{
align-items: stretch;
flex-direction: row;
flex-wrap: nowrap;
height: 100%;
width: 100%;
}
}
.sidebar{
background-color: #f5f5f5;
color: #009688;
flex-basis: 100%;
flex-grow: 0;
flex-shrink: 0;
max-width: 100%;
padding: 20px;
}
#media (min-width: 992px){
.sidebar{
flex-basis: 310px;
max-width: 310px;
}
}
.main{
background-color: white;
color: black;
padding: 20px;
width: 100%;
}
#media (min-width: 992px){
.main{
padding-left: 40px;
}
}
<div class="full_height">
<div class="sidebar">Sidebar content</div>
<div class="main">Main Content</div>
</div>
Check the Snippet in full width view. All snippet is responsive.
If you want both the .sidebar and .main to fill the entire screen, just add the 100vh height.
.sidebar,
.main {
height: 100vh;
}

Resources