手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

 3572

在前端面试中,经常会问到如何使用 CSS 实现骰子/麻将布局。下面本篇文章给大家介绍一下用CSS 创建一个 3D 骰子(Flex和Grid布局实现3D骰子)的方法,希望对大家有所帮助!


手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)


通过本文可以学到:

使用transform来实现3D形状;

给 3D 骰子实现旋转动画;

使用 Flex 布局来实现骰子布局;

使用 Grid 布局来实现骰子布局。

1. 使用 Flex 布局实现六个面

首先,来定义骰子六个面的 HTML 结构:

  1. <div class="dice-box">
  2.   <div class="dice first-face">
  3.     <span class="dot"></span>
  4.   </div>
  5.   <div class="dice second-face">
  6.     <span class="dot"></span>
  7.     <span class="dot"></span>
  8.   </div>
  9.   <div class="dice third-face">
  10.     <span class="dot"></span>
  11.     <span class="dot"></span>
  12.     <span class="dot"></span>
  13.   </div>
  14.   <div class="dice fourth-face">
  15.     <div class="column">
  16.       <span class="dot"></span>
  17.       <span class="dot"></span>
  18.     </div>
  19.     <div class="column">
  20.       <span class="dot"></span>
  21.       <span class="dot"></span>
  22.     </div>
  23.   </div>
  24.   <div class="fifth-face dice">
  25.     <div class="column">
  26.       <span class="dot"></span>
  27.       <span class="dot"></span>
  28.     </div>
  29.     <div class="column">
  30.       <span class="dot"></span>
  31.     </div>
  32.     <div class="column">
  33.       <span class="dot"></span>
  34.       <span class="dot"></span>
  35.     </div>
  36.   </div>
  37.   <div class="dice sixth-face">
  38.     <div class="column">
  39.       <span class="dot"></span>
  40.       <span class="dot"></span>
  41.       <span class="dot"></span>
  42.     </div>
  43.     <div class="column">
  44.       <span class="dot"></span>
  45.       <span class="dot"></span>
  46.       <span class="dot"></span>
  47.     </div>
  48.   </div>
  49. </div>

下面来实现每个面和每个点的的基本样式:

  1. .dice {
  2.   width: 200px;  
  3.   height: 200px;  
  4.   padding: 20px;  
  5.   background-color: tomato;
  6.   border-radius: 10%;
  7. }
  8.   
  9. .dot {
  10.    display: inline-block;
  11.    width: 50px;
  12.    height: 50px;
  13.    border-radius: 50%;
  14.    background-color: white;
  15. }

实现效果如下:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

(1)一个点

HTML 结构如下:

  1. <div class="dice first-face">
  2.   <span class="dot"></span>
  3. </div>

实现第一个面,只需要让它水平和垂直方向都居中即可:

justify-content:center:使点与主轴(水平)的中心对齐。

align-items:center:使点与交叉轴(垂直)的中心对齐。

代码实现如下:

  1. .first-face {
  2.   display: flex;
  3.   justify-content: center;
  4.   align-items: center;
  5. }

现在第一面是这样的:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

(2)两个点

HTML 结构如下:

  1. <div class="dice second-face">
  2.   <span class="dot"></span>
  3.   <span class="dot"></span>
  4. </div>

首先来将第二个面的父元素设置为flex布局,并添加以下属性:

justify-content: space-between:将子元素放置在 flex 容器的开头和结尾。

  1. .second-face {
  2.    display: flex;
  3.    justify-content : space-between;
  4. }

现在点的位置如下:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

这时,第一个点在正确的位置:左上角。而第二个点需要在右下角。因此,下面来使用 align-self 属性单独调整第二个点的位置:

align-self: flex-end:将项目对齐到 Flex 容器的末尾。

  1. .second-face .dot:nth-of-type(2) {
  2.  align-self: flex-end;
  3. }

现在第二面是这样的:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

(3)三个点

HTML 结构如下:

  1. <div class="dice third-face">
  2.   <span class="dot"></span>
  3.   <span class="dot"></span>
  4.   <span class="dot"></span>
  5. </div>

可以通过在第二面放置另一个中心点来实现第三面。

align-self: flex-end:将项目对齐到 Flex 容器的末尾。

