Span at the bottom of Parent div - javascript

I have a flex container in which I have two boxes which are side by side (and collapse in one column when the screen is too small).
Now, when boxes are side by side, I've set that they have the same height, like in the following image.
Now, what I want to achieve is to put the EDIT button of both boxes at the bottom (this means that only the EDIT button of the box with less content will need to move).
I've searched, but the solution are to use position absolute, because one of the two boxes won't need it, and if I put position absolute on both EDIT button, the box on the right will have less height because it won't count the EDIT button anymore.
I tried to play with flex, but I rather not set the boxes as display flex.
There may be some solution with Jquery, I've read something about it, but it was just something like "You could achieve that with Jquery!" but.. I honestly don't know how.
#parent {
flex-flow: row wrap;
display: flex;
align-items: stretch;
}
.box {
margin: 10px;
padding: 15px;
flex: 0 1 calc(50% - 50px);
}
.box:last-of-type {
background-color: green;
}
.box:first-of-type {
background-color: red;
}
.cool-form {
display: flex;
flex-direction: column;
}
.button-container {
display: block;
margin-left: 5px;
margin-top: auto;
align-self: center;
}
.button {
background-color: white;
display: inline-block;
width: 120px;
height: 48px;
line-height: 48px;
border: 1px solid black;
text-align: center;
cursor: pointer;
}
<div id="parent">
<div class="box">
<form class="cool-form">
<h1>Box on left</h1>
<p>This is a shorter box</p>
<span class="button-container">
<span class="button">EDIT</span>
</span>
</form>
</div>
<div class="box">
<form class="cool-form">
<h1>Box on right</h1>
<p>This is</p>
<p>a</p>
<p>bigger</p>
<p>waaay bigger</p>
<p>Box</p>
<span class="button-container">
<span class="button">EDIT</span>
</span>
</form>
</div>
</div>

Adding flexbox to these divs (using flex-direction:column) seems minimally invasive (which was, perhaps a concern).
.box {
display: flex;
flex-direction: column;
}
Then you can give the button container margin-top:auto and it's auomatically pushed to the bottom.
Then it's just a matter of aligning it horizontally/centrally
.button-container {
margin-top: auto;
align-self: center;
}
#parent {
flex-flow: row wrap;
display: flex;
align-items: stretch;
}
.box {
margin: 10px;
padding: 15px;
flex: 0 1 calc(50% - 50px);
display: flex;
flex-direction: column;
}
.box:last-of-type {
background-color: green;
}
.box:first-of-type {
background-color: red;
}
.button-container {
display: block;
margin-left: 5px;
margin-top: auto;
align-self: center;
}
.button {
background-color: white;
display: inline-block;
width: 120px;
height: 48px;
line-height: 48px;
border: 1px solid black;
text-align: center;
cursor: pointer;
}
<div id="parent">
<div class="box">
<h1>Box on left</h1>
<p>This is a shorter box</p>
<span class="button-container">
<span class="button">EDIT</span>
</span>
</div>
<div class="box">
<h1>Box on right</h1>
<p>This is</p>
<p>a</p>
<p>bigger</p>
<p>waaay bigger</p>
<p>Box</p>
<span class="button-container">
<span class="button">EDIT</span>
</span>
</div>
</div>

Related

show divs one after the other

