#19. 3D Background Boxes

这次的任务是透过伪元素来打造立体盒子,同时利用background position属性来做出方块组成的效果。有点像幼儿会玩的立体方块拼图。

https://ithelp.ithome.com.tw/upload/images/20210923/201305343FUa3abmkj.png

让我们先看一下成果:CodePen


实作方法

让我们来了解一下图片是如何被拼起来的:
https://ithelp.ithome.com.tw/upload/images/20210923/20130534c6RZhYZAfO.png

从上图可以见到,一幅完整的小小兵图像,实际上是由16个拼起来的,而每个所显示的图像区块,则透过background-position来指定。由於外层div.boxes的宽高是500px,分割给16个div.box,每个div.box的宽高便是125px,在background-position的位移,也就会以125px为一个单位来移动。

https://ithelp.ithome.com.tw/upload/images/20210923/20130534GfTloVdASf.png

当我们按下Magic按钮,则透过Javascript在div#boxes如果再加上了big选择器,这时候div#boxes的宽高就变成600px,而内层的16个div.box高宽不变,这时使用flexbox的justify-content: space-around分配剩余空间,就会整齐地将16个div.box分开。在这之前,要注意两个属性

  1. flex-wrap要设定成wrap,让内层div.box占满一行後自动跳到下一行。
  2. 外层div#boxes的宽度必须要在624px以内,否则第五个方块就会挤到第一行。

最後再利用伪元素做出右下方的border,就会产生立体方块的视觉效果


程序码部分

Javascript

const boxesContainer = document.getElementById('boxes')
const btn = document.getElementById('btn')

// 点击按钮,toggle big选择器
btn.addEventListener('click', () => boxesContainer.classList.toggle('big'))

// 利用双层回圈产生16个div.box,放入boxesContainer当中,同时利用回圈将backgroundPosition的属性设定好。
function createBoxes() {
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      const box = document.createElement('div')
      box.classList.add('box')
      box.style.backgroundPosition = `${-j * 125}px ${-i * 125}px`
      boxesContainer.appendChild(box)
    }
  }
}

createBoxes()

CSS

.boxes {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  height: 500px;
  width: 500px;
  position: relative;
  transition: 0.4s ease;

  &.big {
    width: 624px;
    height: 624px;
    .box {
      transform: rotateZ(180deg);
    }
  }
}

.box {
  background-image: url('https://media.giphy.com/media/EZqwsBSPlvSda/giphy.gif');
  background-repeat: no-repeat;
  background-size: 500px 500px;
  position: relative;
  height: 125px;
  width: 125px;
  transition: 0.4s ease;

  /* 利用伪元素做出box的立体面 */
  &::after {
    content: '';
    background-color: #f6e58d;
    position: absolute;
    top: 8px;
    right: -15px;
    height: 100%;
    width: 15px;
    transform: skewY(45deg);
  }
  
  &::before {
    content: '';
    background-color: #f9ca24;
    position: absolute;
    bottom: -15px;
    left: 8px;
    height: 15px;
    width: 100%;
    transform: skewX(45deg);
  }
}

<<:  Day 21-制作购物车之前端架构1

>>:  Day 8: Recap Day [1-7] & Enhance

RESTful API 操作对数据完整性的影响最小-Get

-RESTful HTTP 方法 HTTP 方法/动词 GET 通常用於检索数据,这会影响机密性。...

Day 14 - UML x Interface — Portal

UML Portal 是什麽? 开始之前,先说一下 Portal 其实是 React 比较常用的 ...

Day11. UX/UI 设计流程之一: Functional Map (以 Axure RP 实作)

有了 User Story,已经能够了解产品会有哪些角色、他们的需求及功能价值。但缺少的是这些需求...

[Day4] API开发规格书

看完永丰的API规格书,开始盘点所需之参数。 由规格书可知,呼叫API所需要的参数有Version、...

Day.23 Binary Search Tree

终於讲到树,快接近尾声了(烟 二元搜寻图(Binary Search Tree)是一种很高效的资料结...