Css 3) Study

[웹코딩 가이드] 홈

이제 웹 코딩을 배우기 위한 긴 여정을 시작합니다.. diagram-arrow-down

░ Web 표준은 html로 웹사이트 틀을 만들고, Css로 꾸며주고, Javascript로 동작시키는데.. 이것들은 각각 분리하여 작성되어야 나중에라도, 누구라도,, 알아보기 쉽고 유지 관리에도 도움이 된다!


☞ 이 페이지는 Css 코딩 입문자를 위한 기초 가이드입니다만, html/Css, Javascript 등의 웹 프로그래밍 전반에 걸쳐 본격적으로 학습하고자 한다면; MDN의 문서를 찬찬히 살펴보시기를 권합니다..


Css 변수와 함수

░ 사용자가 정의하는 Css 속성, 곧 는 Css 코드의 값을 토큰화할 수 있는 변수 로서, 캐스케이딩의 영향도 받는다(이는 상황에 맞게 조작하거나 재정의할 수 있음을 의미한다!). 한편, 는 요청에 대한 값 을 반환하기 위해 특별한 데이터 처리나 계산을 수행하는 문으로서, 함수 이름으로 호출하는데, 리턴값 을 계산하기 위해 인수 를 받을 수도 있다

변수와 함수
Css 변수에는 문서 전반에 걸쳐 재사용할 임의의 값(만!)을 담는데, 이를 이용하면 한 곳에 값 을 저장해두고서.. 다른 여러 곳에서 필요할 때마다 참조 하여 가져올 수 있는데, 이 토큰화된 값 은 var(); 함수를 써서 접근할 수 있다 - 곧, Css의 var(); 함수는 Css 변수의 값 을 다른 속성의 값 으로 설정해줄 때 사용된다!
[ Css 변수 작성 및 사용하기 ]
                                        
                                            :root { --default-color: green; } /* 전역 Css 변수 --default-color 선언 및 값 설정 */
                                            .def-color { /* 사용자정의 속성 .def-color 선언 */
                                                /* var(); 함수를 써서 Css 변수 --default-color에 담긴 값을 가져온다 */
                                                background-color: var(--default-color); /* 사용자정의 속성 .def-color의 배경색 설정 */
                                            }

                                            :root { --main-bg-color: pink; } /* body용 Css 변수 --main-bg-color 선언 및 값 설정 */
                                            body {
                                                /* Css 변수값을 body의 background-color에 속성값으로 넣는다 */
                                                background-color: var(--main-bg-color);
                                            }
                                        
                                    

☞ 위 코드의 var(--default-color); 함수는 값으로 반환하려는 Css 변수(--default-color)을 인수로 사용하며, 해석된 값을 요청자에게 반환한다 ← 참고로, Css 변수명 앞에는 --를 붙여야 하며 대소문자를 구분한다!


* cf) 주어진 변수가 아직 정의되지 않았을 때, var(); 함수의 Css 변수값에 다수의 대체값들을 옵션으로 추가해줄 수 있다: var(--main-bg-color, blue, red[, ..]) ← 이는 사용자정의 컴포넌트 및 Shadow DOM으로 작업할 때 유용하게 활용된다!


✓ 스크립트에서는 Css에서 표준 속성을 사용하는 것과 같은 방식으로 Css 변수값을 넣어주면 된다: 대상요소.style.setProperty("--my-var", myValue + 1);

계산 함수: calc();
1. Css의 calc(); 함수는 모든 대상에서, 모든 값과 연산기호 사용이 가능하다. 이 함수는 단일 수학 표현식을 인자로 받는데, 이 인자는 길이 length, 숫자 number, 각도 angle 및 주파수 frequency 등.. 다양한 유형의 혼합일 수 있고, 단위 또한 혼합할 수 있다
                                    
                                        :root { --root-height: 5rem; }
                                        
                                        .my-element {
                                            height: calc(var(--root-height) * 3); /* height: 15rem; */
                                        }
                                    
                                
2. Css의 calc(); 함수를 쓰면 고정된 너비의 여백을 가진 블록레벨 요소를 쉽게 배치할 수 있고, 입력폼 등이 컨테이너 박스 바깥으로 나가지 않도록 너비를 제한해주는 것도 간단하다

width: calc(100% - 5em);

                                    
                                        
                                    
                                
                                    
                                        .inner_calc_box {
                                            width: calc(100% - 5em); /* 박스 너비 설정 */
                                            margin: 0 auto; /* 박스 정중앙 배치 */
                                            color: white; background-color: grey;
                                        } .inner_calc_box p { text-align: center; } /* 텍스트 정중앙 배치 */
                                    
                                

☞ 참고로, calc(); 함수를 써서 텍스트 크기를 조절할 때에는 피연산자 중 하나는 반드시 상대길이 단위를 사용해주어야 한다. 그래야만 페이지 확대/축소 시에도 그 비율이 일정하게 유지될 수 있다: font-size: calc(1.5rem + 3vw);

최소값/최대값: min/max();
min();과 max(); 함수는 전달된 인수들 중 가장 작게/크게 계산되는 값을 반환한다
                                    
                                        body {
                                            margin: 0 auto; /* 가로 정중앙 배치 */
                                            width: min(1024px, calc(70% + 100px)); /* 둘 중 더 작은 값이 선택된다! */
                                        }

                                        p { font-size: max(1.2rem, 1.2vw); } /* 둘 중 더 큰 값이 선택된다! */
                                    
                                
속성값 검색 및 설정하기: attr();
attr(); 함수는 선택한 요소의 속성값을 검색하여 스타일시트에서 사용하는 데 쓰이는데, 가상요소에서도 사용할 수 있다. 이 경우 가상요소의 원래 요소에 있던 속성값이 반환된다

World

                                    
                                        
                                    
                                
                                    
                                        [data-hello]::before { content: attr(data-hello) " "; }
                                    
                                

☞ 예컨대, a::after { content: attr(href); }라면; 여기서, attr(); 함수는 <a> 요소의 href 속성값을 가져와서 ::after 가상요소의 content로 설정한다 ← 곧, <a> 요소의 href 속성값을 변경하려는 경우; 이 content 속성에 자동으로 반영되는 것이다!

데이터 소스 가져오기: url();
URL은 이미지나 글꼴 등 리소스를 가리키는 문자열로서 background-image, cursor, list-style 등 다양한 속성에서 사용되는데, url("데이터 소스"); 함수를 써서 URL의 데이터 소스(따옴표로 묶어야 한다!)를 불러와 이미지, 글꼴 및 컨텐츠 등을 표시할 수 있다
                                    
                                        .container { background-image: url('/images/image.jpg'); }
                                    
                                

Css 플로팅

░ 사실, 최근에는 훨~씬 간편하고 더욱 유용한 플렉스박스와 그리드로 쉽게 페이지 레이아웃을 구성할 수 있기에, 예전처럼 억지로 을 써서, 쌩 머리 짜내면서 페이지 레이아웃을 짜낼 일은 없습니다만.. 그래도, 이미지와 텍스트간 조화로운 배치라는 플로팅의 원초적 기능은 여전히 유용하니 간단히 알고 가기로 합니다

플로팅 및 해제
1. float: left/right; 속성은 박스의 플로팅 방향을 지정하며, clear: both; 속성은 (다음에 나오는 요소에서 사용되어)플로팅을 해제한다
눈내린불국사

