Flexbox child not reading height/width of parent - css

I was experimenting with flexbox and created this layout. I'm trying to get the middle white box that says "hey" to be 90% width/height of the parent but percentages don't seem to affect it. (I have it set as 100px/100px currently which works)
It's strange since the parent has a defined width/height on inspection.
Can anyone tell me how to implement that? (also, general critique on how I used flexbox appreciated as well)
http://jsfiddle.net/yv3Lw5gy/1/
relevant class:
.super-thing{
height: 100px;
width: 100px;
background-color: white;
margin:auto;
box-shadow: 2px 1px 1px #000;
}

The .body parent of .super-thing is display: flex so its children don't inherit its height or width if they don't have flex properties.
###The power of flex compels you!
Set flex: 1 on .super-thing so it grows and shrinks with a 1% margin to create a gap. There is no need for a width or height.
.super-thing {
background-color: white;
margin: 1%;
box-shadow: 2px 1px 1px #000;
flex: 1;
}
###Complete Example
In this example, the box-sizing: border-box and the removal of the margin to be replaced with padding on <body>, get the entire container properly sized in the viewport so there is no scrollbar.
* {
background-color: rgba(255, 0, 0, .2);
box-sizing: border-box;
}
* * {
background-color: rgba(0, 255, 0, .2);
}
* * * {
background-color: rgba(0, 0, 255, .2);
}
* * * * {
background-color: rgba(255, 0, 255, .2);
}
* * * * * {
background-color: rgba(0, 255, 255, .2);
}
* * * * * * {
background-color: rgba(255, 255, 0, .2);
}
html,
body,
.container {
height: 100%;
}
body {
padding: 10px;
margin: 0;
}
.container {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: stretch;
/* align-content: center; */
}
.header {
flex: 1 0 30px;
display: flex;
}
.header-left {
flex: 11 0 auto;
}
.header-right {
flex: 1 0 auto;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
.header-right .small-item {
width: 100%;
outline: 1px solid #fff;
}
.main {
background-color: #fff;
flex: 10 0 30px;
display: flex;
}
.left-column {
flex: 3;
flex-direction: column;
display: flex;
justify-content: center;
}
.left-column .story {
flex: 2;
outline: 1px solid white;
/* margin:auto; */
}
.right-column {
flex: 12;
background-color: #f0f;
display: flex;
flex-direction: column;
}
.right-column-body {
flex: 10;
display: flex;
flex-direction: column;
}
.right-column-body .header {
flex: 1;
display: flex;
justify-content: center;
}
.thing {
width: 20%;
margin: 5px
}
.super-thing {
background-color: white;
margin: 1%;
box-shadow: 2px 1px 1px #000;
flex: 1;
}
.right-column-body .body {
background-color: #ccc;
flex: 5;
display: flex;
flex-direction: column;
justify-content: center;
}
.right-column-footer {
flex: 1;
background-color: white;
}
.footer {
flex: 1 0 30px;
}
<div class="container">
<div class="header">
<div class="header-left">Left</div>
<div class="header-right">
<div class="small-item">A</div>
<div class="small-item">B</div>
<div class="small-item">C</div>
<div class="small-item">D</div>
</div>
</div>
<div class="main">
<div class="left-column">
<span class="story">A</span>
<span class="story">A</span>
<span class="story">A</span>
<span class="story">A</span>
</div>
<div class="right-column">
<div class="right-column-body">
<div class="header">
<div class="thing">A</div>
<div class="thing">B</div>
<div class="thing">C</div>
</div>
<div class="body">
<div class="super-thing">Hey</div>
</div>
<div class="right-column-footer">Footer</div>
</div>
</div>
</div>
<div class="footer">Footer</div>
</div>

Related

Burger Menu Placement in Flexbox

I want to build a little note taking app but i cant figure out how i can put a burger menu on the right side of the flexbox. Down here you can find my js and css file:
JavaScript / HTML
<div className={styles.wrapper}>
<main className={styles.content}>
<div className={styles.templatelist}>
<div className={styles.template}>
<h2>Daily Meeting Minutes</h2>
<div className={styles.properties}>
<p>Sections: 5</p>
<p>Questions: 5</p>
<p>Tables: 5</p>
</div>
</div>
</div>
</main>
</div>
I have tried to create a new div and position it with top and left but nothing seems to work for me.
CSS
.wrapper {
display: flex;
margin-top: 2rem;
}
.content {
display: flex;
flex-direction: column;
margin: auto;
width: 50%;
height: 100%;
}
.templatelist {
margin-top: 2rem;
display: flex;
flex-direction: column;
}
.template {
width: 100%;
height: 6rem;
border-radius: 1rem;
padding: 1rem;
background: rgba(255, 255, 255, 0);
border-radius: 16px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(13.3px);
-webkit-backdrop-filter: blur(13.3px);
border: 1px solid rgba(255,153,0, .5);
}
.properties {
display: flex;
flex-direction: row;
margin-top: 1rem;
gap: 2rem;
}
Codepen
https://codepen.io/Vylex/pen/ZERgxzm
Desired outcome
.template {
width: 100%;
height: 6rem;
border-radius: 1rem;
padding: 1rem;
background: rgba(255, 255, 255, 0);
border-radius: 16px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(13.3px);
-webkit-backdrop-filter: blur(13.3px);
border: 1px solid rgba(255,153,0, .5);
display: flex;
justify-content: space-between;
}
.properties {
display: flex;
flex-direction: column;
}
p {
margin: .5rem;
}
I recommend you do the following:
<div class="templatelist">
<div class="template">
<h2>Daily Meeting Minutes</h2>
<div class="properties">
<p>Sections: 5</p>
<p>Questions: 5</p>
<p>Tables: 5</p>
</div>
</div>
<div class="menu">Burger</div>
keep the border and everything in the templateList class. Use the display to flex, flex-direction to row, and justify-content to space-between. I believe this will work for you.
CSS and HTML
.wrapper {
display: flex;
margin-top: 2rem;
}
.content {
display: flex;
flex-direction: column;
margin: auto;
width: 50%;
height: 100%;
}
.templatelist {
margin-top: 2rem;
display: flex;
flex-direction: column;
}
.template {
width: 100%;
border-radius: 1rem;
padding: 1rem;
background: rgba(255, 255, 255, 0);
border-radius: 16px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(13.3px);
-webkit-backdrop-filter: blur(13.3px);
border: 1px solid rgba(255,153,0, .5);
}
.properties {
display: flex;
flex-direction: row;
gap: 2rem;
justify-content: space-between;
align-items: center;
}
.burger{
font-size: 2em;
}
.options{
display: flex;
column-gap: 1em;
}
<div class="wrapper">
<main class="content">
<div class="templatelist">
<div class="template">
<div class="properties">
<div class="left">
<h2>Daily Meeting Minutes</h2>
<div class="options">
<p>Sections: 5</p>
<p>Questions: 5</p>
<p>Tables: 5</p>
</div>
</div>
<div class="burger">
<p>:</p>
</div>
</div>
</div>
</div>
</main>
</div>

Flex container's width doesn't expand when flex item is styled by aspect-ratio

I want to make a square element #board responsive.
Unfortunately, in landscape view, the flex container #wrap doesn't expand it's width to the width of the flex item #board. When I apply a fixed width and height to #board it does, thus the reason seems to be the aspect-ratio.
What's the reason for this, did I do anything wrong? How can I fix it?
I used this HTML and CSS:
html,
body {
height: 100%;
}
body {
margin: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 26%, rgba(89, 177, 185, 1) 100%);
}
#wrap {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border: 2px solid blue;
}
#timer,
#home {
font-size: 7.5vh;
}
#board {
flex: 1;
background-color: lightblue;
aspect-ratio: 1 / 1;
}
<div id="wrap">
<div id="timer">00:00:00</div>
<div id="board"></div>
<div id="home">Home</div>
</div>
Remove flex: 1 from #board and add height: 100% to it instead:
html,
body {
height: 100%;
}
body {
margin: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 26%, rgba(89, 177, 185, 1) 100%);
}
#wrap {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border: 2px solid blue;
}
#timer,
#home {
font-size: 7.5vh;
}
#board {
height: 100%;
background-color: lightblue;
aspect-ratio: 1 / 1;
}
<div id="wrap">
<div id="timer">00:00:00</div>
<div id="board"></div>
<div id="home">Home</div>
</div>

Make child div fill parent div with scroll

I am having problems with flexbox layout parenting a child control.
html, body, .frame{
margin: 0;
height: 100%;
}
* {
box-sizing: border-box;
}
.frame{
display: flex;
flex-flow: column;
}
.header{
background-color: yellow;
height: 40px;
}
.body-outer{
background-color: green;
flex: 1;
display: flex;
flex-flow: column;
}
.body-inner{
border: 1px solid red;
flex: 1;
}
.big-text{
height: 2000px;
border: 1px solid lightblue;
overflow: auto;
margin: 5px;
}
<div class="frame">
<div class="header">header</div>
<div class="body-outer">
<div>subheader</div>
<div class="body-inner>">
<div class="big-text">big text</div>
</div>
</div>
</div>
The 'body-inner' div is meant to fill the remaining space with flex: 1 and the 'big-text' is supposed to fill the whole space of 'body-inner' without expanding it but showing scroll bars.
You have the overflow applied to the content. It should be applied to the container that will be overflowed.
Also, you need a fixed height, so that the overflow property has something to overflow.
Try this:
.frame {
display: flex;
flex-flow: column;
height: 100vh;
}
.header {
background-color: yellow;
height: 40px;
}
.body-outer {
height: calc(100vh - 40px); /* new */
background-color: green;
/* flex: 1; */
display: flex;
flex-flow: column;
}
.body-inner {
border: 1px solid red;
flex: 1;
overflow: auto; /* moved here */
}
.big-text {
height: 2000px;
border: 1px solid lightblue;
/* overflow: auto; */
margin: 5px;
}
body {
margin: 0;
}
* {
box-sizing: border-box;
}
<div class="frame">
<div class="header">header</div>
<div class="body-outer">
<div>subheader</div>
<div class="body-inner">
<div class="big-text">big text</div>
</div>
</div>
</div>

