Best practice for splitting viewport with CSS flex - css

Hoping this is not a nonsense question as it is in a way a tad non-specific.
It's quite simple - I am aiming to produce a design splitting the viewport/screen into rough halves (60/40) vertically, similar to how AirBnB do: -
AirBnB New York
Is this just as simple as using flexbox columns (I am using Bootstrap 4), specifying the column widths and setting the right-hand side column to position: fixed?
Any advice that anyone has would be most welcome as I have never approached this type of design before and I want to make sure I am not overlooking anything.

Here's a flex layout based solution.
html,
body {
height: 100%;
margin: 0
}
.box {
display: flex;
flex-flow: column;
height: 100%;
}
.box .row {
border: 1px dotted grey;
}
.box .row.header {
flex: 0 1 60vh;
}
.box .row.content {
flex: 1 1 40vh;
}
<div class="box">
<div class="row header">
<p><b>header</b>
(60%)</p>
</div>
<div class="row content">
<p>
<b>content</b>
(40%)
</p>
</div>
</div>

Related

How to fix flexbox overlapping divs when using media query?

I'm asking my first question here, so I apologize in advance if I didn't explain something well.
I'm currently developing portfolio website (Angular 13 with Sass). I've come to a point where I have two divs placed next to each other inside of a flexbox. I use media query (mobile view) to achieve divs to place below each other. One div contains text and other image.
I'm using Sass for flex box
#mixin flex-container($flexdirection, $justifycontent: false) {
#if $justifycontent {
justify-content: $justifycontent;
} #else {
justify-content: center;
}
display: flex;
flex-wrap: wrap;
row-gap: 20px;
align-items: center;
flex-direction: $flexdirection;
}
HTML component looks like this
<div class="about" id="about" #about>
<div class="about__details">
<h1 class="about__title">{{title}}<span class="purple_highlight">A</span>ndjela. <span class="wave">👋</span>
</h1>
<p class="about__paragraph">{{paragraph}}
</p>
<a href="https://drive.google.com/file/d/1PK82zuN4g_Ly5nmNIgRpIsEW9j_gnyaS/view?usp=share_link" target="_blank">
<button class="about__cv_button">My resume</button>
</a>
</div>
<div class="about__img">
<img src="assets/img/profilePicture.png" alt="profile">
</div>
</div>
CSS looks like this
#include mq-between(xs, sm) {
.about {
#include flex-container(row);
height: 100vh;
&__img {
background-color: aqua;
bottom: 0;
right: 0;
flex-shrink: 0;
}
img {
max-width: 100%;
max-height: 100%;
}
&__details {
background-color: blanchedalmond;
left: 10%;
right: 10%;
}
}
}
Result looks like in picture
I've tried using flex-direction as column, flex-basis, max-width, max-height, padding and margin, but nothing seems to make changes for what I'm looking for.
What am I missing to show the divs beneath each other with the correct height?

Two-Column Newspaper Layout with CSS Grid

I've got CSS grid to produce a two-column layout. But the problem is that it's not top-aligning content in each column.
For example, in the second column, the last element should top-align to but up against the other column-two element.
body>div {
display: grid;
grid-template-columns: 50% 50%;
grid-template-rows: auto auto;
grid-auto-flow: column;
/* https://codepen.io/maddesigns/pen/oZGWRN */
/* https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow */
}
body>div>div:nth-of-type(1) {
height: 300px;
}
body>div>div:nth-of-type(2) {
height: 100px;
}
body>div>div:nth-of-type(3) {
height: 200px;
}
<div style="">
<div style="background:red">
1
</div>
<div style="background:green;">
2
</div>
<div style="background:yellow">
3
</div>
<div style="background:pink">
4
</div>
</div>
I couldn't use flex for this layout because I wanted to achieve this layout without defining the container height. column-count:2 would have worked without defining the container height but then I couldn't use div reordering.
So I'm using CSS grid because div reordering is still available (e.g./i.e. order:–1; works well) and it auto-divies up what to put in each of the two columns.
The gird is acting exactly as intended, to keep order and symmetry just like this. I can recommend using 2 grids side by side to achieve what you're looking for. Here's an example that I made to demonstrate this:
.left{
display: grid;
grid-template-rows: auto auto;
grid-auto-flow: column;
width: 50%;
float: left;
/* https://codepen.io/maddesigns/pen/oZGWRN */
/* https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow */
}
.right{
display: grid;
grid-template-rows: auto auto;
grid-auto-flow: column;
width: 50%;
/* https://codepen.io/maddesigns/pen/oZGWRN */
/* https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow */
}
.left>div:nth-of-type(1) {
height: 300px;
}
.left>div:nth-of-type(2) {
height: 100px;
}
.right>div:nth-of-type(1) {
height: 200px;
}
.right>div:nth-of-type(2) {
height: 50px;
}
<div class="left" style="">
<div style="background:red">
1
</div>
<div style="background:green;">
2
</div>
</div>
<div class="right">
<div style="background:yellow">
3
</div>
<div style="background:pink">
4
</div>
</div>
In fact, until a CSS technology arrives with the ability to automatically close the gaps, CSS in general has no solution. Something like this would probably require reflowing the document, so I'm not sure how useful or efficient it would be.
Source: https://stackoverflow.com/a/45200955/1625909

Display Flex Centre & Bottom

