>웹 프론트엔드 >CSS 튜토리얼 >순수한 CSS 3D 패키지 토글을 만드는 방법

순수한 CSS 3D 패키지 토글을 만드는 방법

尊渡假赌尊渡假赌尊渡假赌
尊渡假赌尊渡假赌尊渡假赌원래의
2025-03-15 09:35:09378검색

순수한 CSS 3D 패키지 토글을 만드는 방법

완전히 평평한 골판지 상자를 알고 있습니까? 당신은 그것들을 접고 테이프로 실용적인 상자를 만들 수 있습니다. 재활용이 필요한 경우, 잘라 내고 평평하게하십시오. 최근에 저는이 개념의 3D 애니메이션 버전과 상담을 받았으며 Pure CSS로 구현하는 것이 흥미로운 자습서가 될 것이라고 생각했습니다. 그래서 우리는 시작했습니다!

이런 종류의 애니메이션은 어떻게 생겼습니까? 랩핑 타임 라인을 어떻게 만들 수 있습니까? 크기를 유연하게 조정할 수 있습니까? 순수한 CSS 패키지 토글 효과를 만들어 봅시다.

최종 효과는 다음과 같습니다. 상자를 포장하고 포장하지 않으려면 클릭하십시오.

어디서부터 시작해야합니까?

어디서부터 시작해야합니까? 미리 계획을 세우는 것이 가장 좋습니다. 우리는 포장 템플릿이 필요하다는 것을 알고 있으며 3 차원 공간에서 접어야합니다. CSS 3D에 익숙하지 않다면이 기사를 읽으려면 시작하는 것이 좋습니다.

3D CSS에 익숙하다면 입방 형을 만들고 시작하는 경향이있을 수 있습니다. 그러나 이것은 몇 가지 문제가 발생합니다. 패키지가 2D에서 3D로 어떻게 변환되는지 고려해야합니다.

템플릿을 만들부터 시작하겠습니다. 우리는 미리 표시를 계획하고 포장 애니메이션이 어떻게 작동하는지 생각해야합니다. HTML부터 시작하겠습니다.

<div>
  <div>
    <div>
      <div>
        <div></div>
        <div></div>
        <div>
          <div></div>
          <div></div>
        </div>
        <div>
          <div></div>
          <div></div>
          <div>
            <div></div>
            <div></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Mixin은 좋은 생각입니다

여기에는 많은 내용이 있습니다. 많은 div가 있습니다. 나는 종종 퍼그를 사용하여 태그를 생성하여 컨텐츠를 재사용 가능한 청크로 나눌 수 있습니다. 예를 들어, 각면에는 두 개의 덮개가 있습니다. 측면에 대한 퍼그 믹스를 만들고 속성을 사용하여 수정 자 클래스 이름을 적용하여 이러한 모든 태그를 쉽게 쓸 수 있도록 할 수 있습니다.

 Mixin 플랩 ()
  .package__flap.package__flap-탑
  .package__flap.package__flap-바닥

Mixin 측 (클래스)
  .package__side (class =`package__side- $ {class || 'side'}`)
     플랩 ()
    차단하다

.장면
  .Package__WRAPPER
    .패키지
       측면 ( '메인')
         측면 ( '추가')
         측면 ( 'Flipped')
           측면 ( '탭')

우리는 두 개의 믹스 인을 사용했습니다. 하나는 상자의 각 측면에 덮개를 만듭니다. 다른 하나는 상자의 측면을 만듭니다. 측면 믹스에서 우리는 블록을 사용합니다. Mixin 사용의 어린이 요소가 여기에 제시되어 있으며, 이는 나중에 작업을 단순화하기 위해 일부 측면을 중첩해야하기 때문에 특히 유용합니다.

생성 된 태그 :

<div class="scene">
  <div class="package__wrapper">
    <div class="package">
      <div class="package__side package__side--main">
        <div class="package__flap package__flap--top"></div>
        <div class="package__flap package__flap--bottom"></div>
        <div class="package__side package__side--extra">
          <div class="package__flap package__flap--top"></div>
          <div class="package__flap package__flap--bottom"></div>
        </div>
      </div>
      <div class="package__side package__side--flipped">
        <div class="package__flap package__flap--top"></div>
        <div class="package__flap package__flap--bottom"></div>
        <div class="package__side package__side--tabbed">
          <div class="package__flap package__flap--top"></div>
          <div class="package__flap package__flap--bottom"></div>
        </div>
      </div>
    </div>
  </div>
</div>

중첩 된 쪽

중첩 된 측면은 접이식 랩을 더 쉽게 만듭니다. 양쪽에 두 개의 덮개가있는 것처럼. 측면 아동 요소는 측면 변형을 상속받은 다음 자신의 변형을 적용 할 수 있습니다. 우리가 입방체로 시작하면 이것을 활용하기가 어렵습니다.

중첩 된 요소와 비 네스트 요소 사이를 전환하여 실제 효과를 확인하는이 데모를 확인하십시오.

각 상자에는 100% 100%의 값으로 오른쪽 하단에 변환-오리핀이 설정되어 있습니다. "변환"토글을 선택하면 각 상자가 90도 회전됩니다. 그러나 요소를 중첩하면 변형의 동작이 변경됩니다.

두 버전 모두에 대한 태그를 전환했지만 다른 것은 변경되지 않았습니다.

중첩 :

<div>
  <div>
    <div>
      <div>
        <div></div>
      </div>
    </div>
  </div>
</div>

비 네스트 :

<div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

모든 것을 변환하십시오

HTML에 몇 가지 스타일을 적용한 후 패키지 템플릿이 있습니다.

스타일은 다른 색상을 지정하고 패키지의 측면을 찾습니다. 각 측면은 "메인"측면에 대해 배치됩니다. (둥지가 왜 그렇게 유용한 지 곧 이해할 것입니다.)

어떤 것들은주의를 기울여야합니다. 입방체를 사용하는 것과 마찬가지로, 우리는 크기를 결정하기 위해 --height , --width--depth 변수를 사용합니다. 이렇게하면 나중에 패키지 크기를 더 쉽게 변경할 수 있습니다.

 .패키지 {
  높이 : calc (var (-높이, 20) * 1vmin);
  너비 : calc (var (-너비, 20) * 1vmin);
}

이런 식으로 크기를 정의하는 이유는 무엇입니까? 우리는 Lea Verou의 2016 CSS Confasia Talk (52:44 시작)에서 얻은 아이디어 인 Unitless Default Size 20을 사용했습니다. 사용자 정의 속성을 "값"대신 "데이터"로 사용하면 calc() 사용하는 것을 좋아하는대로 사용할 수 있습니다. 또한 JavaScript는 가치 단위를 신경 쓰지 않아도되며, 다른 곳에서 변경하지 않고 픽셀, 백분율 등으로 변경할 수 있습니다. --root 의 계수로 리팩터링 할 수는 있지만 빠르게 지나치게 복잡해질 수 있습니다.

양쪽의 커버 플레이트는 또한 그들이 속한 측면보다 약간 작아야합니다. 이런 식으로, 우리가 접을 때, z-index 충돌은 없습니다.

 .package__flap {
  너비 : 99.5%;
  높이 : 49.5%;
  배경 : var (-flap-bg, var (-face-4));
  위치 : 절대;
  왼쪽 : 50%;
  변환 : 번역 (-50%, 0);
}
.package__flap-- 탑 {
  변환-오리진 : 50% 100%;
  하단 : 100%;
}
.package__flap-바닥 {
  상단 : 100%;
  변환-오리진 : 50% 0%;
}
.package__side--extra> .package__flap-바닥,
.package__--- abbed> .package__flap-- 바닥 {
  상단 : 99%;
}
.package__side--extra> .package__flap-- 탑,
.package__--- abbed> .package__flap-top {
  하단 : 99%;
}

