Expand and overlay div on other sibling elements - css

How do I achieve an input field that: on hover, it expands on the other sibling elements (that have the same parent)?
so for example I have:
.grandparent{
display: flex;
justify-content: space-between;
width:100%;
height:5rem;
}
.other{
background-color: #7fffd477;
display: flex;
align-items: center;
justify-content: center;
width: 5rem;
}
.parent{
background-color: #fff67f;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 12px;
}
.child-1{
background-color: #ff7f7f;
display: flex;
align-items: center;
justify-content: space-between;
height: 100%;
width: 60%;
}
.child-2{
background-color: #77ab55;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
width: 5rem;
}
.child-2:hover{
width: 100%;
transition: all 0.5s;
}
<div class="grandparent">
<div class="parent">
<div class="child-1">
<div class="sub-child-1">1.1</div>
<div class="sub-child-2">1.2</div>
</div>
<div class="child-2">
2.0
</div>
</div>
<div class="other">
other
</div>
</div>
I want the "child-2" div to expand for the whole "parent" (yellow) div and overlay other sibling elements when I hover on it.
Anyone can help me achieve this through CSS?

For the rightmost element in parent to expand over its siblings without affecting them it needs to be positioned absolute and 'anchored' at the right hand side of parent so that the width can grow towards the left.
For the simple HTML structure given in the question where there is only one sibling of the expandable element it would be possible to achieve the required layout without changing the HTML but removing the flex from parent.
However, the question mentions 'siblings' and there is therefore a requirement to layout parent with equal spacing between all its children.
This snippet allows for this by adding a div within child-2. child-2 remains with its given width and therefore takes part in the flex calculations for parent.
However, the inner div is the one which will be positioned absolute and expand to the left.
To get positioning and dimensions correct the 5rem width of child-2 and 12px padding of parent are made CSS variables and CSS calc is used. This should make it easier to change these settings if required.
To show the increased generality, this snippet has 2 siblings (each for the demo set to child-1 settings with width 30% instead of 60%).
.grandparent {
display: flex;
justify-content: space-between;
width: 100%;
height: 5rem;
}
.other {
background-color: #7fffd477;
display: flex;
align-items: center;
justify-content: center;
width: 5rem;
}
.parent {
--pad: 12px;
/* set to the width of the parent's padding */
background-color: #fff67f;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: var(--pad);
position: relative;
}
.child-1 {
background-color: #ff7f7f;
display: flex;
align-items: center;
justify-content: space-between;
height: 100%;
width: 60%;
width: 30%;
}
.child-2 {
--w: 5rem;
/* the width of the rightmost element in parent */
height: 100%;
width: var(--w);
right: 0;
}
.child-2>* {
position: absolute;
background-color: #77ab55;
display: flex;
align-items: center;
justify-content: center;
width: var(--w);
height: calc(100% - (2 * var(--pad)));
transition: all 0.5s;
right: var(--pad);
}
.child-2:hover>* {
width: calc(100% - (2 * var(--pad)));
}
<div class="grandparent">
<div class="parent">
<div class="child-1">
<div class="sub-child-1">1.1</div>
<div class="sub-child-2">1.2</div>
</div>
<div class="child-1">
<div class="sub-child-1">1.1</div>
<div class="sub-child-2">1.2</div>
</div>
<div class="child-2">
<div>
2.0
</div>
</div>
</div>
<div class="other">
other
</div>
</div>

I have adjusted the HTML structure: .child-1 is now after .child-2.
The CSS for .parent now includes flex-direction: row-reverse.
It is now possible to easily affect .child-1 via CSS (display: none).
.grandparent {
display: flex;
justify-content: space-between;
width: 100%;
height: 5rem;
}
.other {
background-color: #7fffd477;
display: flex;
align-items: center;
justify-content: center;
width: 5rem;
}
.parent {
background-color: #fff67f;
display: flex;
justify-content: space-between;
flex-direction: row-reverse; /* Added */
align-items: center;
width: 100%;
padding: 12px;
}
.child-1 {
background-color: #ff7f7f;
display: flex;
align-items: center;
justify-content: space-between;
height: 100%;
width: 60%;
}
.child-2 {
background-color: #77ab55;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
width: 5rem;
}
.child-2:hover {
width: 100%;
transition: all 0.5s;
z-index: 10;
}
/* Added */
.child-2:hover+.child-1 {
display: none;
}
<div class="grandparent">
<div class="parent">
<div class="child-2">
2.0
</div>
<div class="child-1">
<div class="sub-child-1">1.1</div>
<div class="sub-child-2">1.2</div>
</div>
</div>
<div class="other">
other
</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>

Div with position absolute is wider than its container

In the following code:
HTML
<div class="cards-wrapper">
<div class="cards_item">
<div class="card">
<div class="card__header">
<div class="=card__title">
<div>title</div>
</div>
</div>
<div class="card__content">
<p class="card__description">Some text</p>
<p class="card__frequency">more text</p>
</div>
<div class="card__footer">
<div class="card__tick"><input type="hidden" value="0"><label class="checkbox-container"><input type="checkbox" class="list-checkbox" value="false"><span class="checkmark"></span></label></div>
<div class="card__see">Even more</div>
</div>
</div>
</div>
</div>
SCSS
.cards-wrapper {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
outline: 2px solid blue
}
.cards_item {
display: flex;
justify-content: space-between;
box-sizing: border-box;
width: 100%;
padding: 0.5rem;
}
.card {
position: relative;
flex: 0 1 100%;
justify-self: stretch;
box-sizing: border-box;
padding: 0.625rem;
overflow: hidden;
&__header {
display: flex;
flex-direction: row;
align-items: center;
}
&__title {
margin: 0;
}
&__frequency {
margin-bottom: 80px;
}
&__footer {
position: absolute;
bottom: 0.8rem;
display: inline-flex;
align-items: center;
justify-content: space-between;
width: 100%;
outline: 2px solid red;
}
}
Why does .card__footer div with a width of 100% wider than its container?
It fits in the container if you change its width to 90%.
But something seems to be not right here.
Can someone help me please with this?
I see that the container div has padding to it.
can you try this width value on your footer?
width: calc(100% - 1.25rem);
since you are using scss
calc(100% - 2*0.625rem)

Flex wrap - stack rows without stretch? [duplicate]

This question already has answers here:
What's the difference between align-content and align-items?
(15 answers)
Closed 3 years ago.
I have a flex container with two children of fixed dimensions that are aligned flex-end (the bottom of the parent).
When I resize the parent I want them to wrap on top of each other, but instead they each take up 50% of the parent height.
Is there a way to do this without adding another div?
FIDDLE
.wrapper {
width: 600px;
height: 500px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: flex-end;
background-color: #eeeeee;
resize: horizontal;
overflow: auto;
flex-wrap: wrap;
}
.one {
width: 200px;
height: 100px;
background: red;
}
.two {
width: 200px;
height: 100px;
background: blue;
}
<div class="wrapper">
<div class="one">1</div>
<div class="two">2</div>
</div>
You need to also consider align-content like below:
.wrapper {
width: 600px;
height: 500px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-content:flex-end; /*added this*/
align-items: flex-end;
background-color: #eeeeee;
resize: horizontal;
overflow: auto;
flex-wrap: wrap;
}
.one {
width: 200px;
height: 100px;
background: red;
}
.two {
width: 200px;
height: 100px;
background: blue;
}
<div class="wrapper">
<div class="one">1</div>
<div class="two">2</div>
</div>

Flex: Align all children at flex-start but force one child to end?

I have a flex container with 3 children, and I am wanting to ensure that the children all align at flex-start, however the final child should sit at the bottom of the container.
Is it not possible to combine align-content with align-self?
.container {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
padding: 15px 15px 50px 15px;
height: 100%;
background: red;
width: 200px;
height: 500px;
}
.item-1,
.item-2,
.item-3 { width: 100%; }
.item-3 {
align-self: flex-end;
}
<div class="container">
<div class="item-1">One</div>
<div class="item-2">Two</div>
<div class="item-3">Three</div>
</div>
Since you want 100% width of your element, you can switch to column direction then use margin to control alignment:
.container {
display: flex;
flex-direction: column;
padding: 15px 15px 50px 15px;
height: 100%;
background: red;
width: 200px;
height: 300px;
}
.item-3 {
margin-top: auto;
}
<div class="container">
<div class="item-1">One</div>
<div class="item-2">Two</div>
<div class="item-3">Three</div>
</div>

Zoom background image in flexbox layout without affecting neighbour elements

I've got an layout which looks like this and I'm trying to zoom image-background on hover, but I can't get this effect in any way without affecting neighbour elements (on hover it expands like this) - my aim is to zoom only image and stay inside the parent div element. Is there any workaround for this in flexbox layout? This is my code:
HTML:
<body>
<div class="index-wrapper">
<nav class="index-menu">
123
</nav>
<main class="index-main">
<div class="index-square" style="background: yellow;"></div>
<div class="index-square">
<div class="index-square-inner" style="background-image: url(assets/img/is-2.jpg); background-position: center; background-size: cover;transition: all .2s ease-in-out;">
<div style="background: rgba(0, 0, 0, 0.4);">
123
</div>
</div>
</div>
<div class="index-square" style="background: pink;">123</div>
<div class="index-square" style="background: purple;">123</div>
</main>
</div>
</body>
SCSS:
.index-wrapper {
display: flex;
flex-flow: column;
height: 100vh;
.index-menu {
box-shadow: 0 0 2px 2px #d0d0d0;
z-index: 2;
background: white;
color: black;
padding: 2em;
}
.index-main {
display: flex;
background: yellow;
flex-direction: row;
flex: 1;
flex-wrap: wrap;
.index-square {
flex-basis: 50%;
display: flex;
flex-flow: column;
.index-square-inner {
flex: 1;
width: 100%;
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
&:hover {
transform: scale(1.1);
}
div {
flex: 1;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
}
}
}
}
You should add overflow: hidden; to the .index-square style definition;
.index-square {
flex-basis: 50%;
display: flex;
flex-flow: column;
overflow: hidden; /*Add this here*/
See this fiddle.

Resources