Does anyone know how to extend a div 2 to the back, lowering the div 1 to the down, when clicking, in a simple way? It looks easy but with css it is not possible and with javascript it is difficult.
I want when clicking on the 2 extends back and the 1 goes down:
But instead this happens:
div 2 goes down.
Html and Css:
.frame {
width: 50%;
height: 400px;
font: bold 70px roboto;
color: black;
background-color: yellow;
float: left;
}
input:checked .frame {
width: 100%;
}
input{
display: none;
}
<body >
<input type="checkbox" id="a" />
<label for="a" >1</label>
<input type="checkbox" id="b" />
<label for="b" style="background-color: green">2</label>
<input type="checkbox" id="c" />
<label for="c" style="background-color: green">3</label>
<input type="checkbox" id="d" />
<label for="d" >4</label>
</body>
I tried with this javascript:
CodePudding user response:
There is many tricky ways to do it with just css, one of them, is to simply use the display: flex
on the parent and set the flex-direction: row-reverse
but here you must change the order of the html elements.
body{
width: 100%;
display: flex;
flex-direction: row-reverse;
flex-wrap: wrap;
margin: 0;
}
.frame {
display: block;
width: 50%;
height: 100px;
font: bold 70px roboto;
color: black;
background-color: yellow;
}
input:checked .frame {
width: 100%;
}
input{
display: none;
}
<body >
<input type="checkbox" id="b" />
<label for="b" style="background-color: green">2</label>
<input type="checkbox" id="a" />
<label for="a" >1</label>
<input type="checkbox" id="d" />
<label for="d" >4</label>
<input type="checkbox" id="c" />
<label for="c" style="background-color: green">3</label>
</body>
And there is another way to do it with flex too, you can just change the order of the element:
body{
margin: 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.frame {
width: 50%;
height: 100px;
font: bold 70px roboto;
color: black;
background-color: yellow;
order: 2;
}
#b:checked .b {
width: 100%;
order: 1;
}
input{
display: none;
}
<body >
<input type="checkbox" id="a" />
<label for="a" >1</label>
<input type="checkbox" id="b" />
<label for="b" style="background-color: green">2</label>
<input type="checkbox" id="c" />
<label for="c" style="background-color: green">3</label>
<input type="checkbox" id="d" />
<label for="d" >4</label>
</body>
but here you need to set t logic for everyone you will add.
I hope I managed to help, any more explanation let me know.
CodePudding user response:
Nice question. Yep, it does not have pure-css solution, unfortunately...
Fully agree with previous comment regarding to "swapping" strategy via "order" css property. It's definitely less code and more performant then "physically moving" html elements in DOM
Also, "display: grid" is always better then flex for multi-dimensional layouts (2-column in our case)
Supposing that initial requirement expects that any "even cell" should behave as "2", I see full solution like this:
const el_cells = document.querySelectorAll('.wrapper .cell');
el_cells.forEach((el_clicked, index) => {
const el_prev = index > 0 ? el_cells[index - 1] : null;
el_clicked.addEventListener('click', () => {
// checking if element was already expanded
const expanding = !el_clicked.classList.contains('active')
// restoring initial cells state
el_cells.forEach((el, i) => {
el.classList.remove('active');
el.style.order = i 1;
});
if (expanding) {
// resizing selected cell
el_clicked.classList.add('active');
// swapping 'even' cell with previous one (f.e. 2 with 1, 4 with 3, etc...)
if (index % 2 === 1) {
el_clicked.style.order--;
el_prev.style.order ;
}
}
})
})
/* some not very important global styles */
* {
margin: 0;
padding: 0;
font-size: 40px;
font-weight: bold;
}
/* our yellow-green grid */
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
}
.wrapper .cell {
height: 100px;
background: yellow;
}
.wrapper .cell.green {
background: green;
}
.wrapper .cell.active {
grid-column: span 2;
}
<div >
<div >1</div>
<div >2</div>
<div >3</div>
<div >4</div>
<div >5</div>
<div >6</div>
<div >7</div>
<div >8</div>
</div>
Improved this example a bit to make expanded cells to collapse on click :)