在 CSS 网格布局中使用 CSS 过渡



我试图让我的粘性标题具有过渡效果,以便它缓和,而不仅仅是快速移动。

我做错了什么?

这是我的工作版本:

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>

根据规范,过渡应该适用于grid-template-columnsgrid-template-rows

7.2. 显式轨道大小调整:grid-template-rowsgrid-template-columns性能

可动画:作为长度、百分比或计算的简单列表,提供 唯一的区别是长度、百分比或计算值 列表中的组件

因此,如果我的解释是正确的,只要唯一的更改是属性的值,而不更改规则的结构,过渡就应该有效。但他们没有


更新

这确实有效,但到目前为止仅在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>

js小提琴演示

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

作为一种解决方法,您可以使用网格项的大小来代替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

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

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

我使用 GSAP 对网格模板列和网格模板行属性进行动画处理:

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>

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

js小提琴

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>

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

.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;
}

但是过渡不适用于网格模板列。这是我的解决方案:

.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;
}

也许,它可以帮助某人。

另一种方法是使用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; }
}

我找到了一个解决方法,但它要求其他列中至少有一列填满宽度。要转换的列必须在grid-template-columnsauto。另一个必须是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)在网格的所有列中执行该操作。但是,如果您只想更改网格的一个块,也可以工作。

经过数小时的反复试验,我终于找到了一种为网格列设置动画的方法。 这会导致列间距变为 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>

相关内容

  • 没有找到相关文章

最新更新