I have a popup where I show notifications. The user can delete notifications at any time. The day the notification arrives and the delete button will appear one after the other. No matter what I did, I couldn't.
How can I show these two divs under each other, as can be seen in the marked area in the picture?
<div className="notificationlist__container only-desktop">
{props.notification.notificationList.map((e) => {
return (
<div className="notificationlist__item">
<div className="notificationlist__info">
<div className="notificationlist__content">
Lorem, ipsum.
</div>
<div className="notificationlist__detail">
<Link to="/profil">
<div>Profile</div>
<AS.KeyboardArrowRightIcon />
</Link>
</div>
</div>
<div className="notificationlist__time">Today
<div className="delete__button">
<AS.IconButton >
<AS.DeleteIcon />
</AS.IconButton>
</div>
</div>
</div>
);
})}
</div>
.notificationlist__container.only-desktop {
font-size: 1.2rem;
// padding-right: 2em;
max-height: 400px;
overflow: auto;
.notificationlist__item {
padding: 0.5em 0;
border-bottom: 1px solid #d1d1d1;
&:last-of-type {
border-bottom: none;
}
display: flex;
justify-content: space-between;
align-items: flex-start;
.notificationlist__info {
margin-right: 1em;
max-width: 400px;
.notificationlist__content {
color: gray;
}
.notificationlist__detail {
margin-top: 1em;
color: var(--palette-blue-300);
display: flex;
align-items: center;
font-size: 1.1rem;
font-weight: 600;
svg {
font-size: 1.5rem !important;
}
a {
display: contents;
}
}
}
.notificationlist__time{
display: flex;
.delete__button {
float: left;
}
}
}
}
display: flex is putting divs next to each other. You can delete display: flex or just add flex-direction: column; to put them under each other. To center them horizontally add align-items: center;
You should move delete button out of notificationlist_time content, then it would be easy to manipulate it
<div className="notificationlist__right">
<div className="notificationlist__time">today</div>
<div className="delete__button">
<AS.IconButton >
<AS.DeleteIcon />
</AS.IconButton>
</div>
</div>
So since it would be two different blocks, you would have an ability to position them like you want.

Flexbox scroll overflowing content in an dynamic sized parent

I have a simple menu and content div structure. The menu has no fixed size and can expand depending on its content. The content div underneath should take the available space and scroll its own content if overflowing. Unfortunately, flexbox now behaves in such a way that the content div, due to its flex:1 property, expands according to its content instead of scrolling the content.
Is there a way to preserve the dynamic sizes using flex:1 and also have the content of the content div scroll?
function toggleMenu() {
const menu = document.querySelector(".menu");
if(menu.classList.contains("open")) {
menu.querySelector(".text").innerHTML = "<p> small text </p>";
menu.classList.remove("open");
}else {
menu.querySelector(".text").innerHTML = "<h1> im the menu </h1>";
menu.classList.add("open");
}
}
body {
padding: 0;
margin: 0;
background-color: #17141d;
display: flex;
height: 100vh;
}
.main {
display: flex;
flex-direction: column;
flex: 1;
background-color: grey;
}
.menu {
background-color: blueviolet;
}
.content {
display: flex;
flex: 1;
background-color: aqua;
}
.segment-wrapper {
flex: 1;
display: flex;
background-color: red;
flex-direction: column;
overflow-y: scroll;
padding: 10px;
box-sizing: border-box;
}
.segment {
height: 500px;
background-color: green;
border-radius: 5px;
border: solid 1px black;
width: 100%;
margin-bottom: 10px;
}
<div class="main">
<div class="menu open">
<div class="text"><h1>im the menu</h1></div>
<button onclick="toggleMenu()">Toggle</button>
</div>
<div class="content">
<div class="segment-wrapper">
<div class="segment">
</div>
<div class="segment">
</div>
<div class="segment">
</div>
</div>
</div>
</div>
you are missing
an height on .main to size it according to body or the viewport's height.
overflow on .content, so it overflows, unless you want .main to overflow (which body does already)
and finally flex-shrink:0; on .segment so it doesn't shrink :)
here an example of what i understood you were after:
function toggleMenu() {
const menu = document.querySelector(".menu");
if(menu.classList.contains("open")) {
menu.querySelector(".text").innerHTML = "<p> small text </p>";
menu.classList.remove("open");
}else {
menu.querySelector(".text").innerHTML = "<h1> im the menu </h1>";
menu.classList.add("open");
}
}
body {
padding: 0;
margin: 0;
background-color: #17141d;
display: flex;
height: 100vh;
}
.main {
display: flex;
flex-direction: column;
flex: 1;
background-color: grey;
max-height;100%;
}
.menu {
background-color: blueviolet;
}
.content {
display: flex;
flex: 1;
background-color: aqua;
overflow:auto;
}
.segment-wrapper {
flex: 1;
display: flex;
background-color: red;
flex-direction: column;
overflow-y: scroll;
padding: 10px;
box-sizing: border-box;
}
.segment {
flex-shrink:0;
height: 500px;
background-color: green;
border-radius: 5px;
border: solid 1px black;
width: 100%;
margin-bottom: 10px;
}
<div class="main">
<div class="menu open">
<div class="text"><h1>im the menu</h1></div>
<button onclick="toggleMenu()">Toggle</button>
</div>
<div class="content">
<div class="segment-wrapper">
<div class="segment">
</div>
<div class="segment">
</div>
<div class="segment">
</div>
</div>
</div>
</div>

