css网格儿童缩放过渡/动画

问题描述 投票:1回答:2

我正在尝试在css网格中缩放孩子的大小,但是我没有成功。问题是我实际上没有缩放它,我只是更改了列和行的位置以填充所有网格。

div {
      width: 100%;
      height: 140px;
      display: grid;
      grid-template-columns: 1fr 1fr 1fr;
      grid-template-rows: 1fr 1fr;
      grid-gap: 20px;
  }


div:active {
    grid-column-start: 1;
    grid-column-end: 5;
    grid-row-start: 1;
    grid-row-end: 4;
    height: 140px; //the size of the grid is 140px just because it doesn't work if you do 100%
    z-index: 3;
 }

enter image description here

如您所见,结果并不是最好的,它们似乎并没有“按比例缩放”,只是从顶部下降。我尝试了使用CSS网格,但是我不知道这是否是最好的方法(使用CSS网格而不是flexbox)。

enter image description here

html css flexbox css-grid
2个回答
1
投票

尝试添加在父级活动对象上具有绝对位置的内部元素。

.box {
    width: 100%;
    height: 140px;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    grid-gap: 20px;
    position: relative;
}

.inner-child {
  height: 100%; width: 100%;
}

.element:nth-child(1) .inner-child {background: #ff0000}
.element:nth-child(2) .inner-child {background: #ffe600}
.element:nth-child(3) .inner-child {background: #14ff00}
.element:nth-child(4) .inner-child {background: #00fff0}
.element:nth-child(5) .inner-child {background: #001aff}
.element:nth-child(6) .inner-child {background: #d400ff}

.element:active .inner-child {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
}
<div class="box">
  <div class="element">
    <div class="inner-child">
    </div>
  </div>
  <div class="element">
    <div class="inner-child">
    </div>
  </div>
  <div class="element">
    <div class="inner-child">
    </div>
  </div>
  <div class="element">
    <div class="inner-child">
    </div>
  </div>
  <div class="element">
    <div class="inner-child">
    </div>
  </div>
  <div class="element">
    <div class="inner-child">
    </div>
  </div>
</div>

对于动画,我们必须添加一个脚本。

setTimeout(function(){ // need to whati untill grid loads.
  let gridWidth = $('.box').width();
  let gridHeight = $('.box').height();
  
  $('.element').each(function () {
    let elementW = $(this).width();
    let elementH = $(this).height();    
    let thisP = $(this).position();

    $(this).find('.inner-child').css({'left': thisP.left + 'px', 'right': gridWidth - (elementW + thisP.left) + 'px', 'top': thisP.top + 'px', 'bottom': gridHeight - (elementH + thisP.top) + 'px'});

  });

}, 200);
.box {
    width: 100%;
    height: 140px;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    grid-gap: 20px;
    position: relative;
}

.inner-child {
  position: absolute;
  z-index: 1;
  transition: all .5s ease;
}

.element:nth-child(1) .inner-child {background: #ff0000}
.element:nth-child(2) .inner-child {background: #ffe600}
.element:nth-child(3) .inner-child {background: #14ff00}
.element:nth-child(4) .inner-child {background: #00fff0}
.element:nth-child(5) .inner-child {background: #001aff}
.element:nth-child(6) .inner-child {background: #d400ff}

.element:active .inner-child {
  left: 0 !important;
  right: 0 !important;
  top: 0 !important;
  bottom: 0 !important;
  z-index: 100;
}
<script
  src="https://code.jquery.com/jquery-3.5.1.min.js"
  integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
  crossorigin="anonymous"></script>
<div class="box">
  <div class="element">
    <div class="inner-child">
    </div>
  </div>
  <div class="element">
    <div class="inner-child">
    </div>
  </div>
  <div class="element">
    <div class="inner-child">
    </div>
  </div>
  <div class="element">
    <div class="inner-child">
    </div>
  </div>
  <div class="element">
    <div class="inner-child">
    </div>
  </div>
  <div class="element">
    <div class="inner-child">
    </div>
  </div>
</div>

1
投票

这是一个纯CSS解决方案,它依赖于只有6个项目的事实,这意味着它本质上不是动态的,需要格外小心。

工作原理

  1. 我们为每个元素定义一个网格区域,这样,网格项目将相对于其网格区域而不是网格容器,因此我们可以转换宽度/高度。
  2. 我们将网格项目放置在它们各自的网格区域中。
  3. 我们绝对放置网格项目,因为定义了网格区域,所以不会有重叠。
  4. 我们为网格项目提供适当的锚点,以便它们从其位置开始生长(示例:右上角的元素将具有top:0;right:0]]]
  5. 中间元素需要特别注意,在代码中已指出

[grid] {
  width: 100%;
  height: 140px;
  display: grid;
  grid-template-areas: "a b c""d e f";
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  grid-gap: 20px;
  position: relative;
}

[grid]>[item]:nth-child(1) {
  background: #ff0000;
  grid-area: a;
  top: 0;
  left: 0;
}

[grid]>[item]:nth-child(2) {
  background: #ffe600;
  grid-area: b;
  top: 0;
}

[grid]>[item]:nth-child(3) {
  background: #14ff00;
  grid-area: c;
  top: 0;
  right: 0;
}

[grid]>[item]:nth-child(4) {
  background: #00fff0;
  grid-area: d;
  bottom: 0;
  left: 0;
}

[grid]>[item]:nth-child(5) {
  background: #001aff;
  grid-area: e;
  bottom: 0;
}

[grid]>[item]:nth-child(6) {
  background: #d400ff;
  grid-area: f;
  bottom: 0;
  right: 0;
}
/* Extra care for the middle elements
 * So they can transition from the middle  
*/
[grid]>[item]:nth-child(5),
[grid]>[item]:nth-child(2) {
  left: 50%;
  transform: translateX(-50%);
}

[grid]>[item] {
  position: absolute;
  width: 100%;
  height: 100%;
}

/* width: calc(300% + 40px); 
 * 300% beacause we have 3 columns each column is 100%
 * becasue the grid item is relative to it's grid area not the grid container
 * 3 columns is 100% * 3 = 300%
 * 40px is the grid gap, You can css variables to make it accessible for the grid items.
 * Same applies to the height.
*/

[grid]>[item]:hover {
  height: calc(200% + 20px);
  width: calc(300% + 40px);
  transition: all .5s linear;
  z-index: 5;
}
<div grid>
  <div item></div>
  <div item></div>
  <div item></div>
  <div item></div>
  <div item></div>
  <div item></div>
</div>
© www.soinside.com 2019 - 2024. All rights reserved.