CSS 座æ¨å¤æã®ä½¿ç¨
CSS 座æ¨å¤æ (CSS transforms) ã¯ã座æ¨ç©ºéã夿´ãããã¨ã§ãéå¸¸ã®ææ¸ããã¼ãæ··ä¹±ãããã«å½±é¿ä¸ã«ããã³ã³ãã³ãã®å½¢ç¶ãä½ç½®ãå¤ãããã¨ãã§ãã¾ãããã®ã¬ã¤ãã¯åº§æ¨å¤æã®ä½¿ç¨ã«ã¤ãã¦ã®è§£èª¬ãè¡ãªãã¾ãã
CSS 座æ¨å¤æã¯ãã¢ãã£ã³ç·å½¢å¤æã HTML è¦ç´ ã«å¯¾ãã¦é©ç¨ããä¸é£ã® CSS ããããã£ã«ãã£ã¦å®ç¾ããã¾ãã座æ¨å¤æã«ã¯ãå転 (rotation)ãæªã (skewing)ãå¤å (scaling)ãå¹³è¡ç§»å (translation) ãªã©ããããå¹³é¢ã¨ 3D 空éã®ä¸¡æ¹ã§è¡ããã¾ãã
è¦å:
座æ¨å¤æå¯è½ãªè¦ç´ ã ãã transform ãããã¨ãã§ãã¾ããã¤ã¾ããã¬ã¤ã¢ã¦ãã CSS ããã¯ã¹ã¢ãã«ã«ãã£ã¦ç®¡çããããã¹ã¦ã®è¦ç´ ã§ãããã ããç½®æã§ã¯ãªãã¤ã³ã©ã¤ã³ããã¯ã¹ã表ã®åããã¯ã¹ã表ã®åã°ã«ã¼ãããã¯ã¹ã¯é¤ãã¾ãã
CSS 座æ¨å¤æã®ããããã£
CSS 座æ¨å¤æã®å®ç¾©ã«ä½¿ããã主ãªããããã£ã 2 ã¤ããã¾ãã transform ï¼ã¾ãã¯ç¬ç«ãã translate, rotate, scale ã®åããããã£ï¼ã¨ transform-origin ã§ãã
transform-origin-
åç¹ä½ç½®ãæå®ãã¾ããããã©ã«ãã§ã¯ãããã¯è¦ç´ ã®ä¸å¤®ã§ãããç§»åãããã¨ãã§ãã¾ããç¹å®ã®ç¹ã弿°ã¨ãã¦å¿ è¦ã¨ããå転ãå¤åãæªããªã©ã®åº§æ¨å¤æã§ä½¿ç¨ããã¾ãã
transform-
è¦ç´ ã«é©ç¨ãã座æ¨å¤æãæå®ãã¾ãã座æ¨å¤æã®ç©ºç½åºåãã®ãªã¹ãã§ãåææä½ã®è¦æ±ãããé çªã§é©ç¨ããã¾ãã座æ¨å¤æã®åæã¯å³ããå·¦ã®é ã«é©ç¨ããã¾ãã
ä¾
ããã座æ¨å¤æåã® MDN ãã´ã®ç»åã§ãã