align-self: center:将项目对齐到 Flex 容器的中间。

  1. .third-face {
  2.  display: flex;
  3.   justify-content : space-between;
  4. }
  5. .third-face .dot:nth-of-type(2) {
  6.  align-self: center;
  7. }
  8. .third-face .dot:nth-of-type(3) {
  9.  align-self: flex-end;
  10. }

现在第三面是这样的:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

如果想要第一个点在右上角,第三个点在左下角,可以将第一个点的 align-self 更改为 flex-end,第二个点不变,第三个点无需设置,默认在最左侧:

  1. .third-face {
  2.  display: flex;
  3.   justify-content : space-between;
  4. }
  5. .third-face .dot:nth-of-type(1) {
  6.  align-self :flex-end;
  7. }
  8. .third-face .dot:nth-of-type(2) {
  9.  align-self :center;
  10. }

现在第三面是这样的:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

(4)四个点

HTML 结构如下:

  1. <div class="dice fourth-face">
  2.   <div class="column">
  3.     <span class="dot"></span>
  4.     <span class="dot"></span>
  5.   </div>
  6.   <div class="column">
  7.     <span class="dot"></span>
  8.     <span class="dot"></span>
  9.   </div>
  10. </div>

在四个点的面中,可以将其分为两行,每行包含两列。一行将在 flex-start ,另一行将在 flex-end 。并添加 justify-content: space-between 以便将其放置在骰子的左侧和右侧。

  1. .fourth-face {
  2.  display: flex;
  3.  justify-content: space-between
  4. }

接下来需要对两列点分别进行布局:

将列设置为flex布局;

将flex-direction设置为column,以便将点放置在垂直方向上

将justify-content设置为space-between,它将使第一个点在顶部,第二个点在底部。

  1. .fourth-face .column {
  2.  display: flex;
  3.   flex-direction: column;
  4.   justify-content: space-between;
  5. }

现在第四面是这样的:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

(5)五个点

HTML 结构如下:

  1. <div class="fifth-face dice">
  2.   <div class="column">
  3.     <span class="dot"></span>
  4.     <span class="dot"></span>
  5.   </div>
  6.   <div class="column">
  7.     <span class="dot"></span>
  8.   </div>
  9.   <div class="column">
  10.     <span class="dot"></span>
  11.     <span class="dot"></span>
  12.   </div>
  13. </div>

第五面和第四面的差异在于多了中间的那个点。所以,可以基于第四面,来在中间增加一列,样式如下:

  1. .fifth-face {
  2.  display: flex;
  3.  justify-content: space-between
  4. }
  5. .fifth-face .column {
  6.  display: flex;
  7.   flex-direction: column;
  8.   justify-content: space-between;
  9. }

现在第五面是这样的:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

还需要对中间的点进行调整,可以设置 justify-content 为 center 让它垂直居中:

  1. .fifth-face .column:nth-of-type(2) {
  2.  justify-content: center;
  3. }

现在第五面是这样的:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

(6)六个点

HTML 结构如下:

  1. <div class="dice sixth-face">
  2.   <div class="column">
  3.     <span class="dot"></span>
  4.     <span class="dot"></span>
  5.     <span class="dot"></span>
  6.   </div>
  7.   <div class="column">
  8.     <span class="dot"></span>
  9.     <span class="dot"></span>
  10.     <span class="dot"></span>
  11.   </div>
  12. </div>

第六个面的布局和第四个几乎完全一样,只不过每一列多了一个元素,布局实现如下:

  1. .sixth-face {
  2.  display: flex;
  3.  justify-content: space-between
  4. }
  5.  
  6. .sixth-face .column {
  7.  display: flex;
  8.   flex-direction: column;
  9.   justify-content: space-between;
  10. }

现在第六面是这样的:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

2. 使用 Grid 布局实现六个面

骰子每个面其实可以想象成一个 3 x 3 的网格,其中每个单元格代表一个点的位置:

+---+---+---+
| a | b | c |
+---+---+---+
| d | e | f |
+---+---+---+
| g | h | i |
+---+---+---+

要创建一个 3 x 3 的网格,只需要设置一个容器元素,并且设置三个大小相同的行和列:

  1. .dice {
  2.     display: grid;
  3.     grid-template-rows: 1fr 1fr 1fr;
  4.     grid-template-columns: 1fr 1fr 1fr;
  5. }