Grid Element expand animations using CSS

I have the following
setTimeout(function(){
var sections = document.querySelectorAll('section'), main = document.querySelector('.grid-container'),
//section = sections[Math.floor(Math.random() * 3)];
section = sections[1];
section.classList.add('expand');
section.parentElement.classList.add('expand');
main.classList.add('expanding');
}, 2000);
*{
box-sizing : border-box;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.grid-container {
width:100%;
height: 100vh;
display:flex;
border: 1px solid;
flex-wrap: wrap;
flex-direction: column;
}
.grid-row, .grid-container {
overflow:hidden;
}
.grid-column, .grid-row {
display: flex;
transition: width .2s, height .2s, margin .2s, transform .2s;
}
.grid-column {
width: inherit;
height: inherit;
align-items: center;
justify-items: center;
}
.grid-column:nth-child(1) {
background-color:green;
}
.grid-column:nth-child(2) {
background-color:orange;
}
.grid-row:nth-child(2) .grid-column:nth-child(1) {
background-color:violet;
}
.grid-row:nth-child(2) .grid-column:nth-child(2) {
background-color:brown;
}
#media screen and (orientation: portrait) {
.grid-row {
width: 100%;
height: 50%;
flex-direction: column;
}
.grid-column {
width: 100%;
height: 50%;
}
.grid-row.expand .grid-column {
transform: translateY(-50%);
}
}
#media screen and (orientation: landscape) {
.grid-row {
width: 50%;
height: 100%;
}
.grid-column {
width: 50%;
height: 100%;
}
}
#media screen and (min-height: 500px) {
.grid-row {
height: 50%;
width: 100%;
}
}
.expanding .expand {
width: 100% !important;
height: 100% !important;
}
<main class="grid-container">
<div class="grid-row" data-index="1">
<section class="grid-column" data-index="1">
<article>
<p>
1
</p>
</article>
</section>
<section class="grid-column" data-index="2">
<article>
<p>
2
</p>
</article>
</section>
</div>
<div class="grid-row" data-index="2">
<section class="grid-column" data-index="1">
<article>
<p>
3
</p>
</article>
</section>
<section class="grid-column" data-index="2">
<article>
<p>
4
</p>
</article>
</section>
</div>
</main>
that I'm trying to develop where the "cells" in the grid that when expands to full area of the view will animate to as if its "pushing" the adjacent elements out of the view.
I'm trying to use a combination of width, height and transforms to give the appropriate animation but the transforms seem to give some unexpected results...
Is there a way to accomplish this WITHOUT position:absolute or with as little javascript as possible??
Here's an example seemingly doing what you want, coded from scratch, without any JavaScript. I used flexbox instead of grid, but it can be achieved with grid as well. I used :hover as a trigger:
body {
padding: 15px;
background-color: #999;
margin: 0;
}
.grid>*:hover,
.grid>*>*:hover {
flex-grow: 3;
}
.grid>*>*:hover {
box-shadow: 0 4px 5px -2px rgba(0, 0, 0, .2), 0 7px 10px 1px rgba(0, 0, 0, .14), 0 2px 16px 1px rgba(0, 0, 0, .12);
z-index: 1;
opacity: 1;
font-size: 5rem;
}
.grid:hover>*:not(:hover) {
flex-grow: 0;
max-height: 0;
overflow: hidden;
}
.grid>*,
.grid>*>* {
transition: all .6s cubic-bezier(0.5, 0, 0.3, 1);
}
.grid {
flex-direction: column;
min-height: calc(100vh - 30px);
box-sizing: border-box;
}
.grid,
.grid>* {
display: flex;
max-height: 100%;
}
.grid>* {
flex-direction: row;
margin: 0;
}
.grid>*,
.grid>*>* {
flex-grow: 1;
}
.grid>*>* {
margin: 0;
z-index: 0;
position: relative;
background-color: #fff;
outline: 1px solid #ddd;
opacity: .95;
display: flex;
align-items: center;
justify-content: center;
line-height: 0;
font-size: 3rem;
overflow: hidden;
}
<div class="grid">
<div>
<div>1</div>
<div>2</div>
</div>
<div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
<div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
</div>
You can play around with flex-grow, change animation or the ratio between hovered and non-hovered elements but, for that, you need to define the requirements better than "seem to give some unexpected results":
You can obviously limit it to 2 + 2 elements. I just wanted to point out it's flexible in terms of structure. Here's an example, expanding to full on both vertical and horizontal:
body {
padding: 15px;
background-color: #999;
margin: 0;
}
.grid>*:hover,
.grid>*>*:hover {
flex-grow: 3;
}
.grid>*>*:hover {
box-shadow: 0 4px 5px -2px rgba(0, 0, 0, .2), 0 7px 10px 1px rgba(0, 0, 0, .14), 0 2px 16px 1px rgba(0, 0, 0, .12);
z-index: 1;
opacity: 1;
font-size: 5rem;
}
.grid:hover>*:not(:hover) {
flex-grow: 0;
max-height: 0;
overflow: hidden;
}
.grid>*:hover>*:not(:hover) {
flex-grow: 0;
flex-basis: 0;
overflow: hidden;
}
.grid>*,
.grid>*>* {
transition: all .6s cubic-bezier(0.5, 0, 0.3, 1);
}
.grid {
flex-direction: column;
min-height: calc(100vh - 30px);
box-sizing: border-box;
}
.grid,
.grid>* {
display: flex;
max-height: 100%;
}
.grid>* {
flex-direction: row;
margin: 0;
}
.grid>*,
.grid>*>* {
flex-grow: 1;
}
.grid>*>* {
margin: 0;
z-index: 0;
position: relative;
background-color: #fff;
outline: 1px solid #ddd;
opacity: .95;
display: flex;
align-items: center;
justify-content: center;
line-height: 0;
font-size: 3rem;
overflow: hidden;
max-width: 100%;
flex-basis: 100%;
flex-grow: 0;
}
<div class="grid">
<div>
<div>1</div>
<div>2</div>
</div>
<div>
<div>3</div>
<div>4</div>
</div>
</div>
Generally, I'd avoid going full width/full height, as it makes selecting another item way more difficult.