웹문서에서 이미지와 텍스트를 나란히 배치하고자 할 때, 이미지에 float: 속성 값으로 right를 주면; 이미지는 우측에서부터 배치되는데.. 이 때 너비값은 이미지 표시에 필요한 만큼만 차지하고 나머지 영역은 비워지면서 이 빈 영역에 텍스트가 자리잡게 된다 ← float 속성을 사용할 때 플로팅 요소 다음에 오는 요소의 레이아웃이 무너질 수 있으므로, 반드시 플로팅을 해제해주어야 한다!


(* 다음에 나오는, <hr> 요소에서 <hr style="clear: both;">로 플로팅을 해제함)

                                    
                                        
                                    
                                
2. 플로팅을 해제하기 위해서는, 부모요소 자체에서 overflow: hidden;이나 overflow: auto; 속성값을 설정해주어도 되지만, 아래 예제에서와 같이 뒤에서 가상요소로 넣어주는 방식이 다른 요소의 스타일 정의와 충돌할 일도 없고, 코드 읽기도 쉬워진다
박스(1) float: left;
박스(2) float: left;
박스(3) float: right;
박스(4) 플로팅을 해제되지 않아 겹쳐서 표시된다!
박스(5) 박스5::before { content:""; display:block; clear:both; }
                                    
                                        
                                    
                                
                                    
                                        /* 여기서(곧, .ex_bxx5 요소 앞에서) 플로팅 해제함 */
                                        .ex_bxx5::before { /* 플로팅 해제용 가상요소 */
                                            content: ""; display: block; clear: both;
                                        }
                                    
                                

☞ 참고로, 예기치 않은 결과를 만들지 않으면서 (부모요소에서)플로팅을 해제하는 가장 확실한 최신 코드는 부모요소에서 display: flow-root; 값을 주는 것이다!

대체요소 객체

░ Css에서 란 자신의 표시 결과가 Css의 범위를 벗어나는, Css 서식모델과는 분리된 외부 객체 인 요소로서 <img>나 <video>, <iframe> 요소가 대표적이다 ← Css는 대체요소 객체의 배치 위치 및 크기를 조정하여 영향을 줄 수는 있지만 그 내용물 자체를 변경할 수는 없다!

대체요소 객체 배치하기
속성은 <img>나 <video> 등 대체요소 객체의 배경 박스 내 컨텐츠 배치 위치(값1 값2)를 %나 키워드로 지정하는데(앞쪽 값은 좌측 면이 기준이 되고, 뒤쪽 값은 상단 면이 기준이 된다), 대체요소 객체가 덮지 않은 부분은 요소의 배경이 드러나게 된다
기본값
                                            
                                                
                                            
                                        
                                            
                                                .object-position_image1 { /* 대체요소 객체의 배경 박스 */
                                                    width: 200px; height: 200px; background-color: silver;
                                                    object-fit: none;
                                                }
                                            
                                        

☞ 여기서는 object-position: 값을 따로 주지 않았으므로, 기본값인 50% 50%가 된다!

단위로는 %, 키워드(top, right, bottom, left) 등을 쓸 수 있다. 예컨대, 기본값인 50% 50% 는 부모박스의 정중앙에 배치되고, 키워드 right top 으로 주면; 우상단 모서리로부터 맞추어지며, left bottom 으로 주면; 좌하단 모서리로부터 맞추어진다. px 단위 또한 사용할 수 있고, 단위를 혼합할 수도 있다
object-position: right top object-position: left bottom object-position: 100% 30px

* cf) 배경 박스보다 더 큰 값을 주어 지구 바깥으로 보내버릴 수도 있다!

object-position: 300px 300px
                                            
                                                
                                            
                                        
객체 맞춤
속성은 대체요소 객체가 부모 박스에 맞춰 채워지도록 다양한 방식으로 그 크기를 조정하는데 사용되는데, none 값은 대체 컨텐츠의 크기를 조절하지 않는다
object-fit: none;
매화
                                    
                                        
                                    
                                
                                    
                                        .object-position_image1 { /* 대체요소 객체의 배경 박스 */
                                            width: 200px; height: 200px; background-color: silver;
                                            object-fit: none;
                                        }
                                    
                                
1. 기본값인 fill 에서는 컨텐츠가 부모 컨테이너를 꽉 채우는데, 필요한 경우 박스에 맞게 늘어나거나 줄어들게 된다
object-fit: fill; (기본값)
매화
2. contain 값을 주면; 대체되는 컨텐츠는 부모 컨테이너에 맞추어 종횡비를 유지하면서 크기가 조정된다. cover 값을 주면; 대체되는 컨텐츠는 부모 컨테이너에 맞추어 종횡비를 유지하면서 크기가 조정되는데, 원본 개체의 나머지 부분은 잘려나갈 수 있다
object-fit: contain;
매화
object-fit: cover;
매화

Css 3) 필터효과

░ Css의 속성은 이미지나 배경, 테두리 등에 다양한 효과 함수를 사용하여 블러나 색상 변형 등의 그래픽 효과를 적용한다

필터링: filter
Css의 filter: 필터함수(값); 속성은 요소에 다양한 필터 효과를 적용하는데, 속성값은 공백으로 구분하여 복수의 필터 효과를 조합할 수도 있다: img { filter: grayscale(0.5) blur(10px); }
블러: filter: blur(값);

값 이 클수록 흐려지는데, 단위는 px을 쓰고, %는 허용되지 않는다!

남산부석 원본 1px 3px
명도: filter: brightness(값);

값 에는 %(나 소수점 단위)를 쓰는데 0 은 완전히 검게 되며, 100% (= 원본)를 넘으면 더 밝아진다 ← 곧, 100% (및 1) 이하는 원본의 밝기를 낮춘다!

0 50% 남산부석 원본 150%
채도: filter: saturate(값);

값 에는 %(나 소수점 단위)를 쓰는데 0% 는 완전한 무채색이 되며, 100% (= 원본)를 넘으면 더 채도가 높아진다 ← 곧, 100% (및 1) 이하는 원본의 채도를 낮춘다!

0 50% 남산부석 원본 150%
색상 대비: filter: contrast(값);

0% 는 완전한 회색조이고, 100% 는 원본과 같으며, 그 이상으로 주면 대비가 더 뚜렷해진다 ← 곧, 100% (및 1) 이하는 원본의 색상 대비를 낮춘다!

0 50% 남산부석 원본 150%
그레이스케일 회색조: filter: grayscale(값);

값 에는 %(나 소수점 단위)를 써서 전환 비율을 지정해주는데 0% (원본 이미지), 100%(완전한 회색조 이미지), 그 사이의 값 은 회색톤 비율을 지정한다

남산부석 원본 50% 100%
세피아톤 갈색조: filter: sepia(값);

값 에는 %(나 소수점 단위)를 써서 전환 비율을 지정해주는데 0% (원본 이미지), 100% (완전한 갈색조 이미지), 그 사이의 값 은 세피아톤 비율을 지정한다

남산부석 원본 50% 100%
색조 회전: filter: hue-rotate(각도값);

주어진 이미지에 hsl 색상환을 적용하는데, 각도값 은 입력 샘플을 조절할 색상환 각도로서 0deg (원본 이미지) ~ 360deg 이다

남산부석 원본 90deg 180deg 270deg
색상 반전: filter: invert(값);

값 에는 %(나 소수점 단위)를 쓸 수 있는데, 0 (원본 이미지) ~ 1 (정반대 색상으로 반전)까지의 값이 들어간다

남산부석 원본 0.2 0.7 1
불투명도: filter: opacity(값);

주어진 이미지의 불투명도를 설정하는데, 보다 확립된 Css의 opacity 속성과 같은 방식으로 작동한다!