这里的 fr 单位允许将行或列的大小设置为网格容器可用空间的一部分,这上面的例子中,我们需要三分之一的可用空间,所以设置了 1fr 三次。

我们还可以使用 repeat(3, 1fr) 将 1fr 重复 3 次,来代替 1fr 1fr 1fr。还可以使用定义行/列的grid-template速记属性将上述代码进行简化:

  1. .dice {
  2.     display: grid;
  3.     grid-template: repeat(3, 1fr) / repeat(3, 1fr);
  4. }

每个面所需要定义的 HTML 就像是这样:

  1. <div class="dice">
  2.   <span class="dot"></span>
  3.   <span class="dot"></span>
  4.   <span class="dot"></span>
  5.   <span class="dot"></span>
  6. </div>

所有的点将自动放置在每个单元格中,从左到右:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

现在我们需要为每个骰子值定位点数。开始时我们提到,可以将每个面分成 3 x 3 的表格,但是这些表格并不是每一个都是我们需要的,分析骰子的六个面,可以发现,我们只需要以下七个位置的点:

+---+---+---+
| a |   | c |
+---+---+---+
| e | g | f |
+---+---+---+
| d |   | b |
+---+---+---+

我们可以使用grid-template-areas属性将此布局转换为 CSS:

  1. .dice {
  2.   display: grid;
  3.   grid-template-areas:
  4.     "a . c"
  5.     "e g f"
  6.     "d . b";
  7. }

因此,我们可以不使用传统的单位来调整行和列的大小,而只需使用名称来引用每个单元格。其语法本身提供了网格结构的可视化,名称由网格项的网格区域属性定义。中间列中的点表示一个空单元格。

下面来使用grid-area属性为网格项命名,然后,网格模板可以通过其名称引用该项目,以将其放置在网格中的特定区域中。:nth-child()伪选择器允许单独定位每个点。

  1. .dot:nth-child(2) {
  2.     grid-area: b;
  3. }
  4. .dot:nth-child(3) {
  5.     grid-area: c;
  6. }
  7. .dot:nth-child(4) {
  8.     grid-area: d;
  9. }
  10. .dot:nth-child(5) {
  11.     grid-area: e;
  12. }
  13. .dot:nth-child(6) {
  14.     grid-area: f;
  15. }

现在六个面的样式如下:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

可以看到,1、3、5的布局仍然是不正确的,只需要重新定位每个骰子的最后一个点即可:

  1. .dot:nth-child(odd):last-child {
  2.     grid-area: g;
  3. }

这时所有点的位置都正确了:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

对于上面的 CSS,对应的 HTML分别是父级为一个div标签,该面有几个点,子级就有几个span标签。代码如下:

  1. <div class="dice-box">
  2.   <div class="dice first-face">
  3.     <span class="dot"></span>
  4.   </div>
  5.   <div class="dice second-face">
  6.     <span class="dot"></span>
  7.     <span class="dot"></span>
  8.   </div>
  9.   <div class="dice third-face">
  10.     <span class="dot"></span>
  11.     <span class="dot"></span>
  12.     <span class="dot"></span>
  13.   </div>
  14.   <div class="dice fourth-face">
  15.     <span class="dot"></span>
  16.     <span class="dot"></span>
  17.     <span class="dot"></span>
  18.     <span class="dot"></span>
  19.   </div>
  20.   <div class="fifth-face dice">
  21.     <span class="dot"></span>
  22.     <span class="dot"></span>
  23.     <span class="dot"></span>
  24.     <span class="dot"></span>
  25.     <span class="dot"></span>
  26.   </div>
  27.   <div class="dice sixth-face">
  28.     <span class="dot"></span>
  29.     <span class="dot"></span>
  30.     <span class="dot"></span>
  31.     <span class="dot"></span>
  32.     <span class="dot"></span>
  33.     <span class="dot"></span>
  34.   </div>
  35. </div>

