Define scroll div height by parent. Any tips? - css

So in resume, I have a #modal { max-height:90% } and I need to place a #footer element below and let the top remaing space to a scrollable div, but is not possible to have a scroll div without setting the height (or max-height, as far as I know).
The way I achieved this is calculating the height of the scrollable div, like so: https://codepen.io/murillotsoza/pen/xxpJPVJ (change the code view to the left/right side)
But I still think that there is a prettier solution without height calculations. Any tips?
#scroll {
max-height: calc(90vh - 18px - 50px);
overflow-y: auto;
overflow-x: hidden;
}
.item {
font-size: 18px; text-align: center;
line-height: 50px; width: 300px;
border-bottom: 1px solid #ccc;
}
#footer {
font-size: 18px; text-align: center;
line-height: 50px; width: 100%;
background-color: #333; color: white;
}
#title{
height: 18px;
background-color: black;
}
#content {
background-color: white;
}
#modal {
max-height: 90%;
overflow: hidden;
}
#background {
position: fixed;
top: 0; left: 0;
width: 100vw;
height: 100vh;
background-color: #eee;
display: flex;
justify-content: center;
align-items: center;
}
body { margin : 0; }
<div id='background'>
<div id="modal">
<div id="title"></div>
<div id="content">
<div id="scroll">
<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 class="item">6</div>
</div>
<div id="footer">FOOTER</div>
</div>
</div>
</div>

Here is a modern CSS grid solution:
You can change around your grid-template fraction units to give more room to your header, scroll area and footer respectively. Currently the 80% height is divided into 4, with 1fr given to your header, 2fr given to your scroll area, and 1fr given to your footer.
* {
box-sizing: border-box;
}
html,
body {
height: 100vh;
}
body {
display: grid;
place-content: center;
margin: 0;
background-color: #eee;
}
.modal {
display: grid;
grid-template: 1fr 2fr 1fr / auto;
width: 300px;
height: 80%;
overflow: hidden;
}
header {
background-color: black;
}
.scroll {
overflow-y: auto;
}
.item {
font-size: 1.1rem;
text-align: center;
line-height: 3rem;
border-bottom: 1px solid #ccc;
}
footer {
font-size: 1.1rem;
text-align: center;
background-color: #333;
color: white;
}
<article class="modal">
<header></header>
<div class="scroll">
<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 class="item">6</div>
</div>
<footer>FOOTER</footer>
</article>
Codepen: https://codepen.io/zachjensz/pen/MWrBVbv

Related

Element does not expand to fill parent flex div