0.1 0.5 0.9 남산부석 원본

* cf) Css 필터는 SVG 이미지에서도 사용할 수 있는데, filter: url(); 함수를 사용하여 연결된 SVG 요소 또는 파일에서 SVG 필터를 적용할 수 있다

                                    
                                        
                                    
                                
백드롭 필터: backdrop-filter
backdrop-filter 속성에서도 Css Filter와 동일한 필터 함수들을 사용하는데, filter 속성이 요소 전체에 필터를 적용하는 반면, 이 속성은 백그라운드에만 필터를 적용한다는 점에서 차이가 있다. 곧, backdrop-filter: 필터링함수[ 필터링함수2, ..]; 속성은 요소 뒤 배경에 블러나 색상 시프트 등의 효과를 준다

공화국을 위하여 !

backdrop titles
                                    
                                        
                                    
                                
                                    
                                        .backdrop_element {
                                            display: flex; flex-direction: column; justify-content: center; align-items: center;
                                            position: relative; width: 100%; height: 50vh; max-height: 150px;
                                        }
                                    
                                        .backdrop_filter {
                                            padding: 0.5em 1em;
                                            backdrop-filter: blur(2px); /* 블러 효과 */
                                            background: rgba(256 256 256 / 0.3); /* 요소 배경에 불투명도를 줌 */
                                            z-index: 1;
                                        }
                                    
                                        .backdrop_element img {
                                            position: absolute; top: 0; left: 0; width: 100%; height: 100%; 
                                            object-fit: cover;
                                        }
                                    
                                

☞ 이 효과는 요소의 '뒤'에 적용하기에, 그 효과를 보려면 요소 자체, 또는 요소의 배경에 불투명도를 주어야 한다!

드롭 쉐도우

░ Css 는 Css의 box-shadow 속성과 다소간 유사하며, 속성값 설정 또한 비슷하다. 하지만, box-shadow 속성이 요소 전체 박스 뒤에 사각형 그림자를 그리는 반면, drop-shadow(); 함수는 이미지 자체의 모양에 맞는 그림자를 만든다는 점에서 차이가 있다!

드롭 쉐도우
Css 3의 filter: drop-shadow(offset-x offset-y [blur] [색상]); 함수는 (박스 뒤에 사각형 그림자를 그리는 것이 아니라)이미지의 배경에, 이미지의 모양에 맞게 흐릿한 블러 효과를 나타내준다 ← 곧, 이미지의 알파 마스크에 흐릿하게 블러 효과를 주어 이미지의 배경으로 합성하는 것이다!
  • offset-x offset-y // 그림자의 가로 세로 오프셋 거리 ← 양수는 우측, 아래쪽 방향이 되고, 음수는 그 반대이다!
  • blur // 이 값(음수는 허용되지 않는다)이 클수록 더 크고 흐린 그림자가 된다 ← 생략하면; 0 으로 설정되어 그림자의 가장자리가 날카로와진다!
  • 색상 // 그림자 색상 ← 미지정 시는 대개 부모요소에 지정된 색상을 상속받는다!

                                    
                                        
                                    
                                
                                    
                                        .d-shadow-ex1 { filter: drop-shadow(-4px -4px grey); }
                                        .d-shadow-ex2 { filter: drop-shadow(4px 4px 2px grey); }
                                    
                                

☞ 위 코드의 <i class="bi-alarm"></i> 부분은 부트스트랩의 아이콘을 불러온 것입니다 ← 부트스트랩 아이콘에 관해서는, 나중에 부트스트랩 강좌를 참조하십시오..

블렌딩 모드

░ Css의 를 이용하면 다수의 레이어에서 색상을 혼합하여 흥미로운 시각적 효과를 낼 수 있고, 이 혼합모드를 활용하여 Css 필터효과나 가상요소 등을 이미지에 적용할 수도 있다!

블렌딩 모드
mix-blend-mode: 키워드; 속성은 대상이 되는 요소의 컨텐츠가 자신의 배경 및 부모요소와 어떻게 혼합되어야할 지를 키워드 값을 통해 지정하는데, 일반 이미지 및 SVG 이미지, 텍스트 모두에서 사용할 수 있다
매화 남산부석
* 이하, 간단한 설명입니다:

* 이하, 간단한 설명입니다:


* cf) 아래는, Multiply가 자신의 배경과 어떻게 혼합되는지 확인해보기 위한 간단한 예제입니다 - 수치로 계산할 수 있는건 아니니 그냥 느낌으로만 이해하십시오 ㅡㅡ;

매화 남산부석
                                            
                                                .blendmode_demo_div {
                                                    max-width: 200px; overflow: hidden;
                                                    background: rgb(218 231 170 / 0.5); /* 이미지가 들어있는 부모요소의 배경색 */
                                                }
                                                
                                                .img_mahwa_multiply, .img_busuk_multiply { mix-blend-mode: normal; }
                                            
                                        

☞ 참고로, mix-blend-mode는 요소에 (요소 자신의 배경 및 부모요소 전체와 혼합되는)블렌딩 모드를 적용하는 반면, background-blend-mode는 요소 내부의 배경만을 대상으로 혼합한다!

블렌딩모드의 쌓임맥락
isolation 속성은 z-index의 쌓임 맥락과 유사하게 블렌딩 모드의 새로운 쌓임맥락을 만드는데, mix-blend-mode와 함께 사용할 때 특히 효율적이다 ← background-blend-mode에서는 (백그라운드 속성은 이미 격리되어 있으므로, 당연히)의미가 없다!
* 시작시, 부모요소의 배경색과 혼합되어 있음! mix-blend-mode: multiply;
                                                    
                                                        
                                                    
                                                
                                                    
                                                        .isolate_demo { /* 부모요소 */
                                                            background: rgb(198, 200, 181);
                                                            max-width: 800px; border: 5px solid gray; border-radius: 0.5rem; overflow: hidden;
                                                        } .isolate_demo img { mix-blend-mode: multiply; } /* 믹스 블렌딩모드 설정 */
                                                    
                                                

☞ 부모요소 내부의 이미지들에 mix-blend-mode: multiply;로 주었으므로 처음에는 부모요소의 색상과 혼합되어 나타난다!

                                                    
                                                        const iso_toggle= document.querySelector('#toggle-element3')
                                                        const iso_isolate= document.querySelector('.isolate_img')

                                                        iso_toggle.addEventListener('change', ({target}) => {
                                                            // 박스를 체크하면; isolation 속성값에 isolate를 넣는다
                                                            iso_isolate.style.isolation= target.checked ? 'isolate' : 'auto';
                                                        });
                                                    
                                                

☞ 버튼에 체크하면; isolation 속성에 기본값인 auto 대신 isolate 값이 들어간다: isolation: isolate; ← 이제 내부 이미지들은 부모요소로부터 벗어나 자신만의 쌓임 맥락을 만들게 된다!

                                                    
                                                        
                                                    
                                                
                                                    
                                                        .isolate_ex {
                                                            position: relative;
                                                            isolation: isolate; /* 이 쌓임맥락 격리가 없으면 배경색까지 함께 혼합된다! */
                                                        }
                                                        
                                                        .circle_isolate {
                                                            position: absolute; width: 80px; height: 80px;
                                                            border-radius: 50%;
                                                            mix-blend-mode: screen;
                                                        }
                                                        .circle_isolate-1 { background: red; }
                                                        .circle_isolate-2 { background: green; left: 40px; }
                                                        .circle_isolate-3 { background: blue; left: 20px; top: 40px; }
                                                    
                                                