I'm trying to create a full height header and have one element centre and another element at the bottom.
I have always used position: absolute; to do this, but I would like to use flex instead.
.full-header {
background-color: green;
display: flex;
}
.align-item-center {
background-color: blue;
}
.align-item-end {
background-color: red;
}
<div class="container full-header">
<div class="align-item-center">
Row 1
</div>
<div class="align-item-end">
Row 2
</div>
</div>
I have attached a diagram to help communicate what I'm trying to do. I am also using bootstrap 4, although if someone can point me in the direction of native flex, that would also be great.
You can achieve this by doing the following:
Set the flex-direction of .full-header to column. This will order the child divs from top to bottom
Add an automatic top and bottom margin to .align-item-center. This will ensure that the top and bottom margins of .align-item-center will automatically extend to occupy the available space in .full-header
body {
margin: 0;
}
.full-header {
background-color: green;
display: flex;
flex-direction: column;
height: 100vh;
}
.align-item-center {
background-color: blue;
margin: auto 0;
}
.align-item-end {
background-color: red;
}
<div class="container full-header">
<div class="align-item-center">
Row 1
</div>
<div class="align-item-end">
Row 2
</div>
</div>

Make flex item with flexible size keep its size when children overflow [duplicate]

This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 5 years ago.
This one is really frustrating me and Im not sure if I worded that correctly.
Basicly, I need my page to stay at 100% height and not grow in height as it is a single page website.
I have a list in an aside and whenever I add content to the list it makes the list grow in size when I need the overflow to be hidden (I have a custom scrollbar applied in react).
Anyhow, the growing (weirdly) only occures when the list has the height of flex: 1;. When I add a fixed height, everything is fine.
Here is how it acts with a fixed height (should also be like this when no fixed height is applied):
When I remove the fixed height of the red box (the list) then it causes itself and the whole page to grow:
See it in action:
Heres the pen to see for yourself: https://codepen.io/anon/pen/zPJdoK
I know theres some unnecassary markup but I needed that to be sure that it represents the actual webpage I am working on.
Sorry for not being able to explain it any more detailed, Im a bit confused as of now...
Are you referring to something like this perhaps? I'm not too sure.
.container{
background: black;
width: 1000px;
height: 300px;
display: grid;
grid-template-columns: 180px 1fr 180px;
grid-template-rows: 1fr;
grid-template-areas: "nav main aside";
}
nav {
grid-area: nav;
background: blue;
}
main {
grid-area: main;
background: black;
display: flex;
flex-direction: column;
}
aside {
grid-area: aside;
background: green;
display: flex;
flex-direction: column;
}
aside > header, aside > footer{
height: 60px;
background: yellow;
}
aside > main {
flex: 3;
background: green;
}
aside > main > .content {
background: red;
margin: 10px;
max-height: 200px;
overflow-y:scroll;
}
.space_taker{
margin: 10px;
height: 30px;
background: white;
}
<div class="container">
<nav></nav>
<main></main>
<aside>
<header>
</header>
<main>
<div class="content">
<div class="space_taker">asdafasdfasdf</div>
<div class="space_taker">asdfasdf</div>
<div class="space_taker">asdfs</div>
<div class="space_taker">dfgdgf</div>
<div class="space_taker">asdasd</div>
<div class="space_taker">asdasd</div>
<div class="space_taker">asdfs</div>
<div class="space_taker">dfgdgf</div>
<div class="space_taker">asdasd</div>
<div class="space_taker">asdasd</div>
<div class="space_taker">asdfs</div>
<div class="space_taker">dfgdgf</div>
<div class="space_taker">asdasd</div>
<div class="space_taker">asdasd</div>
</div>
</main>
<footer>
</footer>
</aside>
</div>

Using calc() with a dynamic value?

I am wondering if this is possible: I have a header that can contain a variable amount of text. Below that I have another element which I want to take up the remaining height of the page.
<div class="header row">
<div class="title column large-5">Potentially very long text</div>
<div class="menu column large-7">Menu items</div>
</div>
<div class="content">
</div>
<div class="footer">
</div>
Normally I would do this using calc, eg:
.content {
height: calc(100vh - 75px);
}
Where 75px is the set height of .header.
But in this example, the .header element is dynamic and does not have a set height. Only a padding and font-size are set.
To complicate things, this also uses the Foundation Grid layout, which makes me nervous about using display: table (.title and .menu sit side by side on desktop, but stacked on mobile) .
Is there anyway to get the height of the dynamic header element (without resorting to JQuery)?
You can use flexbox and set .content to flex-grow: 1 so that it will fill to grow the available space.
body {
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
}
.content {
flex-grow: 1;
background: #eee;
}
<div class="header row">
<div class="title column large-5">Potentially very long text</div>
<div class="menu column large-7">Menu items</div>
</div>
<div class="content">
</div>
<div class="footer">
</div>
I made a small pen to show the way to do this using flex box, it involved changing your markup a bit:
css:
.container {
display: flex;
flex-direction: column;
height: 250px; // whatever you want here
}
.header {
width: 100%;
background: red;
padding: 10px;
}
.content {
background: yellow;
width: 100%;
flex-grow: 1;
}
So the content will always take the available space inside the content div.
check the whole pen: http://codepen.io/anshul119/pen/yMYeLa
hope this helps.

Resources