Flexbox align column to the right if there is only one column

I have a two column flexbox layout. However, sometimes there is only one column, in which case the column should be aligned to the right. Currently the column is aligned to the left.
https://codepen.io/sleepydada/pen/rzVRxL
HTML:
<div class="answers">
<div class="answer">first answer</div>
<div class="answer">second answer</div>
</div>
<div class="answers">
<div class="answer">first answer</div>
</div>
SCSS:
* {
box-sizing: border-box;
}
.answers {
border: 2px solid black;
margin-bottom: 20px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
&:first-of-type {
background: #ccc;
}
.answer {
background: crimson;
margin: 20px 0;
border: 1px solid blue;
flex: 0 0 33.3333%;
}
}
You can add this CSS:
.answer:only-of-type {
margin-left: auto;
}
From MDN
The :only-of-type CSS pseudo-class represents an element that has no
siblings of the same type.
codepen
* {
box-sizing: border-box;
}
.answers {
border: 2px solid black;
margin-bottom: 20px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.answers:first-of-type {
background: #ccc;
}
.answers .answer {
background: crimson;
margin: 20px 0;
border: 1px solid blue;
flex: 0 0 33.3333%;
}
.answers .answer:only-of-type {
margin-left: auto;
}
<div class="answers">
<div class="answer">first answer</div>
<div class="answer">second answer</div>
</div>
<div class="answers">
<div class="answer">first answer</div>
</div>
You can add an invisible div with height set to 0
* {
box-sizing: border-box;
}
.invisible {
height: 0;
border: none !important;
}
.answers {
border: 2px solid black;
margin-bottom: 20px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.answers:first-of-type {
background: #ccc;
}
.answers .answer {
background: crimson;
margin: 20px 0;
border: 1px solid blue;
flex: 0 0 33.3333%;
}
<div class="answers">
<div class="answer">first answer</div>
<div class="answer invisible"><!--invisible div--></div>
<div class="answer">second answer</div>
</div>
<div class="answers">
<div class="answer invisible"><!--invisible div--></div>
<div class="answer">first answer</div>
</div>

Resources