Css 트랜스폼

░ Css의 속성은 GPU 가속 속성이므로 일반적으로 전환되며, 더 부드러운 애니메이션을 만든다. 이 속성을 사용하면 임의로 요소의 크기를 조정하거나, 회전 및 기울이기, 이동, 또는 왜곡시킬 수 있다!

트랜스폼: transform
Css 트랜스폼 속성은 Css 시각적 서식모델의 좌표 공간을 변경하는데, 이는 새로운 쌓임맥락을 생성한다!
Transform 1
Transform 2
Transform 3
                                    
                                        
                                    
                                
                                    
                                        .transformed_el1 { transform: translate(30px, 20px) rotate(15deg); }
                                        .transformed_el2 { transform: rotate(90deg); } 
                                        .transformed_el3 { transform: skewx(10deg) translatex(150px); transform-origin: bottom left; } 
                                    
                                

☞ transform-origin 속성으로 원점의 위치를 지정해줄 수 있는데, 생략시의 기본값은 해당 요소의 중심이다!

rotate(각도deg);는 중심축을 기준으로 각도deg만큼 요소를 회전시키는데, 각각의 축을 기준으로 하는 rotateX/Y/Z(각도deg); 함수를 쓸 수도 있다. 좀 더 복잡하게는; rotate3d(x, y, z, 각도deg);(x, y, z 좌표와 각도) 함수를 쓸 수도 있다: * rotate() 예제

🐶
                                                    
                                                        .transform-rotate {
                                                            animation: rotate 5s ease-in-out both;
                                                        } @keyframes rotate {
                                                            0%   { transform: rotate(0); }
                                                            100% { transform: rotate(180deg); }
                                                        }        
                                                    
                                                

scale(값[, 값2]); 함수는 값[, 값2]만큼 요소를 확대/축소하는데(인수 하나는 x, y 양 방면이며, 인수 둘은 각각 x, y 방면이다), scaleX/Y/Z(); 및 scale3d(x, y, z); 함수도 있다: * scaleX/Y() 예제

🐶
                                                    
                                                        .transform-scale {
                                                            animation: scale 5s both;
                                                        } @keyframes scale {
                                                                50% { transform: scale(0.5); }
                                                            100% { transform: scale(1); }
                                                        }
                                                    
                                                

translate(값[, 값2]); 함수는 값[, 값2]만큼(단위는 px, % 등) 요소를 이동시키는데(인수 하나는 x 방면, 인수 둘은 각각 x, y 방면이다), translateX/Y/Z(); 및 translate3d(x, y, z); 함수도 있다

🐱
🐶
                                                    
                                                        .transform-translateX {
                                                            animation: slide-in 5s both;
                                                        } @keyframes slide-in {
                                                            0% { transform: translateX(-1000px); }
                                                            100% { transform: translateX(0); }
                                                        }
                                                    
                                                        .transform-translateY {
                                                            animation: slide-down 10s both;
                                                        } @keyframes slide-down {
                                                            0% { transform: translateY(-1000px); }
                                                            100% { transform: translateY(0); }
                                                        }
                                                    
                                                

skew(값[, 값2]); 함수는 값[, 값2]만큼 요소를 비트는데(인수 하나는 x 방면, 인수 둘은 각각 x, y 방면이다), skewX/Y(값); 함수도 있다

🐶
                                                    
                                                        .transform-skew {
                                                            animation: skew 10s both;
                                                        } @keyframes skew {
                                                            0% { transform: skew(0deg, 0deg); }
                                                            50% { transform: skew(45deg, 45deg); }
                                                        }
                                                    
                                                

애니메이션에 Css opacity 속성도 또한 유용하게 사용할 수 있다. 아래는, opacity 속성을 써서 요소의 화면 표시상태를 전환한다

🐶
                                                    
                                                        .animation-opacity {
                                                            animation: opacity 10s both;
                                                        } @keyframes opacity {
                                                              0% { opacity: 1; }
                                                             50% { opacity: 0; }
                                                            100% { opacity: 1; }
                                                        }
                                                    
                                                
➥ 트랜스폼의 모션 감소

트랜스폼 변형에 관해 좀 더 알고 싶다면; 문서를 참조해서 살펴보시길 권합니다..


✓ 참고로, 트랜스폼의 지나친 크기 변경/확대/축소 애니메이션은 어떤 사용자에게는 두통을 야기시킬 수도 있다. 이 경우, 미디어 쿼리와 함께 미디어 기능을 이용하면 사용자가 시스템 설정에서 애니메이션을 줄였는지 알아내고, 애니메이션을 비활성화해줄 수 있다!

Css 트랜지션

░ 웹사이트와 상호작용할 때 많은 요소에 중간 상태가 있는 것을 볼 수 있다 - 예컨대, 포커스를 받거나 마우스를 올리면 버튼의 색상이 변경될 수 있는데, Css는 이러한 상태의 스타일을 즉시 전환한다. 이때, Css의 속성을 사용하면 요소의 초기 상태에서 타겟팅 상태로 부드럽게 전환하도록 중간 단계의 상태를 줄 수 있다. 곧, 두 상태간의 전환 시 시각적 안내나 힌트 등을 제공하여 사용자 환경을 개선할 수 있는 것이다!

트랜지션: transition
Css 트랜지션을 설정하려면; 먼저 transition-property 속성으로 전환하고자 하는 스타일을 지정해주어야 하는데, 쉼표로 구분된 목록 형식의 하나 이상의 Css 속성을 지정해주어야 한다. 그외에도, 아래와 같이 여러 속성값들을 추가적으로 설정해줄 수 있다
  • transition-duration: 전환시간; // 전환이 끝날 때까지의 시간 ← 단위는 s(초) 및 ms(밀리초)
  • transition-timing-function: ease/ease-in/ease-out/ease-in-out/steps(n)/cubic-bezier(..); // 전환 중, 전환 속도 변경 방식 ← 기본적으로 Css는 속도 변환 없이 일정한 속도로 전환한다(기본값: linear)
  • transition-delay: 대기시간; // 전환이 시작되기 전 대기시간 ← 이 속성은 그룹의 후속 요소들마다 서로 다르게 설정하여 전환을 분산하는 데 유용하다!

✓ transition: 값1 값2[ ..]; 방식으로 일괄 지정해줄 수도 있지만, 이 경우에는 각 항목의 순서에 따르는 움직임들을 고려해야 할 필요성이 생겨나기에.. 더 피곤해집니다 ㅡㅡ;

1. Css 트랜지션을 활성화하려면 Css에 상태 변경 및 해당 상태 변경을 트리거하는 이벤트가 포함되어야 하는데, 보통은 :hover, :focus, :target 등의 의사클래스가 사용되며, 자바스크립트를 쓸 수도 있다:
                                    
                                        
                                    
                                
                                    
                                        .square_hover:hover { transform: scale(1.2); }
                                    
                                
2. 트랜지션에서 Css transform 속성은 GPU 가속 색상이므로 일반적으로 전환되며, 색상(color, background-color, border-color)도 상호작용 시의 상태를 나타내는 좋은 지표가 될 수 있다. Css filter 속성이나 박스 그림자 또한 마우스가 올라간 때의 상태를 나타낼 때 많이 사용된다

🐶 🐱

                                    
                                        
                                    
                                
                                    
                                        .filter_emoji {
                                            filter: grayscale(100%); transition: filter 450ms ease;
                                        } .filter_emoji:is(:hover, :focus) {
                                            filter: grayscale(0%) drop-shadow(0 8px 8px rgb(0 0 0 / 0.5));
                                        }
                                    
                                