整体的 CSS 代码如下:

  1. .dice {
  2.   width: 200px;  
  3.   height: 200px;  
  4.   padding: 20px;  
  5.   background-color: tomato;
  6.   border-radius: 10%;
  7.   display: grid;
  8.   grid-template: repeat(3, 1fr) / repeat(3, 1fr);
  9.   grid-template-areas:
  10.     "a . c"
  11.     "e g f"
  12.     "d . b";
  13. }
  14. .dot {
  15.   display: inline-block;
  16.   width: 50px;
  17.   height: 50px;
  18.   border-radius: 50%;
  19.   background-color: white;
  20. }
  21. .dot:nth-child(2) {
  22.   grid-area: b;
  23. }
  24. .dot:nth-child(3) {
  25.   grid-area: c;
  26. }
  27. .dot:nth-child(4) {
  28.   grid-area: d;
  29. }
  30. .dot:nth-child(5) {
  31.   grid-area: e;
  32. }
  33. .dot:nth-child(6) {
  34.   grid-area: f;
  35. }
  36. .dot:nth-child(odd):last-child {
  37.   grid-area: g;
  38. }

3. 实现 3D 骰子

上面我们分别使用 Flex 和 Grid 布局实现了骰子的六个面,下面来这将六个面组合成一个正方体。

首先对六个面进行一些样式修改:

  1. .dice {
  2.   width: 200px;  
  3.   height: 200px;  
  4.   padding: 20px;
  5.   box-sizing: border-box;
  6.   opacity: 0.7;
  7.   background-color: tomato;
  8.   position: absolute;
  9. }

定义它们的父元素:

  1. .dice-box {
  2.   width: 200px;
  3.   height: 200px;
  4.   position: relative;
  5.   transform-style: preserve-3d;
  6.   transform: rotateY(185deg) rotateX(150deg) rotateZ(315deg);
  7. }

其中,transform-style: preserve-3d;表示所有子元素在3D空间中呈现。这里的transform 的角度不重要,主要是便于后面查看。

此时六个面的这样的:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

看起来有点奇怪,所有面都叠加在一起。不要急,我们来一个个调整位置。

首先将第一个面在 Z 轴移动 100px:

  1. .first-face {
  2.   transform: translateZ(100px);
  3. }

第一面就到了所有面的上方:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

因为每个面的宽高都是 200px,所以将第六面沿 Z 轴向下调整 100px:

  1. .sixth-face {
  2.   transform: translateZ(-100px);
  3. }

第六面就到了所有面的下方:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

下面来调整第二面,将其在X轴向后移动 100px,并沿着 Y 轴旋转 -90 度:

  1. .second-face {
  2.   transform: translateX(-100px) rotateY(-90deg);
  3. }

此时六个面是这样的:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

下面来调整第二面的对面:第五面,将其沿 X 轴的正方向移动 100px,并沿着 Y 轴方向选择 90 度:

  1. .fifth-face {
  2.   transform: translateX(100px) rotateY(90deg);
  3. }

此时六个面是这样的:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

下面来调整第三面,道理同上:

  1. .third-face {
  2.   transform: translateY(100px) rotateX(90deg);
  3. }

此时六个面是这样的:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

最后来调整第五面:

  1. .fourth-face {
  2.   transform: translateY(-100px) rotateX(90deg);
  3. }

此时六个面就组成了一个完整的正方体:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

下面来为这个骰子设置一个动画,让它转起来:

  1. @keyframes rotate {
  2.   from {
  3.     transform: rotateY(0) rotateX(45deg) rotateZ(45deg);
  4.   }
  5.   to {
  6.     transform: rotateY(360deg) rotateX(45deg) rotateZ(45deg);
  7.   }
  8. }
  9. .dice-box {
  10.   animation: rotate 5s linear infinite;
  11. }

最终的效果如下:

手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)

在线体验:

3D 骰子-Flex:https://codepen.io/cugergz/pen/jOzYGyV

3D 骰子-Grid:https://codepen.io/cugergz/pen/GROMgEe


本文网址:https://www.zztuku.com/index.php/detail-13113.html
站长图库 - 手把手带你使用CSS Flex和Grid布局实现3D骰子(附代码)
申明:本文转载于《脚本之家》,如有侵犯,请 联系我们 删除。

评论(0)条

您还没有登录,请 登录 后发表评论!

提示:请勿发布广告垃圾评论,否则封号处理!!

    编辑推荐