---
# System prepended metadata

title: '[CSS] 旋轉拼接方塊 - Float'
tags: [CSS]

---

# [CSS] 旋轉拼接方塊 - Float


###### tags: `CSS`


## 預期成果
<iframe height="500" style="width: 100%;" scrolling="no" title="[CSS] 旋轉拼接方塊 - Float" src="https://codepen.io/yuna9068/embed/WNaovJv?default-tab=result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/yuna9068/pen/WNaovJv">
  [CSS] 旋轉拼接方塊 - Float</a> by Yuna (<a href="https://codepen.io/yuna9068">@yuna9068</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>


## 撰寫結構
在 `div.card` 內存放要顯示的文字及圖片
依需求在清單內添加 `div.card`，為了明顯看出排版效果，建議 `.item` 數量至少為 ==每排要顯示的數量 x 兩排==
```htmlembedded=
<ul class="list">
  <li class="item">
    <div class="card">
      <div class="card-text">
        <p class="card-title">旋轉拼接方塊</p>
        <p class="card-desc">使用 float、rotate 排版</p>
      </div>
      <picture class="card-pic">
        <img src="https://picsum.photos/id/200/300/200" alt="Image">
      </picture>
    </div>
  </li>
</ul>
```


## 設定樣式
### 1. 添加 Reset CSS
使用 Eric Meyer 的 [Reset CSS](https://meyerweb.com/eric/tools/css/reset/)，此為個人開發習慣，不一定要加，若未使用的話，依下方步驟排版後需再自行微調樣式

### 2. 基本樣式
```css=
*,
*::before,
*::after {
  box-sizing: inherit;
}

html {
  box-sizing: border-box;
  background: #fff3e0;
}

img {
  vertical-align: top;
}
```

### 3. 處理 card 樣式，並調整為每排顯示兩個項目
```css=
.list {
  max-width: 600px;
  margin: auto;
}

.list::after {
  content: '';
  display: block;
  clear: both;
}

.item {
  width: 50%;
  aspect-ratio: 1 / 1;
  padding: 2.5px;
  float: left;
}

.card {
  aspect-ratio: 1 / 1;
  position: relative;
  overflow: hidden;
}

.card-text {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 90%;
  aspect-ratio: 1 / 1;
  margin: auto;
  padding: 10%;
  position: absolute;
  inset: 0;
  color: #d84315;
  text-align: center;
  text-shadow: 0 0 5px #ffffff;
  opacity: 0;
  scale: 0;
  transition: all 0.3s;
}

.card:hover .card-text {
  opacity: 1;
  scale: 1;
}

.card-text::before {
  content: "";
  position: absolute;
  inset: 0;
  background-color: rgba(250, 250, 250, 0.8);
}

.card-title {
  position: relative;
  font-size: clamp(10px, 3vw , 1.2em);
  line-height: 2;
}

.card-desc {
  position: relative;
  font-size: clamp(8px, 2.5vw , 1em);
  line-height: 1.3;
}

.card-pic {
  display: block;
  aspect-ratio: 1 / 1;
  overflow: hidden;
}

.card-pic > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
```

### 4. 旋轉 card，並調整尺寸及位置
#### 4-1. 旋轉
  * `.card` 旋轉 45 度
  * 文字和圖片旋轉 -45 度
  * 文字背景再旋轉 45 度

#### 4-2. card 尺寸
  * 每個 `.card` 都是正方形（長寬比 1:1），經過旋轉後，最寬處為正方形的對角線長，也就是 √2（約 1.41421356）
  * 為了在 `.item` 中完整顯示，需為 ==父層尺寸 / 1.41421356==，約為父層的 70.710678%

#### 4-3. 圖片尺寸
  * 每張圖片都是正方形（長寬比 1:1），經過旋轉後，最寬處為正方形的對角線長，也就是 √2（約 1.41421356）
  * 為了完整填滿 `.card`，需為 ==父層尺寸 * 1.41421356==，約為父層的 141.421356%

#### 4-4. card、圖片位置
  * `.card` 調整至 `.item` 中間
  * 圖片調整至 `.card` 中間

#### 4-5. 文字 z-index
  * 圖片旋轉後會發現 hover 時不會出現文字，設定 z-index 即可解決

```css=
.card {
  width: 70.710678%;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  rotate: 45deg;
}

.card-text {
  z-index: 1;
  rotate: -45deg;
}

.card-text::before {
  rotate: 45deg;
}

.card-pic {
  width: 141.421356%;
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  rotate: -45deg;
}
```

### 5. 排版
#### 5-1. 調整寬度
  * 為了達到拼接效果，須將`.item` 的 `width` 改為 ==100% / (每排要顯示的項目數 * 2 + 1) * 2==，故值 `50%` 應改為 `40%`

#### 5-1. 調整方塊的位置
  * `left` 調整水平位置
  *  `margin-top` 調整垂直位置

#### 5-1. 處理元素重疊區塊導致 hover 未顯示文字問題
  * `.item` 加 `pointer-events: none;`
  * `.card` 加 `pointer-events: auto;`

```css=
.item {
  width: 40%;
  position: relative;
  pointer-events: none;
}

.item:nth-child(4n+1),
.item:nth-child(4n+2) {
  left: 0;
}

.item:nth-child(4n+3),
.item:nth-child(4n+4) {
  left: 20%;
}

.item:nth-child(n+3) {
  margin-top: -20%;
}

.card {
  pointer-events: auto;
}
```


## 其他寫法
* [使用 Grid 切版](/H17M0oQOp "[CSS] 旋轉拼接方塊 - Grid")


---

:::info
建立日期：2024-01-05
更新日期：2024-01-05
:::