html,
body {
margin: 0;
height: 100%;
}
.navbar {
position: fixed;
top: 0;
width: 100%;
height: 50px;
background-color: #2D4256;
}
.nav-centre {
margin: 0 auto;
width: 40%;
height: 100%;
}
.nav-container {
display: flex;
height: 100%;
align-items: center;
/* vertically centre */
}
.nav-item {
color: white;
width: 40px;
text-align: center;
}
.main-content {
height: calc(100% - 50px);
width: 100%;
position: absolute;
bottom: 0;
overflow-y: overlay;
display: flex;
justify-content: center;
}
.main-wrap {
width: 40%;
border-left: 1px solid black;
border-right: 1px solid black;
}
.box {
width: 200px;
height: 200px;
background: white;
border: 1px solid black;
margin: 10px;
}
<body>
<div class="navbar">
<div class="nav-centre">
<div class="nav-container">
<div class="nav-item">1</div>
<div class="nav-item">2</div>
<div class="nav-item">3</div>
<div class="nav-item">4</div>
</div>
</div>
</div>
<div class="main-content">
<div class="main-wrap">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
</body>
The main-wrap div is not expanding to fill the parent main-content div, how can I get the main-wrap element to expand to the full height of the parent?
https://codepen.io/woooof/pen/VwBLprj
The .main-wrapper is getting by default display:block, which doesn't match with the display:flex parent.
To get the value from the parent, you can use display: inherit. Once done, the elements inside won't respect their width. To fix that, you must wrap the elements, and for making it total height, You can use max-content.
.main-wrapper {
display: inherit;
flex-wrap: wrap;
height: max-content;
}
Result:
html,
body {
margin: 0;
height: 100%;
}
.navbar {
position: fixed;
top: 0;
width: 100%;
height: 50px;
background-color: #2D4256;
}
.nav-centre {
margin: 0 auto;
width: 40%;
height: 100%;
}
.nav-container {
display: flex;
height: 100%;
align-items: center;
/* vertically centre */
}
.nav-item {
color: white;
width: 40px;
text-align: center;
}
.main-content {
height: calc(100% - 50px);
width: 100%;
position: absolute;
bottom: 0;
overflow-y: overlay;
display: flex;
justify-content: center;
}
.main-wrap {
width: 40%;
border-left: 1px solid black;
border-right: 1px solid black;
display: inherit;
flex-wrap: wrap;
height: max-content;
}
.box {
width: 200px;
height: 200px;
background: white;
border: 1px solid black;
margin: 10px;
}
<body>
<div class="navbar">
<div class="nav-centre">
<div class="nav-container">
<div class="nav-item">1</div>
<div class="nav-item">2</div>
<div class="nav-item">3</div>
<div class="nav-item">4</div>
</div>
</div>
</div>
<div class="main-content">
<div class="main-wrap">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
</body>
I am not a huge fan of making the size of one element (navbar) determine the position of the second element main-content (margin-top). where you have height: calc(100% - 50px); I would rather if the style of the first changes. Say for example we increase navbar font size, you would not need to adjust the second manually.
Here in this example I set the font-size on an ancestor block to change the nav buttons size and not have to change the content. font-size: 1.5rem;
Change it even larger; again no change to the content CSS;
I put a lot of comments in and some borders just to show where things line - that can and should all be removed for a production version.
html,
body {
margin: 0;
height: 100%;
/* stack the nav and the content blocks */
display: grid;
grid-template-rows: 1fr auto;
}
.navbar {
/* put the navbar at the top */
position: sticky;
top: 0;
background-color: #2D4256;
/* flex, default vertical/horizontal centers nav-centre in the flex */
display: flex;
}
.nav-centre {
margin: 0 auto;
display: flex;
}
.nav-container {
display: flex;
/* again these are the default here
flex-direction: row;
align-items: center;
justify-content: center;
*/
/* how much space above and below the yellow border nav container */
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
.nav-item {
color: white;
/* 2 times font-size for cyan border items */
width: 2em;
text-align: center;
}
.main-content {
display: grid;
justify-content: center;
}
.main-wrap {
border-left: 1px solid black;
border-right: 1px solid black;
}
.box {
width: 200px;
height: 200px;
background: white;
border: 1px solid black;
margin: 10px;
}
/* below here is just for visual clarification and can be removed */
.navbar {
/* just to show you can style and not effect content block *
/* this can be on any of the three containers */
font-size: 1.5rem;
font-family: Verdana, Arial, Helvetica, sans-serif;
}
.nav-centre {
border: 1px solid magenta;
padding: 2px;
}
.nav-container {
border: 1px solid yellow;
}
.nav-item {
border: 1px solid cyan;
/* you can space out the nav buttons */
margin: 0 0.25rem;
}
.main-content {
/* just to show it is below the navbar and separate */
border: solid red 1px;
margin-top: 0.25rem;
margin-left: 0.5rem;
margin-right: 0.5rem;
}
.box {
background-color: #ffffdd;
}
<body>
<div class="navbar">
<div class="nav-centre">
<div class="nav-container">
<div class="nav-item">1</div>
<div class="nav-item">2</div>
<div class="nav-item">3</div>
<div class="nav-item">4</div>
</div>
</div>
</div>
<div class="main-content">
<div class="main-wrap">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
</body>

image goes out from grid and sizing issue

I'm pretty new to coding, and I'm trying to use a grid.
But I got stuck a little bit.
I have the following codePan project:
* {
box-sizing:border-box
}
body {
height:100vh;
width: 100%;
background-color: red;
padding:0;
margin:0;
}
#wrapper {
background-color:blue;
height:100%;
width:100%;
margin:0;
padding:0;
display: grid;
grid-template-areas:
"nav"
"content"
"footer" ;
grid-template-columns: 1fr;
grid-template-rows: .8fr 1fr .8fr ;
}
#nav {
background-color: yellow;
grid-area: "nav";
position: sticky;
top: 0;
}
#content {
background-color: pink;
grid-area: "nav";
display:flex;
flex-direction: column;
}
footer {
background-color: brown;
grid-area: "nav";
}
#box1 {
background-color:purple;
height:50%;
}
#box2 {
background-color: blue;
height:60%;
display:flex;
flex-direction: column;
}
.image {
height: auto;
width: 400px;
position: relative;
top:-150px;
}
button {
height: 90px;
width: 400px;
background-color: #262A58;
color: white;
font-size: 1.5em;
font-family: 'EightOne';
border-radius: 10px;
border-style: none;
cursor: pointer;
}
<div id="wrapper">
<div id="nav"> nav </div>
<div id="content">
<div id="box1">
<h1>flower</h1>
</div>
<div id="box2">
<img class="image" src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.goldpetal.net%2Fmedia%2Fimages%2Fproduct_gallery%2FGerbera_Flower_12.jpg&f=1&nofb=1" alt="">
<button> buy flower </button>
</div>
</div>
<footer>
footer
</footer>
</div>
what i want is the similar like on this picture:
picture
unfortunatly i can not postitioning, the contents in the Box2, becuase the button goes out completly out from grid.
I tried several options, but at the end it was always some issue with the content in the Box2.
if someone could give me an advice. Probably I'm using wrong way Grid...
Thank you!
Let your grid define the size of the areas, and use Flexbox to lay out your content.
You can absolutely achieve this layout with CSS Grid. The button was overflowing its content area because #box2 has a fixed height of 60% of the content grid area, but your .image and the button are taller than that. Basically your image pushes down the button.
You don’t need to set explicit heights on your content, because that’s taken care of the grid.
The white-blue background is a bit tricky, because it doesn’t align exactly with the edges of your image. But you can achieve this affect with a background gradient on your content container.
Check out this working solution as inspiration:
body {
height: 100vh;
padding: 0;
margin: 0;
}
#wrapper {
height: 100%;
width: 100%;
display: grid;
grid-template-areas:
'nav'
'content'
'footer';
grid-template-columns: 1fr;
grid-template-rows: 64px 1fr 96px;
}
#nav {
grid-area: nav;
position: sticky;
top: 0;
background-color: white;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
}
#content {
grid-area: content;
display: flex;
flex-direction: column;
justify-content: center;
background: linear-gradient(to bottom, transparent 60%, #aad 60%);
align-items: center;
padding: 32px;
}
#content .wrapper {
display: flex;
flex-direction: column;
width: 400px;
}
footer {
grid-area: footer;
}
.image {
border: solid 16px #aad;
margin: 16px;
}
button {
padding: 8px 16px;
background-color: #262a58;
color: white;
font-size: 1.5em;
font-family: 'EightOne';
border-radius: 10px;
border-style: none;
cursor: pointer;
margin-top: 32px;
align-self: center;
}
<div id="wrapper">
<div id="nav">nav</div>
<div id="content">
<div class="wrapper">
<h1>flower</h1>
<img
class="image"
src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.goldpetal.net%2Fmedia%2Fimages%2Fproduct_gallery%2FGerbera_Flower_12.jpg&f=1&nofb=1"
alt="Flower"
/>
<button>buy flower</button>
</div>
</div>
<footer>footer</footer>
</div>
Grid is not really used to make a full webpage. Everything is automatically stacked on top of eachother and should not have a fixed height. The height should changed based on the content.