* cf) Css 전환을 사용할 때 특정 Css 속성에 트랜지션을 추가하면 성능 문제가 발생할 수도 있다 - 예컨대, width나 heitht 값이 변경되면; 페이지의 나머지 부분에서 컨텐츠가 푸시되고, Css는 이에 관련된 주변 모든 요소의 위치를 다시 계산해야 하는 것이다!

                                                    
                                                        
                                                    
                                                
                                                    
                                                        .bubbling_wrapper { display: flex; flex-wrap: wrap; padding: 0; }
                                                        .bubbling {
                                                            width: 75px; height: 75px; margin: 4px; padding: 16px;
                                                            background-color: aquamarine; border-radius: 100%;
                                                            font-size: 2em; text-align: center;
                                                            transition: all 5s ease-in 200ms;
                                                        } .bubbling:is(:hover, :focus) {
                                                            background-color: paleturquoise;
                                                            transform: scale(1.6);
                                                            opacity: 0.6;
                                                            transition: transform 150ms cubic-bezier(0.5, 1.75, 0.75, 1.25);
                                                        }
                                                    
                                                

* 아래 이미지에 마우스를 올리세요..

불국사

눈내린 불국사 - 소산 박대성

                                                    
                                                        
                                                    
                                                
                                                    
                                                        .face_back {
                                                            position: relative; width: 250px; height: 145px;
                                                            transition: transform 3s;
                                                            transform-style: preserve-3d;
                                                        } .face_back:focus, .face_back:hover {
                                                            transform: rotateY(180deg);
                                                        }
                                                        
                                                        .face_ex {
                                                            position: absolute; height: 100%; width: 100%;
                                                            backface-visibility: hidden;
                                                        } .back_ex {
                                                            display: grid; place-items: center;
                                                            background: rgb(113, 157, 238);
                                                            transform: rotateY(180deg);
                                                        }
                                                    
                                                

메뉴 제목

  • html 코드
  • css 스타일
  • js 스크립트
                                                    
                                                        
                                                    
                                                
                                                    
                                                        .sliding-menu { position: relative; overflow: hidden; }

                                                        .sliding-actions { /* 메뉴 숨김으로 시작한다 */
                                                            position: absolute; top: 0; right: 0; width: 300px; height: auto;
                                                            padding: 2em; border: grey solid 5px; background: rgb(182 189 166 / 0.5);
                                                            float: right;
                                                            transform: translateX(calc(300px + 4em +  10px)); /* 메뉴 너비 + 양쪽 패딩 + 양쪽 테두리 */
                                                            transition: all 500ms linear; /* 트랜지션(전환) 효과 */
                                                        } .sliding-actions.display { /* 메뉴 펼치기 */
                                                            transform: translateX(0);
                                                            transition: all 1000ms linear; /* 같은 값으로 설정한다면; 생략해도 된다! */
                                                            z-index: 1; /* 메뉴가 본문 내용의 위로 올라오도록 한다 */
                                                        }
                                                    
                                                
                                                    
                                                        const sidebar= document.getElementById('sliding-sidebar');

                                                        document.getElementById('sliding-show').addEventListener('click', () => {
                                                            sidebar.classList.toggle('display');
                                                        });
                                                    
                                                

@keyframes

░ 일반적으로 애니메이션의 키프레임은 타임라인의 타임 스텝에 애니메이션의 상태를 할당하는 데 사용하는 메커니즘으로서, 시작과 종료 및 중간 지점들로 이루어진다. Css 에서의 @keyframes 또한 애니메이션의 키프레임과 동일한 개념을 기반으로 한다

키프레임: @keyframes
Css에서 @keyframes를 사용하려면 다양한 애니메이션 속성을 개별적으로 정의하거나, animation 속성으로 일괄 설정해줄 수도 있다. 아래 코드는 여러 상태가 있는 키프레임을 정의한 것인데, 여기서 키프레임 이름(my-animation)은 함수 이름처럼 작동하여 Css 코드의 다른 위치에서 이를 참조할 수 있게 된다
[ @keyframes 정의 ]
                                        
                                            @keyframes my-animation { /* 키프레임 이름 */
                                                  0% { transform: translateY(20px); /* 키프레임의 시작 지점 ← 키워드 from과 같다 */ }
                                                 50% { transform: translateY(10px); }
                                                100% { transform: translateY(0px); /* 키프레임의 끝 지점 ← 키워드 to와 같다 */ }
                                            }
                                        
                                    
  • animation-duration: 지속시간; @keyframes 타임라인의 길이(딘위: s나 ms)
  • animation-delay: 대기시간; 애니메이션이 시작되기 전 대기시간
  • animation-direction: reverse/alternate/alternate-reverse; 타임라인의 진행 방향
  • animation-iteration-count: 횟수; 타임라인의 반복횟수 (기본값: 1) ← 애니메이션 루프를 만들려면; infinite 값을 주면 된다!
                                                    
                                                        
                                                    
                                                
                                                    
                                                        .demo_step {
                                                            animation: move; /* 키프레임 이름 */
                                                            animation-delay: 3s; /* 시작 전 대기시간 */
                                                            animation-duration: 10s; /* 애니메이션 길이 */
                                                            animation-iteration-count: infinite; /* 반복횟수 ← 기본값 1 */
                                                        } @keyframes move { /* 키프레임 */
                                                              0% { transform: translateX(0px); }
                                                            100% { transform: translateX(400px); }
                                                        }
                                                    
                                                        .demo_step {
                                                            width: 50px; height: 50px; background: rgb(138, 156, 123);
                                                        } .demo_step:hover { animation-play-state: paused; cursor: wait; } /* 일시 정지 */
                                                    
                                                

☞ animation-play-state: paused;는 애니메이션을 일시 중지시킨다

                                                    
                                                        const toggle_el= document.querySelector('#toggle-ele');
                                                        const demo_steps= document.querySelector('.demo_step');
                                                    
                                                        toggle_el.addEventListener('change', ({ target }) => {
                                                            demo_steps.style.animationTimingFunction= target.checked ? 'steps(5)' : 'linear';
                                                        });
                                                    
                                                

☞ 선을 따라 이동하는 대신 간격을 두고 이동하여 애니메이션을 더 세부적으로 제어하고 싶다면; animation-Timing-Function 속성값에 steps(단계수); 함수를 써서 타임라인을 동일한 길이의 정의된 간격으로 나누어줄 수 있다!


░ 각 타이밍 함수 키워드(예: ease)는 사전 정의된 Bézier 곡선을 사용하여 계산되는데, Css에서는 cubic-bezier(x1, y1, x2, y2); 함수를 사용하여 베지어 곡선을 직접 정의해줄 수도 있다 ← 이 베지어 곡선을 이해하는 것은 매우 어려우므로 같은 사이트가 도움이 될 수 있습니다. 나아가, 다양한 Css 애니메이션들을 만들어주는 사이트도 이용해보십시오..

베이직 쉐이프

░ Css 데이터 유형은 clip-path 및 shape-outside 속성에서 사용되는 모양으로서, Css 박스모델 개념을 상속하지만, 이는 Shape 요소 자신의 외부에 적용되는 것이고, 이를 통해 주변 요소의 위치를 재설정해줄 수 있게된다!

