I’m new to grid. I am trying to move an element into another position in a grid.
I expect that dynamically changing grid-area: name
of an element would move it into another spot in the grid. But it doesn’t work. It even breaks the code so background-color: black;
isn’t executed. It is even possible to dynamically change position of element after the grid was generated?
Run this snippet and hover over the green box to see the problem.
.container{
display:grid;
background-color: #FF00FF;
grid-column-gap: 10px;
grid-row-gap: 10px;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-template-areas:
"c1 c2 c3 c4"
"c1 c2 c3 c4"
"c0 c5 c5 c5";
}
#c1{
grid-area: c1;
background-color: red;
}
#c2{
grid-area: c0; /* initially we put it in c0 */
background-color: green;
}
#c2:hover{ /* on hover we put c2 into it's place */
grid-area: c2;
background-color: black;
}
#c3{
grid-area: c3;
background-color: yellow;
}
#c4{
grid-area: c4;
background-color: blue;
}
#c5{
grid-area: c5;
background-color: orange;
}
<div class="container">
<p>nothing</p>
<div id="c1">c1</div>
<div id="c2">c2</div>
<div id="c3">c3</div>
<div id="c4">c4</div>
<div id="c5">c5</div>
</div>
The trouble is that you are changing the grid area on hover. So when you :hover
over the green box, it moves to area c2
, which then means it’s no longer under the cursor and so :hover
no longer applies, so then the green box moves back to area c0
under the cursor, and you get into a loop.
Instead, if you change the area on click rather than on hover, it will work fine. See the snippet below.
PS. It will get confusing if you use the same labels for your grid items and your grid areas. Perhaps use a0
, a1
etc for your grid areas, and b1
, b2
etc for the boxes (grid items).
document.getElementById('b2').addEventListener('click', evt => {
evt.target.classList.toggle('moved')
})
.container {
display: grid;
background-color: #aaa;
gap: 10px;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas:
"a1 a2 a3 a4"
"a0 a5 a5 a5";
}
.container>* {
padding: 1em;
}
#b1 {
grid-area: a1;
background-color: pink;
}
#b2 {
grid-area: a0;
background-color: lime;
cursor: pointer;
}
#b2.moved {
grid-area: a2;
background-color: black;
color: white;
}
#b3 {
grid-area: a3;
background-color: yellow;
}
#b4 {
grid-area: a4;
background-color: cyan;
}
#b5 {
grid-area: a5;
background-color: orange;
}
<div class="container">
<div id="b1">b1</div>
<div id="b2">b2</div>
<div id="b3">b3</div>
<div id="b4">b4</div>
<div id="b5">b5</div>
</div>