在 CSS 网格布局中使用 CSS 过渡
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43911880/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using CSS transitions in CSS Grid Layout
提问by Dan
I am trying to get my sticky header to have a transition effect so it eases in rather than just a snap movement.
我试图让我的粘性标题具有过渡效果,因此它可以减轻而不仅仅是快速移动。
What am I doing wrong?
我究竟做错了什么?
Here's my a working version:
这是我的工作版本:
http://codepen.io/juanmata/pen/RVMbmr
http://codepen.io/juanmata/pen/RVMbmr
Basically the following code adds the class tiny to my wrapper class, this works fine.
基本上下面的代码将类 tiny 添加到我的包装类中,这很好用。
$(window).on('load', function() {
$(window).on("scroll touchmove", function () {
$('.wrapper').toggleClass('tiny', $(document).scrollTop() > 0);
});
});
Here's the CSS part:
这是 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;
}
So the header does shrink as it should but there is no animation, have I missed something or does transitions simply not work with grid?
所以标题确实缩小了,但没有动画,我错过了什么还是过渡根本不适用于网格?
Here's a link to the css-grid docs.
这是 css-grid 文档的链接。
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout
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>
采纳答案by Michael Benjamin
According to the spec, transitions should work on grid-template-columns
and grid-template-rows
.
根据规范,转换应该适用于grid-template-columns
和grid-template-rows
。
7.2. Explicit Track Sizing: the
grid-template-rows
andgrid-template-columns
propertiesAnimatable:as a simple list of length, percentage, or calc, provided the only differences are the values of the length, percentage, or calc components in the list
7.2. Explicit Track Sizing: the
grid-template-rows
和grid-template-columns
属性Animatable:作为长度、百分比或计算的简单列表,提供的唯一区别是列表中的长度、百分比或计算组件的值
So, if my interpretation is correct, as long as the only changes are to the values of the properties, with no changes to the structure of the rule, transitions should work. But they don't.
所以,如果我的解释是正确的,只要唯一的变化是属性的值,规则的结构没有变化,过渡就应该起作用。但他们没有。
UPDATE
更新
This does work but is so far only implemented in Firefox. Follow here for other browser updates. https://codepen.io/matuzo/post/animating-css-grid-layout-properties
这确实有效,但目前仅在 Firefox 中实现。按照此处获取其他浏览器更新。 https://codepen.io/matuzo/post/animating-css-grid-layout-properties
~ a contribution in the comments by @bcbrian
Here's a test I created:
这是我创建的一个测试:
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>
In the test, the transition works on the height and background color, but not on grid-template-rows
or grid-template-columns
.
在测试中,过渡适用于高度和背景颜色,但不适用于grid-template-rows
或grid-template-columns
。
回答by Erik
As a workaround, you can work with the size of the grid items instead with grid-template-columns
or grid-template-rows
.
作为一种解决方法,您可以使用grid-template-columns
或来处理网格项目的大小grid-template-rows
。
You could do:
你可以这样做:
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>
Here's another 2x2 example: https://codepen.io/erik127/pen/OvodQR
这是另一个 2x2 示例:https: //codepen.io/erik127/pen/OvodQR
and here a more extensive example where you can add more columns or rows: https://codepen.io/erik127/pen/rdZbxL
这是一个更广泛的示例,您可以在其中添加更多列或行:https: //codepen.io/erik127/pen/rdZbxL
Unfortunately it's a lot of javascript, it would be nice if grid-template-columns
and grid-template-rows
would be animatable.
不幸的是,它有很多 javascript,如果grid-template-columns
并且grid-template-rows
是可动画的,那就太好了。
Another alternative which might work in some usecases (if your grid items don't span multiple rows) is the use of flexbox together with a grid.
另一种可能适用于某些用例(如果您的网格项不跨越多行)的替代方法是将 flexbox 与网格一起使用。
回答by Pep Santacruz
I used GSAP to animate the grid-template-columns and grid-template-rows properties:
我使用 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>
回答by Emre HIZLI
For now the transition on the grid template is not working. But you can use transform like this:
现在网格模板上的过渡不起作用。但是你可以像这样使用转换:
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>
回答by Dmitry Grinko
In my case I was trying to open sidebar-menu by using this code:
就我而言,我试图使用以下代码打开侧边栏菜单:
.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;
}
but transition was not working for grid-template-columns. This is my solution:
但过渡不适用于 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;
}
Perhaps, it helps someone.
也许,它可以帮助某人。
回答by Oneezy
Another approach is to use transform
. It actually might even be better because transform along w/ opacity can achieve 60fps because it's GPU accelerated instead of CPU accelerated (browser has to do less work).
另一种方法是使用transform
. 它实际上甚至可能更好,因为沿不透明度变换可以达到 60fps,因为它是 GPU 加速而不是 CPU 加速(浏览器必须做的工作更少)。
here's an example:https://codepen.io/oneezy/pen/YabaoR
这是一个例子: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; }
}
回答by Micha? Smoczyński
There is a way to resize grid elements on transition using only CSS, but if you want to resize it, you should use %'s properly, but in your examples problem exists because of sticky position. You have to add height on your .head
element and then change height after adding .tiny
class. Here you can check how I fixed it ( I guess that's the result which you wanted to have ):
有一种方法可以仅使用 CSS 在过渡时调整网格元素的大小,但是如果您想调整它的大小,您应该正确使用 %,但在您的示例中,由于位置粘滞而存在问题。您必须在.head
元素上添加高度,然后在添加.tiny
类后更改高度。在这里你可以检查我是如何修复它的(我想这就是你想要的结果):
Michael answer should use %'s in your example because right now it has "blink" effect on hover, if changed to values from px on %'s it will work perfectly on resize. Here is that example changed on %'s:
迈克尔的回答应该在您的示例中使用 %'s 因为现在它在悬停时具有“闪烁”效果,如果更改为 %'s 上的 px 值,它将在调整大小时完美运行。这是在 % 上更改的示例: