Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to grid layout transitions

This is a very common type of animation - toggle a sidebar on/off:

document.querySelector('.toggle').addEventListener('click', e =>
  document.body.classList.toggle('no-aside')
)
body {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: minmax(50px, 200px) auto;
  grid-template-areas: "aside main";
  margin: 0;
  width: 100vw;
  height: 100vh;
  transition: grid-template-columns .25s;
}

body.no-aside {
  grid-template-columns: 50px auto;
}

aside {
  background: #111;
  color: #fff;
}

main {
  background: #ddd;
}

.toggle {
  background: #111;
  width: 40px;
  height: 40px;
  display: block;
  position: relative;
}

.toggle i,
.toggle i::after,
.toggle i::before {
  position: absolute;
  width: 40px;
  height: 4px;
  border-radius: 4px;
  transition: transform .15s;
  background-color: #fff;
}

.toggle i {
  top: 46%;
  left: 18%;
  display: block;
  opacity: .5;
}

.toggle i::before {
  top: -10px;
}

.toggle i::after {
  bottom: -10px;
}

.toggle i::after,
.toggle i::before {
  content: '';
  display: block;
}

.toggle i::before {
  transform: translate3d(-8px, 0, 0) rotate(-45deg) scale(0.7, 1);
}

.toggle i::after {
  transform: translate3d(-8px, 0, 0) rotate(45deg) scale(0.7, 1);
}

.no-aside .toggle i::before,
.no-aside .toggle i::after {
  transform: none;
}
<aside>
  <a class="toggle">
    <i></i>
  </a>
</aside>

<main>
  content
</main>

But it appears that the transitions for grid* properties are not yet implemented in browsers so it doesn't work with a grid layout.

Is there a way to achieve this with other properties, but still keep the grid layout? Everything I've tried, with width, left, margin etc. seems to leave a gap between the 2 grid items.

like image 636
nice ass Avatar asked Jan 27 '18 18:01

nice ass


1 Answers

Grid is supposed to have 5 animatable properties: grid-gap, grid-row-gap, grid-column-gap, grid-template-columns and grid-template-rows.

But as you said, browsers have not implemented it yet. Firefox and Edge can animate grid-gap, grid-row-gap and grid-column-gap, but not grid-template-columns or grid-template-rows. Chromium browsers can't animate any grid property at all.

A workaround for this particular case would be to set the transition as width on the aside, and have the template columns declared as min-content 1fr.

document.querySelector('.toggle').addEventListener('click', e =>
  document.body.classList.toggle('no-aside')
)
body {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: min-content 1fr;

  /*
  alternatively, ridiculously uneven FR columns can work too, such as
  grid-template-columns: 1fr 30fr;
  */
  grid-template-areas: "aside main";
  margin: 0;
  width: 100vw;
  height: 100vh;
}

body.no-aside aside{
  width:50px;
}

aside {
  width:200px;
  background: #111;
  color: #fff;
  transition: width 1s;
}

main {
  background: #ddd;
}

.toggle {
  background: #111;
  width: 40px;
  height: 40px;
  display: block;
  position: relative;
}

.toggle i,
.toggle i::after,
.toggle i::before {
  position: absolute;
  width: 40px;
  height: 4px;
  border-radius: 4px;
  transition: transform .15s;
  background-color: #fff;
}

.toggle i {
  top: 46%;
  left: 18%;
  display: block;
  opacity: .5;
}

.toggle i::before {
  top: -10px;
}

.toggle i::after {
  bottom: -10px;
}

.toggle i::after,
.toggle i::before {
  content: '';
  display: block;
}

.toggle i::before {
  transform: translate3d(-8px, 0, 0) rotate(-45deg) scale(0.7, 1);
}

.toggle i::after {
  transform: translate3d(-8px, 0, 0) rotate(45deg) scale(0.7, 1);
}

.no-aside .toggle i::before,
.no-aside .toggle i::after {
  transform: none;
}
<aside>
  <a class="toggle">
    <i></i>
  </a>
</aside>
<main>
123123
</main>
like image 54
Facundo Corradini Avatar answered Nov 24 '22 12:11

Facundo Corradini