57

我正在尝试让我的粘性标题具有过渡效果,因此它可以缓和而不仅仅是快速移动。

我究竟做错了什么?

这是我的工作版本:

http://codepen.io/juanmata/pen/RVMbmr

基本上,下面的代码将类 tiny 添加到我的包装类中,这很好。

$(window).on('load', function() {
    $(window).on("scroll touchmove", function () {
        $('.wrapper').toggleClass('tiny', $(document).scrollTop() > 0);
    });
});

这是CSS部分:

.wrapper {
    grid-template-rows: 80px calc(75vh - 80px) 25vh 80px;
    -o-transition: all 0.5s;
    -moz-transition: all 0.5s;
    -webkit-transition: all 0.5s;
    transition: all 0.5s;
}
.tiny {
    grid-template-rows: 40px calc(75vh - 40px) 25vh 80px;
}

所以标题确实缩小了,但没有动画,我错过了什么还是过渡根本不适用于网格?

这是 css-grid 文档的链接。

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout

$(window).on('load', function() {
  $(window).on("scroll touchmove", function() {
    $('.wrapper').toggleClass('tiny', $(document).scrollTop() > 0);
  });
});
* {
	margin:0;
	padding:0;
}

.wrapper {
	display: grid;
	grid-gap: 0px;
	grid-template-columns: 1fr 1fr 1fr 1fr;
	grid-template-rows: 80px calc(75vh - 80px) 25vh 80px;
	grid-template-areas:
		"head head head head"
		"main main main main"
		"leader leader leader leader"
		"foot foot foot foot";
	background-color: #fff;
	color: #444;
}
.tiny {
	grid-template-rows: 40px calc(75vh - 40px) 25vh 80px;
}
.box {
	background-color: #444;
	color: #fff;
	border-radius: 5px;
	font-size: 150%;
}
.box .box {
	background-color: lightcoral;
}

.head {
	grid-area: head;
	background-color: #999;
	z-index: 2;
	display: grid;
	grid-gap: 0px;
	grid-template-columns: 20% 1fr;
	-o-transition: all 0.5s;
	-moz-transition: all 0.5s;
	-webkit-transition: all 0.5s;
	transition: all 0.5s;
	position: sticky;
	top: 0;
}

.logo{
        height: inherit;
        grid-column: 1;
        grid-row: 1;
        background-color:red;
        position: relative;
        overflow: hidden;
    }
.logo img {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        display: block;
        max-width: 100%;
        height: auto;
    }
.main {
	grid-area: main;
	/* CSS Grid */
	z-index: 1;
	grid-column: head-start / head-end;
	grid-row: head-start / leader-start;
	background-color: red;
}
.leader {
	grid-area: leader;
	z-index:1;
	display: grid;
	grid-gap: 0px;
	grid-template-columns: repeat(4, 1fr  );
}
.foot {
	grid-area: foot;
	z-index:1;
}
<div class="wrapper">
  <div class="box head">
    <div class="box logo">
      <a href="#"><img src="https://unsplash.it/200/300/?random" /></a>
    </div>
    <div class="box nav">nav</div>
  </div>
  <div class="box main">main</div>
  <div class="box leader">
    <div class="box leader-1">1</div>
    <div class="box leader-2">2</div>
    <div class="box leader-3">3</div>
    <div class="box leader-4">4</div>
  </div>
  <div class="box foot">foot</div>
</div>

4

8 回答 8

51

根据规范,转换应该在grid-template-columns和上工作grid-template-rows

7.2. 显式轨道大小:grid-template-rowsand grid-template-columns 属性

Animatable:作为长度、百分比或计算的简单列表,只要列表中的长度、百分比或计算组件的值不同

所以,如果我的解释是正确的,只要唯一的变化是属性的值,而不改变规则的结构,转换就应该起作用。但他们没有


更新

这确实有效,但到目前为止只在 Firefox 中实现。在此处关注其他浏览器更新。 https://codepen.io/matuzo/post/animating-css-grid-layout-properties