쉐이프 도형 작성하기
쉐이프 도형을 만들 때 기본 참조상자는 basic-shape 데이터 타입에 사용하는 속성들에 의해 정의되는데, 쉐이프의 좌표계는 기본적으로 참조박스의 좌상단 모서리가 원점이 되며, x축은 오른쪽으로, y축은 아래쪽으로 진행된다
clip-path 속성: 요소 자신의 클리핑 범위를 지정하는데, 클리핑 범위 안의 부분은 보여지고, 바깥은 숨겨진다
192x192 크기의 정사각 이미지 192x192 크기의 정사각 이미지
                                    
                                        
                                    
                                
                                    
                                        .shape_box { /* 기준이 되는 참조 박스 */
                                            max-width: 600px; margin: 0 auto;
                                        }
                                        
                                        .shape_box img.image1 { clip-path: inset(0 round 10%); } /* 둥근 모서리 */
                                        .shape_box img.image2 { clip-path: circle(); } /* 원 */
                                    
                                

☞ 쉐이프 함수의 인수값 중 %로 표시되는 모든 길이는 참조상자의 크기에 의해(그에 대비한 비율로) 결정된다!

shape-outside 속성: 인접한 인라인 컨텐츠가 줄바꿈되어야 하는 모양(사각형이 아닐 수 있음)을 정의한다 - 곧, 인라인 컨텐츠는 기본적으로 요소 주위에서 사각형 형태로 배치되지만, shape-outside 속성을 써서 주변의 인라인 컨텐츠가 (박스모델의 사각형이 아니라)요소의 곡선을 따라 둘러싸도록 할 수 있는 것이다

shape-outside: circle() padding/border/margin-box; 쉐이프 요소와 주변 요소 사이의 간격을 설정한다

                                                    
                                                        
                                                    
                                                
                                                    
                                                        .main_shapefnc {
                                                            width: 550px; margin: 0 auto;
                                                            display: flow-root; /* 내부 플로팅 요소들의 플로팅 해제용 */
                                                        } .left_shapefnc, .right_shapefnc {
                                                            height: 13ex; width: 40%; background-color: lightgray;
                                                        } .left_shapefnc {
                                                            clip-path: polygon(0 0, 100% 100%, 0 100%);
                                                            shape-outside: polygon(0 0, 100% 100%, 0 100%);
                                                            float: left;
                                                        } .right_shapefnc {
                                                            clip-path: polygon(100% 0, 100% 100%, 0 100%);
                                                            shape-outside: polygon(100% 0, 100% 100%, 0 100%);
                                                            float: right;
                                                        }
                                                    
                                                

☞ Shape 요소에서 shape-outside: circle() padding-box; 값을 주면; 주변 요소는 이 Shape 원의 마진(기본값) 및 테두리 영역을 넘어 곧바로 패딩 영역에 달라붙게 된다!

쉐이프 레이아웃
1. 아래는 Css 플로팅에 의해 이미지와 텍스트가 좌우로 배치될 때의 기본 형태이다

문단 옆에 원을 그려주고, Css 플로팅으로 좌우로 배치해봤는데.. 이 원은 Css 박스모델의 사각형 모양 그대로 문단 옆 사각 박스 영역만큼을 차지하면서 자리잡고 있군요 ㅡㅡ; 이 문단이 원을 따라서 둥글게 자리잡도록 할 수 있는 방법은 없을까요?

                                    
                                        
                                    
                                
                                    
                                        .s_circle { 
                                            width: 100px; height: 100px; border-radius: 50%; background-color: #77b597;
                                            float: left;
                                        }
                                    
                                
2. Css 쉐이프 도형(및 쉐이프 함수)를 사용하면 박스모델의 단순한 사각형을 넘어, 주변 요소와의 관계에서 보다 추상적이고 기하학적인 레이아웃을 만들 수 있다

circle(); 함수는 원을 그려주는데, 그 원에다 shape-outside: circle(); 속성을 추가하여 주변 인라인 요소가 원형에 맞춰 줄바꿈되도록 했습니다, 화려한 변신이군요 ^^ shape-outside 속성은 인라인 컨텐츠가 박스모델이 아닌 주변 요소의 곡선을 따라 둘러싸도록 합니다. 추가적으로, 위 원에다 마진을 약간 주니 보기에 더 좋군요: margin-right: 1em; 값으로 주변 요소들과의 사이에 약간의 간격을 줬습니다..

                                    
                                        
                                    
                                
                                    
                                        .s_circle2 {
                                            shape-outside: circle(); /* 바깥쪽 경계 모양 설정 */
                                            margin-right: 1em; /* 원 주변 요소와의 마진 간격 */
                                        }
                                    
                                

☞ 원을 그려주는 circle([r at x y]); 함수는 (요소 박스의 좌상단을 기준으로 하는)x, y 중점 좌표(생략 시, 요소 박스 정중앙인 50% 50% 이다)에서 시작되는 (요소 크기에 대비한)반지름 r 의 크기(생략 시, 원 지름은 요소 박스 전체 크기가 된다)에 의해 규정된다 ← 단위로는 px, %, top/bottom/left/right/center, closest-side/farthest-side 등을 사용할 수 있는데, 원의 크기를 (줄이거나 늘여서)값으로 넣어줄 때는 circle(50px at 30% 70%);(= 원 중심은 박스의 30% 70% 지점이 되고, 원의 지름은 100px 크기가 된다) 식으로 r 값과 x y 값을 함께 넣어주어야 한다!

쉐이프 함수

░ Css의 clip-path 및 shape-outside 속성들은 도형을 사용하여 상자를 시각적으로 자르거나 컨텐츠가 흐를 도형을 작성하는데, inset();, circle();, ellipse();, polygon(); 등의 간단한 도형 작성 관련 함수들이나, 좀 더 복잡한 path(); 함수를 써서 정의해줄 수 있다

쉐이프 함수: rect();, circle();
rect(); 함수는 컨테이너 박스의 좌상단 원점으로부터 지정된 거리에 사각형을 정의하며, circle(); 함수는 반지름과 위치를 이용하여 원 도형을 정의한다: circle(50px at 30% 70%);
남산부석

rect(); 함수는 컨테이너 박스의 좌상단 원점으로부터 지정된 거리에 사각형을 정의하며, circle(); 함수는 반지름과 위치를 이용하여 원 도형을 정의한다j: circle(50px at 30% 70%);

남산부석

rect(); 함수는 컨테이너 박스의 좌상단 원점으로부터 지정된 거리에 사각형을 정의하며, circle(); 함수는 반지름과 위치를 이용하여 원 도형을 정의한다: circle(50px at 30% 70%);

한편, ellipse(); 함수는 (타원이므로)두 개의 반지름을 지정해야 한다는 점을 제외하고는 circle(); 함수와 매우 유사한 방식으로 작동한다: ellipse(100px 200px at 10% 20%);

                                    
                                        
                                    
                                
                                    
                                        .shape_rect, .shape_circle, .shape_ellipse {
                                            max-width: 800px; margin: 0 auto; display: flow-root; /* 플로팅 해제용 */
                                        }
                                        
                                        .shape_rect img {
                                            float: left; margin-right: 1.5em;
                                            clip-path: rect(); /* 쉐이프 사각형 */
                                            shape-outside: rect(); /* 사각형 옆 문단 */
                                        }

                                        .shape_circle img {
                                            float: left; margin-right: 1.5em; margin-top: 1em;
                                            clip-path: circle(); /* 쉐이프 원 */
                                            shape-outside: circle(); /* 원 옆 문단 */
                                        }
                                    
                                

░ polygon(); 함수는 SVG 채우기 규칙과 위치값을 써서 다각형을 정의하는데, 이 함수는 직접 작성하기에는 좀 어려우니, 필요하다면; 같은 폴리곤 자동 변환 사이트를 이용해보십시오..