å転
ããã§ã¯ MDN ãã´ããå·¦ä¸ã®è§ãã 90 度å転ããã¾ãã
<img src="logo.png" alt="MDN Logo" />
img {
rotate: 90deg;
transform-origin: bottom left;
}
æªãã¨å¹³è¡ç§»å
ãã®ä¾ã¯ div è¦ç´ ã 10 度æªãã X è»¸ã«æ²¿ã£ã¦ 150 ãã¯ã»ã«å¹³è¡ç§»åãã¾ãã
<img src="logo.png" alt="MDN logo" />
img {
transform: skewX(10deg) translateX(150px);
transform-origin: bottom left;
}
3D ç¹æã® CSS ããããã£
ç«ä½ç©ºéã§ CSS 座æ¨å¤æ ãè¡ãã«ã¯ãããå°ãè¤éã«ãªãã¾ããè¦ç¹ãä¸ã㦠3D 空éã®ç°å¢è¨å®ãè¡ããã¨ããå§ããå¿ è¦ãããããããã 2D ã®è¦ç´ ããã®ç©ºéã§ã¨ãæåãè¨å®ããªããã°ãªãã¾ããã
è¦ç¹
è¨å®ããæåã®è¦ç´ ã¯è¦ç¹ (perspective) ã§ããè¦ç¹ã¯ 3D ã®å°è±¡ãä¸ãããã®ã§ããè¦ã人ããé ãããã»ã©ããã®ãå°ãããªãã¾ãã
è¦ç¹ã®è¨å®
ãã®ä¾ã¯æ§ã
ãªä½ç½®ã«è¦ç¹ãè¨å®ãããç«æ¹ä½ã表示ãã¾ããã©ã®ããã«ç«æ¹ä½ãæ©ã縮ã¾ããã¯ã perspective ããããã£ã§å®ç¾©ããã¾ããå°ããå¤ã»ã©ãè¦ç¹ã¯è¿ããªãã¾ãã
HTML
以ä¸ã® HTML ã¯ãï¼ã¤ã®åãããã¯ã¹ã®ã³ãã¼ããæ§ã ãªå¤ã®è¦ç¹ãè¨å®ãã¦ä½æãã¾ãã
<table>
<tbody>
<tr>
<th><code>perspective: 250px;</code></th>
<th><code>perspective: 350px;</code></th>
</tr>
<tr>
<td>
<div class="container">
<div class="cube perspective-250">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</td>
<td>
<div class="container">
<div class="cube perspective-350">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</td>
</tr>
<tr>
<th><code>perspective: 500px;</code></th>
<th><code>perspective: 650px;</code></th>
</tr>
<tr>
<td>
<div class="container">
<div class="cube perspective-500">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</td>
<td>
<div class="container">
<div class="cube perspective-650">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
CSS
æ§ã ãªè·é¢ã®é è¿æ³ãè¨å®ããããã«ä½¿ç¨ãããã¨ãã§ãã CSS ã®ã¯ã©ã¹ã§ããã³ã³ããã¼ããã¯ã¹ãç«æ¹ä½èªèº«ãããããã®é¢ã®ããã®ã¯ã©ã¹ãå«ã¿ã¾ãã
/* ãã¾ãã¾ãª perspective ã®å¤ã®ããã®ç¥è¨ç¨ã¯ã©ã¹ */
.perspective-250 {
perspective: 250px;
}
.perspective-350 {
perspective: 350px;
}
.perspective-500 {
perspective: 500px;
}
.perspective-650 {
perspective: 650px;
}
/* ã³ã³ããã¼ã® divãç«æ¹ä½ã® divãé¢ã®ä¸è¬çãªè¨å® */
.container {
width: 200px;
height: 200px;
margin: 75px 0 0 75px;
border: none;
}
.cube {
width: 100%;
height: 100%;
perspective-origin: 150% 150%;
transform-style: preserve-3d;
}
.face {
display: block;
position: absolute;
width: 100px;
height: 100px;
border: none;
line-height: 100px;
font-family: sans-serif;
font-size: 60px;
color: white;
text-align: center;
backface-visibility: visible;
}
/* æ¹åã«åºã¥ãã¦ããããã®é¢ãè¨å® */
.front {
background: rgb(0 0 0 / 30%);
transform: translateZ(50px);
}
.back {
background: lime;
color: black;
transform: rotateY(180deg) translateZ(50px);
}
.right {
background: rgb(196 0 0 / 70%);
transform: rotateY(90deg) translateZ(50px);
}
.left {
background: rgb(0 0 196 / 70%);
transform: rotateY(-90deg) translateZ(50px);
}
.top {
background: rgb(196 196 0 / 70%);
transform: rotateX(90deg) translateZ(50px);
}
.bottom {
background: rgb(196 0 196 / 70%);
transform: rotateX(-90deg) translateZ(50px);
}
/* 表ã®è¦æ ãããããã */
th,
p,
td {
background-color: #eeeeee;
padding: 10px;
font-family: sans-serif;
text-align: left;
}
çµæ
2 ã¤ç®ã®è¨å®è¦ç´ ã¯è¦ã人ã®ä½ç½®ã§ã perspective-origin ããããã£ã使ãã¾ããããã©ã«ãã§ã¯è¦ç¹ã¯è¦ã人ã®ä¸å¤®ã«åããããã¾ããããã¤ã妥å½ã§ããã¨ã¯éãã¾ããã
è¦ç¹ã®å¤æ´
ãã®ä¾ã¯ä¸»è¦ãª perspective-origin å¤ã§ç«æ¹ä½ã表示ãã¾ãã
HTML
<section>
<figure>
<figcaption><code>perspective-origin: top left;</code></figcaption>
<div class="container">
<div class="cube po-tl">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: top;</code></figcaption>
<div class="container">
<div class="cube po-tm">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: top right;</code></figcaption>
<div class="container">
<div class="cube po-tr">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: left;</code></figcaption>
<div class="container">
<div class="cube po-ml">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: 50% 50%;</code></figcaption>
<div class="container">
<div class="cube po-mm">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: right;</code></figcaption>
<div class="container">
<div class="cube po-mr">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: bottom left;</code></figcaption>
<div class="container">
<div class="cube po-bl">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: bottom;</code></figcaption>
<div class="container">
<div class="cube po-bm">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: bottom right;</code></figcaption>
<div class="container">
<div class="cube po-br">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: -200% -200%;</code></figcaption>
<div class="container">
<div class="cube po-200200neg">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: 200% 200%;</code></figcaption>
<div class="container">
<div class="cube po-200200pos">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: 200% -200%;</code></figcaption>
<div class="container">
<div class="cube po-200200">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
</section>
CSS
/* perspective-origin ã®å¤ï¼ä¾ãã¨ã«ç°ãªãï¼ */
.po-tl {
perspective-origin: top left;
}
.po-tm {
perspective-origin: top;
}
.po-tr {
perspective-origin: top right;
}
.po-ml {
perspective-origin: left;
}
.po-mm {
perspective-origin: 50% 50%;
}
.po-mr {
perspective-origin: right;
}
.po-bl {
perspective-origin: bottom left;
}
.po-bm {
perspective-origin: bottom;
}
.po-br {
perspective-origin: bottom right;
}
.po-200200neg {
perspective-origin: -200% -200%;
}
.po-200200pos {
perspective-origin: 200% 200%;
}
.po-200200 {
perspective-origin: 200% -200%;
}
/* ã³ã³ããã¼ã® divãç«æ¹ä½ã® divãé¢ã®ä¸è¬çãªè¨å® */
.container {
width: 100px;
height: 100px;
margin: 24px;
border: none;
}
.cube {
width: 100%;
height: 100%;
perspective: 300px;
transform-style: preserve-3d;
}
.face {
display: block;
position: absolute;
width: 100px;
height: 100px;
border: none;
line-height: 100px;
font-family: sans-serif;
font-size: 60px;
color: white;
text-align: center;
backface-visibility: visible;
}
/* æ¹åã«åºã¥ãã¦ããããã®é¢ãè¨å® */
.front {
background: rgb(0 0 0 / 30%);
transform: translateZ(50px);
}
.back {
background: lime;
color: black;
transform: rotateY(180deg) translateZ(50px);
}
.right {
background: rgb(196 0 0 / 70%);
transform: rotateY(90deg) translateZ(50px);
}
.left {
background: rgb(0 0 196 / 70%);
transform: rotateY(-90deg) translateZ(50px);
}
.top {
background: rgb(196 196 0 / 70%);
transform: rotateX(90deg) translateZ(50px);
}
.bottom {
background: rgb(196 0 196 / 70%);
transform: rotateX(-90deg) translateZ(50px);
}
/* ã¬ã¤ã¢ã¦ãã®è¦æ ãããããã */
section {
background-color: #eeeeee;
padding: 10px;
font-family: sans-serif;
text-align: left;
display: grid;
grid-template-columns: repeat(3, 1fr);
}
çµæ
ããã¾ã§è¡ãã°ã 3D 空éã«è¦ç´ ãé ç½®ãããã¨ãã§ãã¾ãã
é¢é£æ å ±
- CSS ã®
transformããããã£ããã³ CSS<transform-function>ãã¼ã¿å - ç¬ç«ãã座æ¨å¤æããããã£:
translate,rotate,scaleï¼skewããããã£ã¯ããã¾ããï¼ - 端æ«ã®åã㨠3D 座æ¨å¤æã®ä½µç¨
- Intro to CSS 3D transforms (David DeSandro ã«ããããã°è¨äº)
- CSS Transform Playground (CSS 座æ¨å¤ææ©è½ãè¦è¦åãããªã³ã©ã¤ã³ãã¼ã«)