Positioning an absolute element above other elements

So I am building this frontendmentor site and im having trouble positioning the shopping cart div on top of the rest of the elements. At first i tried using z-index but apparently that doesnt work with elements that have a position style. I used position relative on the parent and absolute on the child so it would always appear under the shopping cart icon. Is there any other way to force an element on top or should i change the way i position the div.
.right-container {
padding: 1rem;
}
.account-container {
display: flex;
align-items: center;
position: relative;
}
.cart-icon-container {
margin-right: 2rem;
}
.cart-icon-container img {
height: 30px;
width: 30px;
aspect-ratio: 1;
}
.shopping-cart-overlay {
position: absolute;
top: 5rem;
right: 100px;
width: 400px;
border-radius: 10px;
box-shadow: 0 1rem 10px rgba(0, 0, 0, 0.185);
}
.shopping-cart-content {
display: flex;
justify-content: center;
align-items: center;
padding: 2rem 1rem;
}
<div class="right-container">
<div class="account-container">
<div class="shopping-cart-overlay">
<div class="shopping-cart-header">
<h4>Cart</h4>
</div>
<div class="shopping-cart-content">
<p>Your cart is empty</p>
</div>
</div>
<a href="/index.html" class="cart-icon-container">
<img src="./images/icon-cart.svg" alt="cart">
</a>
<img class="avatar" src="./images/image-avatar.png" alt="profile-pic">
</div>
</div>
Well it does work. Read this to get a better understanding of how z-index works with position. You just couldn't notice it because the div was transparent.
Check out the snippet below. It's your exact code, but I changed the background and positioned the .shopping-cart-overlay element closer to the other elements, just to show you that it actually works.
.right-container {
padding: 1rem;
}
.account-container {
display: flex;
align-items: center;
position: relative;
}
.cart-icon-container {
margin-right: 2rem;
}
.cart-icon-container img {
height: 30px;
width: 30px;
aspect-ratio: 1;
}
.shopping-cart-overlay {
position: absolute;
//top: 5rem;
//right: 100px;
width: 400px;
border-radius: 10px;
box-shadow: 0 1rem 10px rgba(0, 0, 0, 0.185);
/* Changes */
top: 0;
left: 125px;
z-index: 99;
background-color: red;
}
.shopping-cart-content {
display: flex;
justify-content: center;
align-items: center;
padding: 2rem 1rem;
}
<div class="right-container">
<div class="account-container">
<div class="shopping-cart-overlay">
<div class="shopping-cart-header">
<h4>Cart</h4>
</div>
<div class="shopping-cart-content">
<p>Your cart is empty</p>
</div>
</div>
<a href="/index.html" class="cart-icon-container">
<img src="./images/icon-cart.svg" alt="cart">
</a>
<img class="avatar" src="./images/image-avatar.png" alt="profile-pic">
</div>
</div>

How to control the height of descendant box within a nested flexbox context?