쉐이프 함수: inset();
inset(값 값 값 값 [round 값]); 함수는 박스의 각 측면에서 지정된 인셋 거리에 사각형을 정의한다
앞쪽 인수는 상자 안쪽으로 상/우/하/좌로부터의 인셋 거리이며(인수의 개수는 3, 2, 1의 단축값으로 줄 수도 있다), 추가 옵션인 round 값(값은 1, 2, 3, 4개까지 줄 수 있다) 인수는 박스 코너(좌상, 우상, 우하, 좌하 순서임) 둥근 모서리를 설정한다 ← 단위는 px 및 % 모두 가능하다
                                    
                                        
                                    
                                
                                    
                                        .shape_inset {
                                            width: 150px; height: 80px; margin: 10px 10px 10px 40px; background-color: coral; float: left;
                                            clip-path: inset(30px 60px 15px 0 round 25px);
                                            shape-outside: inset(40px 40px 10px 0 round 15px);
                                        }
                                    
                                
offset-path: xywh(x y w h); 속성은 참조 상자의 x, y 방면 거리와 해당 지점에서의 w, h 값(너비 높이)을 설정하여 사각 박스 영역을 설정해준다. 추가적으로, clip-path 속성으로 클리핑 경로를 정의해줄 수 있다
☞ 음~ 좀 어렵군요.. 너무 어려우니 대충, 대충,, 코드 만지작, 만지작 하면서 확인해 보십시오.. 덕분에, 이 세상 누구도 못 본 그 난해한 양자 도약을 눈으로 직접 구경하게 되는군요, 봤나요? 못 봤나요??
→
                                                
                                                    
                                                
                                            
                                                
                                                    .xywh_path {
                                                        width: 25px; height: 25px;
                                                        background-color: rgb(140, 196, 106);
                                                        animation: move 20s linear infinite;
                                                    } @keyframes move {
                                                          0% { offset-distance: 25%; }
                                                        100% { offset-distance: 100%; }
                                                    }
                                                    
                                                    .xywh-path_sub {
                                                        offset-path: xywh(0px 0px 100% 100% round 10%);
                                                        clip-path: circle();
                                                    }
                                                
                                            

스크롤 Overflow

░ Css 동작 모듈은 스크롤 위치가 '스크롤 경계'에 도달할 때(이 경계를 넘는 오버스크롤 시) 스크롤 컨테이너의 동작을 제어한다

스크롤 오버플로
요소의 내용이 컨테이너보다 크고, 스크롤이 가능하거나 기본적으로 스크롤되는 상황에서(예컨대, 블로그 게시판에서 [게시글] 입력 시) 요소의 스크롤 가능 영역을 지나 계속해서 스크롤하면 부모요소에서 스크롤이 시작되는 경우가 있다. 반대로, 웹사이트의 이용약관에서 보듯이, [확인란]을 활성화하기 위해 약관 설명 바깥까지 도달하더라도 페이지가 스크롤되거나 바운스되지 않도록 할 수도 있다
                                    
                                        #chat-board .messags {
                                            height: 300px;
                                            overflow: auto; overscroll-behavior: contain;
                                        }
                                    
                                

☞ 이 코드는 채팅창의 스크롤 컨텍스트와 기본 페이지를 논리적으로 분리하고, 그리하여 페이지 하단에 고정된 채팅창의 맨 밑 게시물까지 스크롤해 내려가도 기본 페이지로 스크롤이 전파되는 것을 막아준다!

1. 기본적으로, 컨테이너(또는, 페이지 자체)에서 발생한 스크롤은 끝 경계 지점까지 도달하여 오버스크롤될 때 상위요소로 전파될 수 있는데(기본값인 auto), overscroll-behavior 속성에 contain 값을 주어 상위요소로의 스크롤 체이닝 전파를 막고, 나아가 모바일앱에서의 스크롤하여 새로고침 작업도 중단시킬 수 있다. 한편, none 값은 contain과 동일하지만 Android의 오버스크롤 글로우 효과 및 iOS의 리버밴딩 효과 까지 방지한다:

* cf) 참고로, 스크롤하여 새로고침 작업을 사용 중지하는 것은 전체 뷰포트 정의 요소(대개, <html> 또는 <body>)에서 스크롤 체이닝을 방지하기만 하면 된다(body { overscroll-behavior-y: contain; }). 한편, '스크롤 경계'에 도달할 때의 반동 효과(= 오버스크롤 글로우 효과 및 리버밴딩 효과) 까지 사용 중지하고자 한다면; body { overscroll-behavior-y: none; } 코드를 사용하면 된다 ← 이 경우, 좌/우측 스와이프 탐색은 계속 유지된다!

2. scroll-behavior 속성을 사용하면 요소에 대한 브라우저 제어 스크롤을 선택할 수 있고, scrollTo(); 또는 링크와 같은 페이지 내부 탐색 방법을 지정할 수 있는데, 이 모드는 prefers-reduced-motion과 함께 사용하여 사용자 환경설정에 따라 스크롤 동작을 지정하는 경우에 특히 유용하다!
3. 모바일 앱에서 일부 스크롤러에 절대적 스크롤러(= 풀-투-리프레시) 동작이 있는데, 이는 Root Scroller에서 발생한다. 한 페이지에는 루트 스크롤러가 단 하나만 존재하며, 기본적으로 documentElement는 페이지의 루트 스크롤러이지만, 이 루트 스크롤러를 변경하면; 특정 동작이 documentElement 이외의 스크롤러에도 적용될 수 있다(= 암시적 루트 스크롤러)
[ 암시적 루트 스크롤러 ]
                                        
                                            const rootElement= document.documentElement
                                            const firstTier= rootElement.childNodes
                                            // firstTier는 루트 요소의 직계 자식의 NodeList(head, body 등)이다
                                            
                                            for(const child of firstTier) {
                                              // 루트 요소의 각 직계 자식으로 작업한다..
                                            }
                                        
                                    

☞ 암시적 루트 스크롤러를 만들려면; 컨테이너를 고정으로 배치하여 전체 표시 영역을 덮고, 스크롤러와 함께 z-index가 가장 높은지 확인하는 스크롤러 승격을 사용하면 된다:

스크롤 스냅

░ Css 은 스크롤 작업이 완료된 후 스크롤 컨테이너의 스크롤 오프셋을 원하는 스냅 위치가 되도록 조정하는 작업으로서, 이를 이용하면 페이지 매김된 기사나 캐러셀 이미지 등에서 스크롤 스냅 위치를 선언하여 잘 제어된 부드러운 스크롤 환경을 만들 수 있다.

스크롤 스냅 활성화하기
스크롤 스냅을 활성화하기 위해서는; 먼저, 스크롤 컨테이너의 크기와 overflow 속성을 정의해주어야 한다
[ 스크롤 스냅 활성화 ]
                                        
                                            .scroll_container { /* 스크롤 컨테이너 */
                                                height: 400px;
                                                overflow-y: scroll;
                                                scroll-snap-type: y mandatory; /* 스크롤스냅 타입 설정 */
                                            }
                                        
                                    

☞ 이 코드에서 height: 400px; 및 overflow-y: scroll; 값은 스크롤 컨테이너에 설정하는데, 컨텐츠가 컨테이너를 넘치지 않는다면; 스크롤할 것은 없다!