Horizontally-scrolling div inside a flex column

I can't seem to have a horizontally-scrolling div inside a flex column.
Codepen
.container { display: flex; margin: 20px; height: 300px; border: 1px solid blue; }
.side-nav { flex-shrink: 0; width: 100px; min-height: 100%; background: grey; }
.main { padding: 20px; }
.scrollable { overflow-x: auto; max-width: 100%; }
.long-content { width: 2000px; height: 50px; background: red; }
<div class='container'>
<div class='side-nav'>
</div>
<div class='main'>
<h1>Test</h1>
<div class='scrollable'>
<div class='long-content'>
This is supposed to scroll horizontally unless your window is super wide
</div>
</div>
<p>Some paragraph below the scrollable box</p>
</div>
</div>
If I change the max-width of .scrollable to px it would work, but I need it to fill the column.
What am I missing?
In my opinion, this is a Module"bug" (Wierd).
Anyway, one very simple solution is to use flex-basis (Instead of width).
Step 1 for main add width: 0;
.container {
display: flex;
margin: 20px;
height: 300px;
border: 1px solid blue;
}
.side-nav { flex-shrink: 0; width: 100px; min-height: 100%; background: grey; }
.main {
padding: 20px;
border: 5px dashed orange;
/* "new code" */
width: 0px;
}
.scrollable { overflow-x: auto; max-width: 100%; }
.long-content { width: 2000px; height: 50px; background: red; }
<div class='container'>
<aside class='side-nav'>
Aside
</aside>
<main class='main'>
<h1>Test</h1>
<div class='scrollable'>
<div class='long-content'>
This is supposed to scroll horizontally unless your window is super wide
</div>
</div>
<p>Some paragraph below the scrollable box</p>
</main>
</div>
Step 2 - main add flex-basis: 100%;
.container {
display: flex;
margin: 20px;
height: 300px;
border: 1px solid blue;
}
.side-nav { flex-shrink: 0; width: 100px; min-height: 100%; background: grey; }
.main {
padding: 20px;
border: 5px dashed orange;
/* "new code" */
width: 0px;
flex-basis: 100%;
}
.scrollable { overflow-x: auto; max-width: 100%; }
.long-content { width: 2000px; height: 50px; background: red; }
<div class='container'>
<aside class='side-nav'>
Aside
</aside>
<main class='main'>
<h1>Test</h1>
<div class='scrollable'>
<div class='long-content'>
This is supposed to scroll horizontally unless your window is super wide
</div>
</div>
<p>Some paragraph below the scrollable box</p>
</main>
</div>
One more option is to use width: 0; & flex-grow:1
.container {
display: flex;
margin: 20px;
height: 300px;
border: 1px solid blue;
}
.side-nav { flex-shrink: 0; width: 100px; min-height: 100%; background: grey; }
.main {
padding: 20px;
border: 5px dashed orange;
/* "new code" */
width: 0px;
flex-grow: 1;
}
.scrollable { overflow-x: auto; max-width: 100%; }
.long-content { width: 2000px; height: 50px; background: red; }
<div class='container'>
<aside class='side-nav'>
Aside
</aside>
<main class='main'>
<h1>Test</h1>
<div class='scrollable'>
<div class='long-content'>
This is supposed to scroll horizontally unless your window is super wide
</div>
</div>
<p>Some paragraph below the scrollable box</p>
</main>
</div>
I don't like any of those ideas - but this is life hh.