@bcbrian评论中的贡献


这是我创建的一个测试:

grid-container {
  display: inline-grid;
  grid-template-columns: 100px 20vw 200px;
  grid-template-rows: repeat(2, 100px);
  background-color: black;
  height: 230px;
  transition: 2s;
  
  /* non-essential */
  grid-gap: 10px;
  padding: 10px;
  box-sizing: border-box;
}

grid-container:hover {
  grid-template-columns: 50px 10vw 100px;
  grid-template-rows: repeat(2, 50px);
  background-color: red;
  height: 130px;
  transition: 2s;
}

grid-item {
  background-color: lightgreen;
}
<grid-container>
  <grid-item></grid-item>
  <grid-item></grid-item>
  <grid-item></grid-item>
  <grid-item></grid-item>
  <grid-item></grid-item>
  <grid-item></grid-item>
</grid-container>

jsFiddle 演示

在测试中,过渡适用于高度和背景颜色,但不适用于grid-template-rowsor grid-template-columns

于 2017-05-11T17:07:01.723 回答
13

作为一种解决方法,您可以使用网格项目的大小来代替grid-template-columnsgrid-template-rows

你可以这样做:

grid-container {
  display: inline-grid;
  grid-template-columns: 100px 20vw 200px;
  background-color: black;
  height: 230px;
  transition: 2s;
  
  /* non-essential */
  grid-gap: 10px;
  padding: 10px;
  box-sizing: border-box;
}

grid-container:hover {
  background-color: red;
  height: 130px;
}

grid-item {
  height: 100px;
  transition: height 2s;
  background-color: lightgreen;
}

grid-container:hover .first-row {
  height: 25px;
}

grid-container:hover .last-row {
  height: 75px;
}
<grid-container>
  <grid-item class='first-row'></grid-item>
  <grid-item class='first-row'></grid-item>
  <grid-item class='first-row'></grid-item>
  <grid-item class='last-row'></grid-item>
  <grid-item class='last-row'></grid-item>
  <grid-item class='last-row'></grid-item>
</grid-container>

这是另一个 2x2 示例: https ://codepen.io/erik127/pen/OvodQR

这里有一个更广泛的示例,您可以在其中添加更多列或行:https ://codepen.io/erik127/pen/rdZbxL

grid-template-columns不幸的是,它有很多 javascript,如果并且grid-template-rows将是可动画的,那就太好了。

另一种可能适用于某些用例(如果您的网格项目不跨越多行)的替代方法是将 flexbox 与网格一起使用。

于 2018-04-05T19:12:01.887 回答
7

我使用 GSAP 为 grid-template-columns 和 grid-template-rows 属性设置动画:

function changeGridTemplateColumns(pattern) {
  TweenMax.to(".container",
    1, {
      gridTemplateColumns: pattern
    }
  );
}

function changeGridTemplateRows(pattern) {
  TweenMax.to(".container",
    1, {
      gridTemplateRows: pattern
    }
  );
}

$(document).ready(
  function() {
    $(".el-a,.el-b,.el-c").mouseenter(
      function() {
        changeGridTemplateRows("2fr 1fr");
      }
    );
    $(".el-d,.el-e,.el-f").mouseenter(
      function() {
        changeGridTemplateRows("1fr 2fr");
      }
    );

    $(".el-a,.el-d").mouseenter(
      function() {
        changeGridTemplateColumns("2fr 1fr 1fr");
      }
    );

    $(".el-b,.el-e").mouseenter(
      function() {
        changeGridTemplateColumns("1fr 2fr 1fr");
      }
    );

    $(".el-c,.el-f").mouseenter(
      function() {
        changeGridTemplateColumns("1fr 1fr 2fr");
      }
    );

    $(".container").mouseleave(
      function() {
        changeGridTemplateColumns("1fr 1fr 1fr");
        changeGridTemplateRows("1fr 1fr");
      }
    );
  }
);
.container {
  width: 50vw;
  height: 50vw;
  margin: auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, 1fr);
  grid-template-areas: "a b c" "d e f";
}