.main {
height: 100px;
width: 100px;
border: 1px solid;
background: green;
}
.columns {
display: flex;
}
.columns.vertical {
flex-direction: column;
flex-wrap: nowrap;
}
.box22 {
overflow: auto;
}
.box1 {
background: red;
}
.box2 {
background: orange;
border: 1px blue solid;
}
.box222 {
background: white;
border: 1px blue solid;
}
<md-content class="md-padding">
<div class="main columns vertical">
<nav class="box1">nav</nav>
<div class="box columns vertical">
<div class="b">asdasd</div>
<div class="box2 columns vertical">
<div class="box21 columns">
box21
</div>
<div class="box22 columns">
<div class="box221">box221</div>
<div class="box222">
<p>a</p>
<p>a</p>
</div>
</div>
</div>
</div>
</div>
</md-content>
I manually set the height of outermost box main and also set box22 with overflow:auto, however the box22 stretched out the main box and no scroll bar shows up.
What I want is to set height in the outermost box and the nested inner box can automitically control it's height thus all boxes are fitted. How to fix these kind of problem, should I set heights for all descendant boxes?
I tested setting overflow :auto at box(level1), box2(level2) and box22(level3), only box(level1) can automatically control it's height and shows up a scroll bar when it's height overlayed.
what I want is shown below, however, to achieve this, I need to manually specify the father box of box22. In other words, if I want to make a flex contaner scrollable, I have to at least set it's father box's height, which is toally unaccptable.
.main {
height: 100px;
width: 100px;
border: 1px solid;
background: green;
}
.columns {
display: flex;
}
.columns.vertical {
flex-direction: column;
flex-wrap: nowrap;
}
.box22 {
overflow: auto;
}
.box1 {
background: red;
}
.box2 {
height:64px;
background: orange;
border: 1px blue solid;
}
.box21 {
background: yellow;
}
.box222 {
background: white;
border: 1px blue solid;
margin-top: auto;
}
<md-content class="md-padding">
<div class="main columns vertical">
<nav class="box1">nav</nav>
<div class="box columns vertical">
<div class="b">asdasd</div>
<div class="box2 columns vertical">
<div class="box21 columns">
box21
</div>
<div class="box22 columns">
<div class="box221">box221</div>
<div class="box222">
<p>a</p>
<p>a</p>
<p>a</p>
</div>
</div>
</div>
</div>
</div>
</md-content>
Well, as you noted, the parent container needs a height declaration in order to generate a scrollbar.
This makes sense because there's no way to trigger an overflow condition if there's no fixed length.
With a flexible length (e.g., height: auto), the container will shrink and expand to accommodate content, never triggering an overflow and, therefore, never generating a scrollbar.
MDN describes it like this:
In order for overflow to have an effect, the block-level container must have either a set height (height or max-height) or white-space set to nowrap.
So that's your obstacle. Here's how you get around it (knowing that you can't set more heights):
Give the browser what it needs to trigger the overflow: set a tiny (1px) height.
You get the full height that you want: use flex-grow to consume remaining space.
So something like this...
height: 1px;
flex-grow: 1;
but more efficiently:
flex: 1 0 1px; /* fg, fs, fb */
Add this to your code:
.main .columns.vertical {
flex: 1 0 1px;
}
.box22 {
flex: 1 0 1px;
}
.main {
height: 100px;
width: 100px;
border: 1px solid;
background: green;
}
/* NEW */
.main .columns.vertical {
flex: 1 0 1px;
}
/* ADJUSTMENT */
.box22 {
flex: 1 0 1px;
overflow: auto;
}
.columns {
display: flex;
}
.columns.vertical {
flex-direction: column;
flex-wrap: nowrap;
}
.box22 {
flex: 1 0 1px;
overflow: auto;
}
.box1 {
background: red;
}
.box2 {
background: orange;
border: 1px blue solid;
}
.box222 {
background: white;
border: 1px blue solid;
}
<md-content class="md-padding">
<div class="main columns vertical">
<nav class="box1">nav</nav>
<div class="box columns vertical">
<div class="b">asdasd</div>
<div class="box2 columns vertical">
<div class="box21 columns">box21</div>
<div class="box22 columns">
<div class="box221">box221</div>
<div class="box222">
<p>a</p>
<p>a</p>
</div>
</div>
</div>
</div>
</div>
</md-content>
consider using max-height instead of height on main also... if you start with flexbox... best to keep display: flex through the whole chain
.top {
position: static;
height: 200px;
width: 200px;
max-height: 200px;
max-width: 200px;
overflow: auto;
}
.flexcol {
width: 100%;
display: flex;
flex-direction: column;
padding: 0;
}
.mynav {
display: flex;
flex-direction: row;
flex-grow: 1;
background-color: blue;
}
.box1 {
display: flex;
flex-grow: 1;
background-color: red;
}
.box2 {
display: flex;
flex-direction: column;
flex-grow: 1;
background-color: green;
}
.box3 {
display: flex;
flex-grow: 1;
background-color: yellow;
}
.box221 {
min-height: 50px;
background-color: pink;
width: 100%;
}
.box222 {
min-height: 50px;
background-color: grey;
width: 100%;
}
.darklink {
color: white;
}
<div class="top">
<div class="flexcol">
<nav class="mynav">
<a class="darklink" href="#" target="_">Link1</a>
<a class="darklink" href="#" target="_">Link2</a>
<a class="darklink" href="#" target="_">Link3</a>
</nav>
<div class="box1">
<p>para</p>
</div>
<div class="box2">
<div class="box221">
<p>para</p>
<p>para</p>
</div>
<div class="box222">
<p>para</p>
<p>para</p>
<p>para</p>
</div>
</div>
<div class="box3">
<p>para</p>
</div>
</div>
</div>

Make 2 divs overlaping 2 other divs responsively

So,I don't know how to make divs overlap eachother in such a way and I'm curious to find out if it's even possible. If it is, is it also possible to make something like that responsive too, using bootstrap or some other library? If yes, wouldn't it be needed for the divs to completely change configuration so the content still makes sense? (like in the pic below)
If something like that can't happen (referring to the responsiveness) is there a way to make the entire thing disappear and show something else instead?
This might give you somewhere to start?
You'll need to use a combination of #media queries and flex.
Look into #media queries here: CSS #media Rule
Look into flex box here: A Complete Guide to Flexbox
This code might be of some help! (Resize the output window to see the results)
See here: JSFiddle
.panel-container {
}
.container {
display: flex;
flex-direction: column;
justify-content: space-around;
}
.panel {
}
.col {
display: flex;
flex-direction: row;
justify-content: space-around;
}
#a1 {
background-color: blue;
height: 100px;
width: 100px;
line-height: 100px;
text-align: center;
}
#a2 {
background-color: blue;
height: 100px;
width: 100px;
border-radius: 50%;
line-height: 100px;
text-align: center;
}
#a3 {
background-color: blue;
height: 100px;
width: 100px;
line-height: 100px;
text-align: center;
}
#b1 {
background-color: red;
height: 100px;
width: 100px;
line-height: 100px;
text-align: center;
}
#b2 {
background-color: red;
height: 100px;
width: 100px;
border-radius: 50%;
line-height: 100px;
text-align: center;
}
#b3 {
background-color: red;
height: 100px;
width: 100px;
line-height: 100px;
text-align: center;
}
#media only screen and (max-width: 600px) {
.container {
display: flex;
flex-direction: column;
}
.col {
display: flex;
flex-direction: column;
}
}
<div class="container">
<div class="col">
<div id="a1">A1</div>
<div id="a2">A2</div>
<div id="a3">A3</div>
</div>
<div class="col">
<div id="b1">B1</div>
<div id="b2">B2</div>
<div id="b3">B3</div>
</div>
</div>
<div class="panel-container">
<div id="lhs" class="panel"></div>
<div id="rhs" class="panel"></div>
</div>
its possible. use CSS flexbox
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
youll want to switch the flex direction of the container element with a css media query and so on... this is a more html/css related problem than javascript

Categories

Resources