또한 각 구성 요소에 대한 transform-origin 고려하기 시작했습니다. 상단 덮개는 하단 가장자리에서 회전하고 하단 덮개는 상단 가장자리에서 회전합니다.

의사 요소를 사용하여 오른쪽에 레이블을 만들 수 있습니다. 우리는 clip-path 사용하여 원하는 모양을 얻습니다.

 .package__side-abbed : {이후 {
  콘텐츠: '';
  위치 : 절대;
  왼쪽 : 99.5%;
  높이 : 100%;
  너비 : 10%;
  배경 : var (-3);
  -webkit-clip-path : 다각형 (0%, 100%20%, 100%80%, 0 100%);
  클립 경로 : 다각형 (0%, 100%20%, 100%80%, 0 100%);
  변환-오리진 : 0% 50%;
}

3D 평면에서 템플릿을 사용해 보겠습니다. 먼저 x 축과 y 축에서 .scene 회전시킬 수 있습니다.

 .장면 {
  변환 : rotatex (-24deg) rotatey (-32deg) rotatex (90deg);
}

우리는 템플릿을 접을 준비가되었습니다! 우리의 템플릿은 사용자 --packaged 속성에 따라 붕괴됩니다. 값이 1 인 경우 템플릿이 붕괴 될 수 있습니다. 예를 들어, 일부 측면과 의사 요소 라벨을 붕괴시켜 봅시다.

 .package__side-탭 베드,
.package__side-abbed : {이후 {
  변환 : rotatey (calc (var (-패키지, 0) * -90deg);
}
.package__side--extra {
  변환 : rotatey (calc (var (-포장, 0) * 90deg);
}

또는 "주요"측면이 아닌 모든 측면에 대한 규칙을 쓸 수 있습니다.

 .package__side : NOT (.package__side-main),
.package__side : not (.package__side-main) : {after {
  변환 : rotatey (calc ((var (-패키지, 0) * var (-회전, 90)) * 1deg);
}
.package__SIDE-타축 {-로테이션 : -90;

이것은 모든면을 다룰 것입니다.

중첩 된 측면이 부모 요소의 변형을 물려받을 수 있다고 말했을 때를 기억하십니까? --packaged 값을 변경할 수 있도록 데모를 업데이트하면 해당 값이 변환에 어떤 영향을 미치는지 알 수 있습니다. 1에서 0 사이의 --packaged 값을 슬라이딩하면 내가 의미하는 바를 알 수 있습니다.

이제 템플릿의 접힌 상태를 전환 할 수있는 방법이 있었으므로 일부 움직임을 다루기 시작할 수 있습니다. 우리의 이전 데모는 두 상태 사이에서 전환됩니다. 이를 위해 transition 사용할 수 있습니다. 가장 빠른 방법? .scene 에서 각 어린이 요소의 transform transition 추가하십시오.

 .장면 *,
.Scene *:: 후 {
  전환 : calc (var (-속도, 0.2) * 1s) 변환;
}

다단계 전환!

그러나 우리는 전체 템플릿을 한 번에 접지 않습니다. 실제 생활에서 접는 과정은 순서대로, 한쪽과 덮개를 먼저 접은 다음 다음 단계로 넘어갑니다. 범위 사용자 정의 속성은이 목적에 이상적입니다.

 .장면 *,
.Scene *:: 후 {
  전환 : calc (var (-속도, 0.2) * 1s) calc ((var (-단계, 1) * var (-지연, 0.2)) * 1s);
}

여기서 우리는 각 변환에 대해 transition-delay 사용하여 --step 스펙을 곱해 --delay 곱하십시오. --delay 값은 변하지 않지만 각 요소는 순서대로 "단계"를 정의 할 수 있습니다. 그런 다음 일이 일어나는 순서를 명확하게 진술 할 수 있습니다.

 .package__side--extra {
  -단계 : 1;
}
.package__side-- abbed {
  -단계 : 2;
}
.Package__SIDE-- 플리핑,
.package__side-abbed :: 이후 {
  -단계 : 3;
}

작동 방식을 더 잘 이해하려면 아래 데모를 확인하십시오. 슬라이더 값을 변경하여 일이 발생하는 순서를 업데이트하십시오. 어떤 차를 이기는가를 바꿀 수 있습니까?

같은 기술이 다음에해야 할 일의 열쇠입니다. 보다 현실적인 효과를 위해 모든 것에 약간의 일시 정지를 추가하여 --initial-delay 도입 할 수도 있습니다.

 .Race__Light-- 애니메이션,
.race__light-- 애니메이션 : 후,
.자동차 {
  애니메이션-델리 : calc ((var (-단계, 0) * var (-지연 단계, 0) * 1s);
}

패키지를 되돌아 보면 한 걸음 더 나아가 전환 될 모든 요소에 "단계"를 적용 할 수 있습니다. 이것은 매우 장점이지만 효과가 있습니다. 또는 태그에서 이러한 값을 인화 할 수 있습니다.

 .package__side--extra> .package__flap-- 바닥 {
  -단계 : 4;
}
.package__--- abbed> .package__flap-- 바닥 {
  -단계 : 5;
}
.package__side--main> .package__flap-- 바닥 {
  -단계 : 6;
}
.package__side--flipped> .package__flap-- 바닥 {
  -단계 : 7;
}
.package__side--extra> .package__flap-top {
  -단계 : 8;
}
.package__--- abbed> .package__flap-top {
  -단계 : 9;
}
.package__side--main> .package__flap-top {
  -단계 : 10;
}
.package__side--flipped> .package__flap-top {
  -단계 : 11;
}

그러나 비현실적이라고 느낍니다.

어쩌면 우리는 상자를 뒤집어 야합니다

실생활에서 상자를 접 으면 상자를 먼저 뒤집은 다음 상단 덮개를 접을 수 있습니다. 어떻게해야합니까? 눈이 날카로운 눈을 가진 사람들은 .package__wrapper 요소를 발견했을 것입니다. 우리는 그것을 사용하여 패키지를 밀어 넣을 것입니다. 그런 다음 X 축 주위의 랩을 회전시킵니다. 이것은 패키지를 옆으로 돌리는 느낌을 줄 것입니다.

 .패키지 {
  변환-오리진 : 50% 100%;
  변환 : rotatex (calc (var (-패키지, 0) * -90deg);
}
.package__wrapper {
  변환 : 번역 (0, calc (var (-패키지, 0) * -100%);
}

그에 따라 --step 선언을 조정하면 이와 비슷한 효과를 얻을 수 있습니다.

상자를 확장하십시오

접힌 상태와 전개 된 상태를 전환하면 확장이 잘못 보인다는 것을 알 수 있습니다. 확장 순서는 붕괴 순서를 완전히 뒤집어야합니다. --packaged 및 단계 수에 따라 플립 --step 뒤집을 수 있습니다. 우리의 최신 단계는 15입니다. 전환을 업데이트 할 수 있습니다.

 .장면 *,
.Scene *: {이후
  -단계-----스펙트 : 15;
  -스텝 델리 : calc (var (-step, 1)-((1- var (-PAPAPADED, 0)) * (var (-step)-((var (-스펙트 없음) 1)-var (-step)));
  전환 : calc (var (-속도, 0.2) * 1s) calc ((var (-Step Delay) * var (-지연, 0.2)) * 1s);
}

이것은 실제로 transition-delay 역전시키기위한 많은 calc 입니다. 그러나 그것은 작동합니다! 우리는 --no-of-steps 가치를 최신 상태로 유지하기 위해 스스로에게 상기시켜야합니다!

다른 옵션이 있습니다. "순수한 CSS"경로를 계속하면서 결국 체크 박스 트릭을 사용하여 접힌 상태를 전환합니다. 정의 된 "단계"세트를 가질 수 있으며, 그 중 하나는 확인란을 선택할 때 활성화됩니다. 이것은 확실히 더 장악적인 해결책입니다. 그러나 그것은 우리가 더 세분화 적으로 제어 할 수있게합니다.

 /* 폴드*/
: 확인 ~ .Scene .package__side--extra {
  -단계 : 1;
}
/* 확장하다*/
.package__side--extra {
  -단계 : 15;
}

크기와 중심

데모에서 dat.gui를 포기하기 전에 패키지의 크기를 조정합시다. 우리는 패키지가 접고 뒤집을 때 중앙에 있는지 확인하고 싶습니다. 이 데모에서 랩에는 더 큰 --height 가 있고 .scene 에는 점이 붙은 경계가 있습니다.

패키지를 더 잘 센터하기 위해 혁신을 조정할 수도 있습니다.

 /* z 축에서 번역하여 패키지 높이를 고려하십시오*/
.장면 {
  변환 : calc (var (-Protate-X, -24) * 1deg)) rotatey (calc (var (-rotate-y, -32) * 1deg)) rotatex (90deg) translate3d (0, 0, calc (-Height, 20) * -0.5vmin));
}
/* 뒤집기 전에 깊이를 슬라이딩하여 랩 깊이를 고려하십시오*/
.package__wrapper {
  변환 : 번역 (0, calc ((var (-패키지, 0) * var (-깊이, 20) * -1vmin);
}

이것은 우리에게 장면에서 신뢰할 수있는 중심 효과를 제공합니다. 그러나 그것은 모두 개인적인 취향에 달려 있습니다!

확인란 추가 팁

이제 dat.gui를 없애고 "순수한"CSS로 만드십시오. 이를 위해서는 HTML에 많은 컨트롤을 소개해야합니다. 우리는 확인란을 사용하여 소포를 붕괴시키고 확장합니다. 그런 다음 라디오 버튼을 사용하여 패키지 크기를 선택합니다.

 <label for="one">에스</label>

<label for="two">중</label>

<label for="three">엘</label>

<label for="four">특대</label>

<input type="checkbox" id="package">
<label for="package" class="open">패키지를 엽니 다</label>
<label for="package" class="close">패키지를 닫으십시오</label>

마지막 데모에서는 입력을 숨기고 태그 요소를 사용합니다. 그러나 이제 모두 먼저 눈에 띄게합시다. 속임수는 일부 컨트롤을 선택할 때 형제 조합 (~)을 사용하는 것입니다. 그런 다음 .scene 에서 사용자 정의 속성 값을 설정할 수 있습니다.

 #package : 확인 ~ .Scene {
  -포장 : 1;
}
#on : 확인 ~ .Scene {
  -하이 (Height : 10);
  -width : 20;
  -심 : 20;
}
#two : 확인 ~ .Scene {
  -height : 20;
  -width : 20;
  -심 : 20;
}
#three : 확인 ~ .Scene {
  -height : 20;
  -width : 30;
  -심 : 20;
}
#four : 확인 ~ .Scene {
  -히트 : 30;
  -width : 20;
  -심 : 30;
}

이 기능이있는 데모는 다음과 같습니다!

최종 광택

이제 우리는 물건을 "예쁘게"보이게하고 추가 세부 사항을 추가 할 수 있습니다. 모든 입력을 먼저 숨기겠습니다.

 입력 {
  위치 : 고정;
  상단 : 0;
  왼쪽 : 0;
  너비 : 1px;
  높이 : 1px;
  패딩 : 0;
  마진 : -1px;
  오버플로 : 숨겨진;
  클립 : rect (0, 0, 0, 0);
  흰색 공간 : Nowrap;
  국경비 : 0;
}

크기 옵션을 원형 버튼으로 설정할 수 있습니다.

 .size-label {
  위치 : 고정;
  상단 : var (-상단);
  오른쪽 : 1REM;
  Z- 인덱스 : 3;
  Font-Family : Sans-Serif;
  글꼴 중량 : 대담한;
  색상 : #262626;
  높이 : 44px;
  너비 : 44px;
  디스플레이 : 그리드;
  장소 항목 : 센터;
  배경 : #FCFCFC;
  국경-라디우스 : 50%;
  커서 : 포인터;
  국경 : 4px 고체 #8bb1b1;
  변환 : 번역 (0, calc (var (-y, 0) * 1%)) 스케일 (var (-scale, 1));
  전환 : 0.1S 변환;
}
.Size-Label : 호버 {
  ----- : -5;
}
.Size-Label : Active {
  ---y : 2;
  -스케일 : 0.9;
}

패키지의 접이식 및 확장을 전환하기 위해 어디서나 클릭 할 수 있기를 원합니다. 따라서 .open.close 태그가 전체 화면을 차지합니다. 왜 두 개의 레이블이 있는지 알고 싶습니까? 이것은 약간의 속임수입니다. transition-delay 사용하고 해당 태그를 확대하면 패키지가 변환되면 두 개의 태그를 숨길 수 있습니다. 이것이 스팸 클릭과 싸우는 방법입니다 (사용자가 키보드에서 스페이스 바를 누르는 것을 막지는 않지만).

 .닫다,
.열려 있는 {
  위치 : 고정;
  높이 : 100VH;
  너비 : 100VW;
  z- 인덱스 : 2;
  변환 : scale (var (-scale, 1)) translate3d (0, 0, 50vmin);
  전환 : 변환 0S VAR (-공개 지연, calc (((var (-STEPS, 15) 1) 1) * var (-지연, 0.2) * 1s));
}

#package : 확인 ~ .Close,
.열려 있는 {
  -스케일 : 0;
  -reveal-delay : 0s;
}
#package : 확인 ~ .open {
  -스케일 : 1;
  -reveal-delay : calc (((var (-스펙트, 15) 1) 1) * var (-지연, 0.2) * 1s);
}

이 데모를 확인하여 .open.close 에서 background-color 추가 한 위치를 확인하십시오. 변환 중에는 레이블이 보이지 않습니다.

우리는 이미 완전한 기능을 가지고 있습니다! 그러나 우리 패키지는 현재 약간 부드럽습니다. 추가 세부 정보를 추가하여 포장 테이프 및 포장 레이블과 같은 "상자"처럼 보이도록하겠습니다.

이와 같은 세부 사항은 우리의 상상력에 의해서만 제한됩니다! 우리는 --packaged 커스텀 속성을 사용하여 무엇이든 영향을 줄 수 있습니다. 예를 들어, .package__tapescaleY 변환을 변환합니다.

 .package__tape {
  변환 : translate3d (-50%, var (-오프셋 -y), -2px) scalex (var (-패키지, 0));
}

시퀀스에 영향을 미치는 새로운 기능을 추가 할 때마다 단계를 업데이트해야합니다. --step 값뿐만 아니라 --no-of-steps 값도 마찬가지입니다.

그게 다야!

순수한 CSS 3D 소포 스위칭을 만드는 방법입니다. 웹 사이트에 넣으시겠습니까? 아마도! 그러나 CSS로 이러한 것들을 구현할 수 있다는 것을 보는 것은 재미 있습니다. 사용자 정의 속성은 매우 강력합니다.

CSS를위한 선물을 축하하고 선물하지 ​​않겠습니까!

잘 지내세요! ʕ • ʔ • ᴥ

위 내용은 순수한 CSS 3D 패키지 토글을 만드는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.