How to shrink the width of div when the elements are removed in resize div

Question: I am having two div's A & B where DIV A is having min and max width with resize horizontal feature and Div B is auto width.
Now when Div A has 4 divs in it when each div is removed the width of DIVA is auto shrinked but when i dragg div A to right and remove an element in DIV A the width is not auto
.resizeE {
border-right: 6px solid;
display: flex;
align-items: stretch;
justify-content: flex-start;
align-content: center;
width: auto;
min-width: 150px;
max-width: 250px;
height: 100%;
resize: horizontal;
overflow: auto;
}
.E1 .E2 .E3 .E4 {
border: 2px solid #A0A0A0;
width: 50px;
height: 50px;
}
.box {
width: 30px;
float: left;
margin: 5px;
}
.red {
color: red;
background: pink;
}
.blue {
color: blue;
background: light-blue;
}
.green {
color: green;
background: pink;
}
.map {
width: 100%;
}
<div style="height:100%;width:100%;background: #e2e2e2;overflow-y: hidden;overflow-x: hidden;">
<div class="resizeE">
<div class="red box">E1</div>
<div class="red box">E2</div>
<div class="blue box">E3</div>
<div class="green box">E4</div>
</div>
<div class="col p-5">
<div class="map">
block B
</div>
</div>
</div>

How can I align a big div next to three stacked divs?

Three small divs, stacked upon each other, with a big three-small-divs-high div on their right side. How do I do this? Does Bootstrap have anything prepared for it?
You don't need to use any framework, you can do this with Flexbox.
.content {
display: flex;
}
.left {
display: flex;
flex-direction: column;
flex: 1;
}
.box {
padding-bottom: 50px;
}
.right {
flex: 3;
background: #22B14C;
}
.box:nth-child(1) {background: #ED1C24;}
.box:nth-child(2) {background: #00A2E8;}
.box:nth-child(3) {background: #FFAEC9;}
<div class="content">
<div class="left">
<div class="box">Small DIv</div>
<div class="box">Small DIv</div>
<div class="box">Small DIv</div>
</div>
<div class="right">Big div</div>
</div>
This should do it:
#left, #right {
float: left;
font-weight: bold;
font-family: Calibri, sans-serif;
font-size: 20px;
}
#left .small {
display: block;
width: 200px;
height: 55px;
padding: 12px;
box-sizing: border-box;
}
#right {
display: block;
width: 400px;
height: 165px;
padding: 20px;
box-sizing: border-box;
font-size: 60px;
}
<div id="left">
<div class="small" style="color: #22B14C; background-color: #ED1C24">Small div</div>
<div class="small" style="color: #FFAEC9; background-color: #00A2E8">Small div</div>
<div class="small" style="color: #ED1C24; background-color: #FFAEC9">Small div</div>
</div>
<div id="right" style="color: #0099DB; background-color: #22B14C">Big div</div>
If you want that it has a width of 100%, use
#right {
/* ... */
width: calc(100% - 200px);
}

Resources