1. 다음, 스크롤 컨테이너에서 scroll-snap-type: x/y/both;(스크롤이 발생하는 축) 속성을 주어 스크롤 스냅을 활성화하는데, mandatory나 proximity 옵션(맞춤의 엄격도)을 추가해줄 수도 있다:
  • mandatory 옵션은 컨텐츠가 어느 지점에 스냅되건 간에 스크롤과 상관없음을 브라우저에 알려준다 ← 이는 스크롤이 완료될 때, 화면 상단에 있을 것으로 예상하는 것이 분명 거기에 있을 것이라고 확신할 수 있으므로 일관된 스크롤링이 가능해진다!
  • proximity 옵션은 근처에 있을 때만 스크롤 컨텐츠를 해당 위치에 스냅하며, 정확한 거리는 브라우저가 결정하도록 한다
2-1. 이어서, 스크롤 컨테이너의 하위 컨텐츠 요소에서 scroll-snap-align: start/center/end; 선언으로 스크롤 컨테이너 스냅 포트의 스크롤 오프셋(= 컨텐츠 정렬 위치)를 설정해준다:
                                    
                                        .scroll_container div { /* 스크롤할 컨텐츠 */
                                            scroll-snap-align: start; /* 블록축과 인라인축 모두에 적용된다 */
                                            /* scroll-snap-align: start center; 식으로 두개의 값을 주면; 각각 블록축과 인라인축에 적용된다 */
                                        }
                                    
                                

☞ 스냅 포트 표시 영역은 스크롤 컨테이너의 시각적 표시 영역과 동일하지만 scroll-padding 속성을 사용하여 조정해줄 수도 있다!


✓ 자식 요소 중 하나의 컨텐츠가 부모 컨테이너를 넘칠 경우라면; mandatory 옵션을 사용해서는 안된다 - 이 경우, 사용자가 넘친 컨텐츠를 스크롤하여 볼 수 없게된다! 또한, scroll-snap-type 값이 mandatory이면서 자식 요소의 scroll-snap-align 값이 없거나 none(기본값임!)이라면; 사용자는 해당 요소를 스크롤하여 볼 수 없다!

2-2. 스크롤 스냅에서 scroll-snap-align 값이 start나 end일 때, 스크롤 컨텐츠가 스냅 포트의 가장자리에 딱 붙지 않게 하려면; 스크롤 컨테이너에서 scroll-padding 값(= 인셋)을 설정해주면 된다. 나아가, 각 스크롤 컨텐츠 요소에서 scroll-margin 값(= 아웃셋)을 설정해줄 수도 있다:

✓ 다시 말해, scroll-padding 속성은 스크롤 컨테이너(또는, 스냅포트)의 표시영역을 조정하는 데 사용되는 스크롤 컨테이너의 인셋을 정의하며, scroll-margin 속성은 스크롤 컨테이너(또는, 스냅포트)의 대상이 되는 각 스크롤 컨텐츠 요소간 마진 간격을 조정하는 데 사용할 오프셋을 정의한다 ← 이러한 스크롤 컨테이너의 패딩과 스크롤 대상요소의 마진은 단순히 스크롤 표시영역을 맞추는 것이 아니라, 모든 관련 스크롤 작업 컨테이너 및 대상 컨텐츠 요소의 크기를 실제로 수정한다!

3. 기본적으로 스크롤 스냅은 사용자가 스크롤을 멈췄을 때만 작동한다. 따라서, 그 전에 여러 스냅 지점을 건너뛰어 지나칠 가능성이 있는데, 스크롤 대상요소에 scroll-snap-stop: always; 값을 주면; 이 건너뜀을 막을 수 있다:
                                    
                                        .scroll-container {
                                            scroll-snap-type: x mandatory;
                                        }
                                        
                                        .scroll-container > div { /* div:nth-of-type(odd) 및 div:nth-of-type(even) 식으로 좀 더 복잡하게 설정하는 것도 가능하다 ← 홀수번째 및 짝수번째마다 */
                                            scroll-snap-align: center;
                                            scroll-snap-stop: always; /* scroll-snap-stop: normal; ← 기본값 */
                                        }
                                    
                                

☞ 이 효과는 scroll-snap-type 속성에 mandatory 값이 주어졌을 때 더 두드러진다!

스크롤스냅 활용 사례
1. 스크롤 스냅을 활용하는 가장 일반적인 사례로는 가로 이미지 캐러셀이 있다. 가로축에 scroll-snap-type이 있도록 스크롤 컨테이너를 지정해주고, scroll-snap-align 속성으로 각 이미지의 맞춤 위치를 설정해주면 된다
[ 가로 스크롤 스냅 ]
                                        
                                            
                                        
                                    
                                        
                                            #gallery {
                                                display: flex;
                                                overflow-x: scroll;
                                                scroll-snap-type: x mandatory;
                                                scroll-padding: 50%; /* 자식요소들을 컨테이너 중앙에 스냅되도록 한다 */
                                            } #gallery img { scroll-snap-align: center; }
                                        
                                    
2. 스크롤 스냅을 활용하는 또 다른 대표적 사례는 세로로 스크롤할 수 있는 논리적 섹션들이 있는 페이지인데, 이 경우에는 scroll-snap-type: y proximity;가 더 적합하다 - 이는 사용자가 특정 섹션의 중앙으로 스크롤할 때 간섭을 일으키지 않으며, 사용자가 충분히 가까이 스크롤하면 스냅된다
[ 세로 스크롤 스냅 ]
                                        
                                            
                                        
                                    
                                        
                                            header { position: fixed; height: 10vh; }
    
                                            section {
                                                scroll-snap-type: y proximity;
                                                overflow-y: scroll;
                                                scroll-padding-top: 15vh; /* 헤더 및 그밖의 추가 확장 공간을 위한 여분! */
                                            } article { scroll-snap-align: start; }
                                        
                                    

☞ 스크롤 컨테이너의 상단에 15vh 인셋을 추가해줌으로써(scroll-padding-top: 15vh;), 웹브라우저에게 스크롤 컨테이너의 상단에서 15vh 아래 지점을 스크롤 스냅의 세로 시작 지점으로 취급하라고 알려주고, 따라서 스크롤 맞춤 대상요소의 시작 지점이 이 새로운 위치와 함께 플러시되어 위로 그만큼의 공간이 여분으로 확보된다!

3. (전체화면 섹션들로 구성된 개인 블로그 등) 및 (전체화면 이미지들로 구성된 캐러셀 이미지 슬라이더 등)도 웹사이트를 돌아다니면서 자주 접하게 되는 풍경들이다. 한편, 동시에 x, y 양방향으로 스크롤 스냅을 작동시킬 수도 있다 - 예컨대, 작은 타일들로 구성된 2차원 썸네일 갤러리를 구성할 때인데, 아래와 같은 방식으로 스크롤 스냅을 위한 Css 코드를 작성해줄 수 있다:
[ 양방향 스크롤 스냅 ]
                                        
                                            .thumbnail-gallery { /* 썸네일 갤러리 컨테이너 */
                                                height: 90vh;
                                                overflow: scroll;
                                                scroll-snap-type: both mandatory; /* 상하, 좌우 양방향 스크롤 스냅 타입 설정 */
                                            } .tile { /* 각각의 썸네일 이미지들 */
                                                scroll-snap-align: start;
                                            }
                                        
                                    

░ 이상, 이래 저래 스크롤 스냅 관련 요점들을 정리해봤지만.. 꽤나 어려운데다, 최신 기법이라 브라우저별 호환성 문제나 기기별 정상작동 여부는 MDN의 브라우저 호환성 명세도 참조하면서, 코딩 시 직접 확인해봐야 할 듯합니다 ㅡㅡ;

wave