.el-a {
  grid-area: a;
  background-color: skyblue;
}

.el-b {
  grid-area: b;
  background-color: darkseagreen;
}

.el-c {
  grid-area: c;
  background-color: coral;
}

.el-d {
  grid-area: d;
  background-color: gold;
}

.el-e {
  grid-area: e;
  background-color: plum;
}

.el-f {
  grid-area: f;
  background-color: beige;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="container">
  <div class="el-a"></div>
  <div class="el-d"></div>
  <div class="el-b"></div>
  <div class="el-e"></div>
  <div class="el-c"></div>
  <div class="el-f"></div>
</div>

于 2018-10-29T19:30:46.380 回答
5

目前,网格模板上的过渡不起作用。但是您可以像这样使用转换:

jsFiddle

var button = document.querySelector("#btnToggle");
button.addEventListener("click",function(){
	var content = document.querySelector(".g-content");
  if(content.classList.contains("animate"))
    content.classList.remove("animate");
  else
	  content.classList.add("animate");
});
html,body{
  width:100%;
  height:100%;
  padding:0;
  margin:0;
}

.g-content{
  display:grid;
  height:100%;
  grid-template-columns: 200px 1fr;
  grid-template-rows:60px 1fr 30px;
  grid-template-areas: 
    "g-header g-header"
    "g-side g-main"
    "g-footer g-footer";
 overflow-x:hidden;
}

.g-header{
  grid-area:g-header;
  background:#2B4A6B;
  display:grid;
  grid-template-columns: max-content 1fr;
}

.g-header button{
  align-self:center;
  margin:0 5px;
}

.g-side{
  grid-area:g-side;
  background:#272B30;
  transition:all 0.5s;
}

.g-main{
  grid-area:g-main;
  background:#FFFFFA;
  transition:all 0.5s;
}

.g-footer{
  grid-area:g-footer;
  background:#7E827A
}

.animate .g-main{
  width:calc(100% + 200px);
  transform:translateX(-200px);
}

.animate .g-side{
  transform:translateX(-200px);
}  
<div class="g-content">
  <div class="g-header">
    <button id="btnToggle">
    Toggle
    </button>
  </div>
  <div class="g-side">
  </div>
  <div class="g-main">
  test
  </div>
  <div class="g-footer">
  </div>
</div>

于 2018-07-13T06:55:21.553 回答
3

就我而言,我试图使用以下代码打开侧边栏菜单:

.wrapper{
  display: grid;
  grid-template-columns: 0 100%;
  transition: all 1s;
  .sidebar{
    background-color: blue;
  }
  .content{
    background-color: red;
  }
}
.wrapper.sidebar-open{
  grid-template-columns: 300px 100%;
  transition: all 1s;
}

但是过渡不适用于 grid-template-columns。这是我的解决方案:

.wrapper{
  display: grid;
  grid-template-columns: auto 100%;
  .sidebar{
    width: 0;
    background-color: blue;
    transition: all 1s;
  }
  .content{
    background-color: red;
  }
}
.sidebar.sidebar-open{
  width: 300px;
  transition: all 1s;
}

也许,它可以帮助某人。

于 2018-10-23T12:29:10.993 回答
2

另一种方法是使用transform. 它实际上甚至可能更好,因为不透明的变换可以达到 60fps,因为它是 GPU 加速而不是 CPU 加速(浏览器必须做更少的工作)。

这是一个例子: https ://codepen.io/oneezy/pen/YabaoR

.sides {
  display: grid;
  grid-template-columns: 50vw 50vw;
}

.monkey { animation: 0.7s monkey cubic-bezier(.86,0,.07,1) 0.4s both; }
.robot { animation: 0.7s robot cubic-bezier(.86,0,.07,1) 0.4s both; }

@keyframes monkey {
  0% { transform: translate(-50vw); }
  100% { transform: 0; }
}

@keyframes robot {
  0% { transform: translate(50vw); }
  100% { transform: 0; }
}
于 2018-04-13T11:40:25.737 回答
0

经过数小时的反复试验,我终于找到了一种为网格列设置动画的方法。这会导致列间距变为 0,并且悬停的字段按其宽度扩展。

这是我到目前为止得到的:

$('.cards').each(function(){
  let cols = window.getComputedStyle($(this).get(0));
  let colGapAmount = cols.getPropertyValue("grid-template-columns").split(" ").length - 1;
  let card = $(this).find('.card');
  let standardColWidth = parseInt(card.css('width'), 10);
  let colGapSpace = colGapAmount * parseInt($(this).css('column-gap'), 10);
  let newSize = (standardColWidth + colGapSpace) + 'px';
  //Set Values
  $(this).closest('.cards').get(0).style.setProperty('--scaledSize', newSize);
  $(this).closest('.cards').get(0).style.setProperty('--normalSize', standardColWidth + 'px');
});

$('.card').hover(function(){
  $(this).closest('.cards').addClass('noGap');
},
function(){
  $(this).closest('.cards').removeClass('noGap');
});
.cards {
     --normaleSize: 100%;
     --scaledSize: unset;
     display: grid;
     grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
     column-gap: 20px;
     transition: column-gap 1s ease-in-out;
}
 .cards .card {
     transition: width 1s ease-in-out;
     border: 1px solid black;
     width: var(--normalSize);
}
 .cards .card:hover {
     width: var(--scaledSize);
}
 .cards.noGap {
     column-gap: 0px;
}
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="cards">
  <div class="card">1</div>
  <div class="card">2</div>
  <div class="card">3</div>
  <div class="card">4</div>
  <div class="card">5</div>
</section>

<section class="cards" style="margin-top: 3rem">
  <div class="card">1</div>
  <div class="card">2</div>
  <div class="card">3</div>
  <div class="card">4</div>
  <div class="card">5</div>
</section>

于 2021-04-06T19:26:35.573 回答
0

我找到了一种解决方法,但它要求至少有一个其他列填满宽度。要转换的列必须autogrid-template-columns. 另一个必须是1fr,否则该auto列将使用这个缺失的空间。此外,要转换的列在两种状态下都必须具有绝对宽度。

这里是:

代码笔

document.querySelector('.js-button').addEventListener('click', function() {
  document.querySelector('.js-grid').classList.toggle('grid--full')
})
.grid {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  grid-template-rows: 100px;
  grid-gap: 20px;
  transition: all 1s;
}

.item {
  background-color: #D73B38;
  color: #ffffff;
  padding: 10px;
  border-radius: 5px;
  border: none;
  transition: 1s;
}

.grid .item:nth-child(3n + 2) {
  width: 200px;
  background: blueviolet; 
}
.grid--full .item:nth-child(3n + 2) {
  width: 300px;
  background: cadetblue;
}

button {
  background-color: #123456;
  color: #ffffff;
  margin: 2rem 0;
  padding: 1.4rem;
  border: none;
  border-radius: 5px;
  text-transform: uppercase;
  font-size: 1.2rem;
}
<p>Fork from <a href="https://codepen.io/matuzo/pen/rmQvMG">Manuel Matuzovic</a></p>

<button class="js-button">Animate</button>

<div class="grid js-grid">
  <article class="item">
    <h2>Element 1</h2>
  </article>
  <article class="item">
    <h2>Element 2</h2>
  </article>
  <article class="item">
    <h2>Element 3</h2>
  </article>
  <article class="item">
    <h2>Element 4</h2>
  </article>
  <article class="item">
    <h2>Element 5</h2>
  </article>
  <article class="item">
    <h2>Element 6</h2>
  </article>
</div>

它使用选择器:nth-child(3n + 2)在网格的所有列中执行此操作。但如果您只想更改网格的一个块,也可以使用。

于 2020-09-22T13:37:47.870 回答