아주 기본적인 CSS 의 문법은 밑과 같이 표현 할 수 있다.
Styling 이라는 Domain 내부에서 단순히 색상, 텍스트 크기만을 정하는 것이 아니기 때문이다.
이와 관련된 중요한 속성과 값을 알아야 하며, 이를 이해해야 제대로 CSS 를 사용할 수 있다.
나도 CSS 를 잘 사용하지 못한다.
CSS 는 하나 이상의 DOM 을 한번에 스타일링 할 수 있다.
이는 단순 파일에서 그치는 것이 아니라, 한 번의 선언에서 스타일링 할 수도 있다.
이는 수많은 HTML 태그 중 비슷한 성격의 태그들을 뭉쳐서 같은 스타일로 만들 수 있다.
주로 HTML 스타일링 템플릿에서 비슷한 성격의 선언들을 볼 수 있다.
그래서, 선택자를 먼저 봐 보자.
혹은 두 개 이상의 태그를 한 번에 스타일링 할 수 있다.
이에 대한 예제를 보자.
그 태그를 그대로 넣어서 스타일링 하면 된다.
라는 의문이 들었다.
자유로운 HTML 특성상 렌더링이 될 수는 있겠으나, 콘솔에서는 분명히 경고가 뜰 것이다.
중첩된 태그들 내부에서 "유일" 한 기능 or View 를 보여주어야 하는 DOM 들이 있다.
예를 들면, 검색 창이 있을 것 같다.
이는 HTML 파일에 존재하는 모든 엘리먼트에 대해서 적용한다는 의미이다.
또 다른 역할로는, 조금 이따 보게 될 결합 선택자로 다양한 스타일링을 추구 할 수 있다.
각 계층이 중앙 정렬을 통해 집합처럼 다른 색상을 보이게 만들 수 있다.
나도 이 선택자는 처음 접해보는데, 활용도가 무궁무진 할 것 같다는 생각이 든다.
등등
class, id 를 특성, 즉 Attribute 라고 말할 수 있다.
단순히 "이 속성(특성) 을 가졌다" 해서 콕 집을 수도 있겠지만,
MDN 문서의 예제를 보고 그 활용 예제가 많다는 것을 느꼈다.
MDN 문서에서 예시로 준 CSS
/* <a> elements with a title attribute */
/* <a> 태그에 title 이라는 속성이 "존재" 한다면 */
a[title] {
color: purple;
}
/* <a> elements with an href matching "https://example.org" */
/* <a> 태그에 href 속성이 존재하는데, 이 속성의 값이 "https://example.org" 라면 */
a[href="https://example.org"]
{
color: green;
}
/* <a> elements with an href containing "example" */
/* <a> 태그의 href 가 "example" 을 어떤 형태이던 가지고 있다면. */
a[href*="example"] {
font-size: 2em;
}
/* <a> elements with an href ending ".org" */
/* <a> 태그의 href 속성 값이 ".org" 로 끝난다면. */
a[href$=".org"] {
font-style: italic;
}
/* <a> elements whose class attribute contains the word "logo" */
/* <a> 태그의 class 속성이 "logo" 를 가지고 있을 때. */
/* 이러한 표현법은, class="logo large bold" 이러한 방식처럼, 여러 개가 중첩되었을 때 사용이 가능하다. */
a[class~="logo"] {
padding: 2px;
}
이를 다시 재해석하여 내 방식으로 작성한다면,
본래 문서보다 설명이 떨어질 것이라는 게 내 판단이었다.
나는 속성 선택자를 처음 배우기 때문이다.
다시 보면, 속성 선택자를 보더라도, CSS 를 다시 배우길 잘했단 생각도 든다..
MDN CSS 특성 선택자 문서
이것을 보면 "특성(속성) 선택자" 라는 영역에 대해서 굉장히 자세히 배울 수 있다.
강의나 책 수준에서는 다루지 않았던 Detail 이 쏟아져 나오는데,
CSS 단순 지식에서 돌파하기 어려운 복잡한 스타일 구성을
속성(특성) 선택자를 이용하여 상당수 돌파할 수 있으리라고 생각된다.
내가 공식 문서를 보며 배우는 것이 이러한 묘미에서 나온 것이 아닐까 생각된다.
특성 선택자에 대한 정확한 구문은 밑의 링크를 클릭하면 볼 수 있다.
MDN CSS 특성 선택자 - (구문)
나도 처음 사용 해 보는, 속성 선택자를 이용 해 볼 시간이다.
예를 들어, 이렇게 만들 수 있을 것 같다.
input 태그에는 placeholder 라는 속성이 존재한다.
사이트 사용자가 입력 시 어떤 형태로 입력해야 하는지 예시로 보여주는 역할을 한다.
간단하게, 이메일 형태가 있을 것이다.
그리고 사용자의 "별명" 도 입력할 수 있을 것인데,
여기에는 data-nickname 이라는 개발자의 HTML 전용 Convention 을 이용해서 작성한다.
즉, 개발자가 따로 일반 Tag 에 원하는 "속성" 을 생성하고 싶다면,
input[placeholder] {
border-radius : 5px;
font-size : bold;
color : pink;
}
input[data-nickname] {
margin-top : 10px;
color : blue;
}
<body>
<input placeholder="example@example.com"/>
<br/>
<input data-nickname/>
</body>
위의 예제를 보다시피, 동일한 태그인 input 임에도 불구하고,
태그에 어떤 속성이 선언되었느냐에 따라 스타일링이 다르게 표출되는 것을 알 수 있다.
위의 CSS 선언은 어떻게 해석 할 수 있을까?
사용자에게 안내가 필요한 부분은(placeholder)
- 입력 칸 모서리 둥글게
- 폰트는 두껍게
- 텍스트는 핑크색
사용자가 "별명" 을 입력하는 칸 (data-nickname - 개발자의 커스텀 속성 선언시)
- 바로 위의
input 과는 10 픽셀 조금 떨어뜨리고,
- 텍스트 색상은 파란색.
내가 보여준 예제는 MDN 에서 보여준 것과는 다르게 매우 간단하므로,
이 속성(특성) 선택자를 활용하기 위해서는 위의 다양한 형태에 대해서 읽어볼 필요가 있다.
특히, 특정 속성에 "어떤 내용을 내포할 때" 적용하는 개별 스타일 a[href*="example"] 이라는 예시는
정말 사용할 데가 많아 보인다.
뿐만 아니라, 웹을 개발하는 도중에 하나의 태그에 중첩된 클래스 이름을 빈 칸인 로 떨어뜨리는 경우가 있는데,
a[class~="logo"] 라는 선택자로 가져오는 것은,
classnames 라는 NPM 모듈 대신 선택할 수 있는 대체품으로 보이기까지 한다.
& 을 사용하는 중첩 선택자의 경우 (& nesting)
속성(특성) 선택자를 처음 배운 것 처럼,
나는 중첩 선택자를 처음 본다. 아주 정확히는, CSS 에서도 되는 지 몰랐다.
아마 CSS 가 발전하면서 들어간 기능이라고 "예측" 되는데,
그 이유는 scss, sass 처럼 중첩된 형태로 CSS 를 작성할 경우,
결국 브라우저가 이를 따로 나눈 것과 동일하게 인식하기 떄문이다.
예를 들어서,
.parent-css {
/* 부모 스타일링 규칙 */
.child-css {
/* 자식 스타일링 규칙 */
}
}
이러한 형태로 CSS 를 작성한다면,
브라우저가 중첩 선택자를 파싱하는 과정에서, 자동으로 이 선택자 사이에 공백을 추가하여
선택자 규칙을 생성하기 때문이다.
위의 중첩 표현식은 이렇게 파싱된다.
.parent-css {
/* 부모 스타일링 규칙 */
}
.parent-css .child-css {
/* 자식 스타일링 규칙 */
/* 이 형태는 부모 스타일링 규칙 요소에 대한 자식 요소의 스타일링 규칙을 의미한다. */
}
공백인 ' ' 을 사용하여 따로 생성하는데,
이는 여러 개의 선택자를 한 번에 선언하는 .parent-css, .child-css {...} 과는 다르다.
그리고, 위에 선언된 "파싱이 필요없는" CSS 구문은,
밑의 CSS 와도 동일하다.
.parent-css {
/* 부모 스타일링 */
& .child-css {
/* 자식 스타일링 */
}
}
이는 아무리 봐도 SASS 문법 같은데, 이런걸 흔히 알고 있나? 궁금해서 AI 에게 질문 해 보았다.
(Gemini 2.5 Pro)
그런데, 중첩 선택자는 SASS 에서만 가능하다고 말하는 것이다.
따라서, MDN 의 정확한 Reference 를 대고 너의 주장이 확실한 것인지,
아니면 너무 최신의 정보라 너가 인식하지 못한 것인지 물어보니까,
자신의 정보가 틀렸다고 인정하고, 최신 브라우저에 적용되는 문법이라고 말해 주었다.
예시 :
.parent-css {
background : pink;
text-align : center;
width : 250px;
.child-css {
background : dodgerblue;
text-align : center;
width : 125px;
}
}
<body>
<div class="parent-css">
parent <br/>
<div class="child-css">child</div>
</div>
<br/>
<div class="child-css">child</div>
</body>
위의 예시를 본다면,
부모인 parent-css 클래스가 적용된 component 와,
자식인 child-css 클래스가 적용된 component 는 정상적으로 스타일링 되는 것을 볼 수 있다.
그러나, 그 밑에 부모 컴포넌트 없이,
단순히 child-css 만이 적용된 컴포넌트는, 그 어떤 스타일링도 되지 않은 것을 볼 수 있다.
즉, 중첩 선택자로 적용되었을 때,
.child-css 는 하나만 똑 떼어져서 선언되는 것이 아니라,
.parent-css .child-css 로 선택자가 생성된다.
이는, 부모 컴포넌트가 .parent-css 클래스이며, 자식 컴포넌트가 .child-css 클래스를 가져야만`
.child-css 가 적용될 수 있는 것이다.
브라우저가 최신 전처리를 통해 파싱한 정확한 css 는,
.parent-css {
background : pink;
text-align : center;
width : 250px;
}
.parent-css .child-css {
background : dodgerblue;
text-align : center;
width : 125px;
}
이기 때문이다. 즉, 선택자 중 .child-css 만 선언되는 경우는 없다.
그렇다면 이 최신 기능은 어떤 시점의 브라우저에서부터 적용되나?
일단, MDN 의 이 목록을 보는 것이 좋다.
중첩 선택자 브라우저 호환성
인터넷 브라우저의 대표 주자인 Chrome 은, 2023-12 에 정식 Release 되었다.
이는 매우 최신 기능이라고 볼 수 있다.
중첩 선택자의 중요성
우리가 CSS 를 통해 만들게 될 여러 Element 들을 Interaction 하게 꾸밀 수 있다.
이 때, 우리가 가장 중요하게 사용될 문자는 바로 & 이다.
이 문자가 들어가냐, 들어가지 않냐에 따라서 그 의미가 달라지기 때문이다.
예를 들어 보자.
유저와 소통하는 듯한 HTML 컴포넌트의 Interaction 을 생각 해 보자.
이를 위해 HTML 태그에는 "가상 클래스" 라는 것이 존재한다.
예를 들자면,
active <--> disabled
focus
hover
예를 들어, 특정 영역 위에 마우스가 올라갔을 때,
색상 변화 혹은 트랜지션을 통해 인터랙션 UX 를 주는 것이 대표 예시 중 하나라고 생각한다.
.container {
text-align : center;
padding : 10px;
margin : 5px;
background : black;
color : #999;
&:hover {
color : #555;
background : #aaa;
}
}
<body>
<div class="container">
container
</div>
<div class="container">
container
</div>
<div class="container">
container
</div>
</body>
위의 예제에 마우스를 가져다 대 보면,
마우스가 올라간 엘리먼트는 마치 Interaction 한 느낌을 줄 수 있다.
물론, 트랜지션까지 넣은 것은 아니라서, 아직은 미완성적인 느낌을 줄 수 있다.
그렇다면, & 를 없애면 어떻게 될까?
여기가 포인트인데, &:hover 에서, :hover 로 배치가 바뀌면 어떻게 될지 보는 것이다.
그렇게 된다면, container 클래스 속성을 가진 엘리먼트가 :hover 가 되었을 때가 아니라,
.container :hover 로 선언되기 때문에,
container 이라는 클래스 속성을 가진 엘리먼트의 "자식 엘리먼트가" :hover 되었을 때,
로 변경된다.
.container {
background : dodgerblue;
margin : 10px;
:hover {
background : black;
color : white;
}
}
div {
background : skyblue;
margin : 5px;
padding : 10px;
text-align : center;
}
<body>
<div class="container">
<div>div 1</div>
<div>div 2</div>
<div>div 3</div>
</div>
</body>
이 예제의 바로 직전에서 container 클래스 속성을 "가진" 엘리먼트에 한하여 처리를 했던 반면,
이 예제는 container 클래스 속성을 가진 엘리먼트의 "자식" 엘리먼트에 한하여 :hover 처리를 했다.
이러한 패턴은 특정 클래스 속성 컴포넌트 내부에서 공통 Interaction 을 지정 할 때 유용할 것이라고 생각한다.
중첩 선택자 "&" 에 대한 직관적인 이해
중첩 선택자 & 문자는 CSS 작성에 있어 편리함을 주지만,
프로그래밍에 있어 직관적인 이해 또한 필요하다고 생각한다.
& 는 위와 같은 기능을 가능하게 해 주며,
& 는 "정확히" 부모 엘리먼트를 의미한다.
.container {
background : black;
color : white;
& > a {
color : blue;
}
}
위의 css 는 정확히
.container {
background : black;
color : white;
}
.container > a {
color : blue;
}
이렇게 파싱된다.
괄호 속의 괄호 표현식을 가능하게 해 주는 & (레퍼런스) 문자는, 이러한 의미를 담고 있다.
또 다른 예시를 들어 보자.
.level-1 {
&:hover {
background : red;
}
& > .level-2 {
&:hover {
background : green;
}
& > .level-3 {
&:hover {
background : blue;
}
}
}
}
div {
text-align : center;
margin : 10px;
padding : 5px;
}
여기 최상위 level-1 클래스 속성을 가진 컴포넌트부터,
최하위 level-3 클래스 속성을 가지는 컴포넌트를 꾸미는 CSS 가 있다.
위에서 & 레퍼런스 문자가 많이 사용되었는데, 이는 어떻게 스타일링될까?
<body>
<div class="level-1">
level-1
<div class="level-2">
level-2
<div class="level-3">level-3</div>
</div>
</div>
</body>
위의 예제에 level-1 부터 level-3 텍스트까지 호버링 해 보자.
그렇다면, 위의 CSS 예제에서 선언된 & 들은 서로 다른 Scope 를 가졌음을 알 수 있다.
&(레퍼런스) 는, 현재 자신을 괄호 { ... } 로 담고 있는 선택자를 의미한다.
CSS 인접 형제 결합자의 경우 ("+")
이번에는 "동일 계층에 존재하는" DOM 을 위한 스타일링 문법을 볼 수 있다.
만약에, a + p { ... } 가 된다면, 이러한 의미를 가진다.
a 직후 p 가 들어와야 발동한다.
- 위의 선택자 예시는
p 를 스타일링한다.
위의 결합자(+) 라는 것을 어디에 사용할까.. 상상을 해 보니,
예를 들어 img 이미지는 이후 설명이 들어가는 경우가 많다.
따라서, img 태그 이후 설명에 관한 p (Paragraph) 문장이 올 경우,
img + p { ... } 로 꾸밀 수 있을 것 같다.
여기서 img 만 와도 딱히 상관이 없으며,
바로 직후 p 태그가 있을 경우, 이미지 설명에 관한 스타일링을 해 주겠다.
이러한 목적으로 작성할 수 있을 것 같다.
div {
margin : 0px;
}
img {
width : 100%;
margin : 10px;
}
img + p {
padding : 5px;
border : 2px solid dodgerblue;
border-radius : 5px;
text-align : center;
}
<body>
<div>
<img src="https://tistory1.daumcdn.net/tistory/6142901/attach/eaf30c1affbe45adb0179071560647bc"/>
</div>
<div>
<img src="https://tistory1.daumcdn.net/tistory/6142901/attach/eaf30c1affbe45adb0179071560647bc"/>
<p>코딩크리쳐 로고 이미지입니다.</p>
</div>
</body>
위와 같은 방식으로 이미지에 따라붙는 설명 목적의 p 에만 따로 스타일링을 추가할 수 있다.
CSS 일반 형제 결합자의 경우 ("~")
직전에 알게 되었던 "인접 형제 결합자" (+) 와는 달리,
일반 형제 결합자는 더 넓은 Scope 를 의미한다.
"인접" 형제 결합자의 경우 img + p { ... } 가 된다면,
img 태그 "직후" p 태그만 스타일링 했다.
그러나, 일반 형제 결합자 ~ 의 경우,
img ~ p { ... } 가 된다면,
img 태그 이후 나타나는 "모든" p 태그에 대해 스타일링을 적용한다.
물론, 이는 img 와 같은 계층의 p 태그일 경우에만 적용이다.
특정 태그 이후에 나타나는 "같은 계층의" 특정 태그를 "모두" 선택한다는 기능은
꽤 유연한 기능으로 보여, 오히려 어떤 용도로 사용될지 감이 잡히진 않았다.
따라서, 이에 대한 사용 Convention 을 Gemini 에게 질문했는데,
답변의 요약은, "주로 Interaction CSS 에 사용된다" 였다.
AI 가 제시한 예시와 방식은,
어떻게 특정 웹 사이트는, 내가 클릭하는 것에 대해서 다른 요소를 띄워줄 수 있는가?
에 대한 의문을 해소시켜주기에 충분했다.
이러한 예제를 만들어 보기로 했다.
처음 나타나는 요소는, 2 가지의 체크박스가 존재한다.
그런데, 하나의 체크박스를 활성화 할 때 마다,
더 디테일 한 선택지를 하위에 보여 주는 식으로 제작할 수 있다는 것이다.
이번에는 HTML 을 먼저 작성하는 것이, CSS 파일을 이해하는 데 더 가독성이 좋을 것이라고 판단하여
HTML 파일을 작성 한 후, CSS 를 작성해 보기로 했다.
개발자가 현재 선호하는 파트와, 관련된 언어를 선택하는 체크박스를 만들기로 했다.
<body>
<fieldset>
<legend>일반 형제 선택자 예시</legend>
<div>
<input type="checkbox" id="front-end" name="front"/>
<label for="front">Front-End</label>
<div class="front-switch">
<input type="checkbox" id="js-front" name="javascript" />
<label for="javascript">JavaScript</label>
<input type="checkbox" id="python-front" name="python" />
<label for="python">Python</label>
</div>
<br/>
<br/>
<input type="checkbox" id="back-end" name="back" />
<label for="back">Back-End</label>
<div class="back-switch">
<input type="checkbox" id="js-back" name="javascript" />
<label for="javascript">JavaScript</label>
<input type="checkbox" id="java-back" name="java" />
<label for="java">Java</label>
</div>
</div>
</fieldset>
</body>
.front-switch, .back-switch {
display : none;
}
#front-end:checked ~ .front-switch {
display : block;
}
#back-end:checked ~ .back-switch {
display : block;
}
위의 예제를 실제로 클릭 해 보면,
각 체크박스를 클릭 할 때
JS 코드 없이 CSS 만으로 원하는 다른 체크박스를 나타나게 만들 수 있다.
물론 위의 HTML 을 보면, 선택자의 위치 상 "인접 형제 선택자" 인 + 로 변경해도 된다.
그러나, 그 사이에 설명에 해당하는 p 태그가 들어가도, ~ 선택자 덕분에 스타일이 변경되지 않는다.
CSS 의 가상 클래스란 무엇인가?
위에서 보여준 예제 중, :hover 이 가상 클래스에 해당하고,
:focus , ... 등등 다양한 가상 클래스 요소가 CSS 에 존재한다.
그렇다면, 가상 클래스란 무엇인가?
완벽하진 않지만, 가상 클래스란, HTML 태그 내부에
"설정되었을 수도" "설정되지 않았을 수도" 있는 클래스를 의미한다.
MDN 에 따르면, "선택자에 추가하는 키워드로, 선택한 요소가 특별한 상태여야 만족 할 수 있다" 라고 한다.
예를 들어서, 위에서 체크박스 예시를 사용 할 때,
:checked 를 사용하여 선택자를 선언했다.
HTML 을 작성 할 때, 우리는 CheckBox 나, RadioButton 여러 개를 선언 할 때,
기본적으로 "선택된 상태" 로 나타날 지, "선택되지 않은 상태" 로 나타날 지 선택할 수 있다.
<input type="checkbox" ... checked> ==> 이 체크박스는 선택된 상태로 초기화 된다.
<input type="checkbox" ...> ==> 선택되지 않은 상태로 나타난다.
즉, input Element 에서, checked 라는 가상 항목은, "있을수도, 없을 수도" 있다.
HTML 태그들은 웹 페이지를 작성함에 있어, 위와 같은 "그럴수도, 아닐수도" 에 대한 "가상 클래스" 들을
마련 해 두었다. 40개 쯤 된다.
참고로, 이 가상 클래스라는 것은, class=".." 로 선택할 수 없으며, ...[checked]
와 같이 선택 할 수 없다.
element:가상 클래스 로 선택 할 수 있다.
먼저, 내가 예시를 들기 전, 대부분의 가상 클래스에 대해 예시를 들고 있는 MDN 링크를 둔다.
MDN 공식문서 - (Pseudo-classes)
유용 해 보이는 CSS 가상 클래스 선택자들
이 CSS 가상 클래스 선택자들은, HTML 과 CSS 의 "정해진 소통" 과 흡사하다고 생각된다.
HTML 과 CSS 는 서로에게 상관 할 수 없다.
그러나, 이 가상 클래스 선택자(Pseudo classes) 들은 HTML 과 CSS 간의
정해진 변경 사항에 대한 스타일링 소통 이라고 생각한다.
가상 클래스 선택자들은 수십가지가 되는데,
기초 상태에서 알아야 할 가상 클래스 선택자는 이 글에 넣을 수 있겠다 생각된다.
:hover
위에서 작성한 인터랙션 예시에서 :hover 을 즐겨 사용 한 것을 볼 수 있다.
그 만큼 유저가 직접적으로 맞닥들일 수 있는 현재 상태에 대한 가상 클래스이다.
만약에 사용자가 특정 HTML 요소에 마우스(Pointing 디바이스)로 커서를 올려 놓는다면,
해당 HTML 요소에 :hover 이라는 가상 클래스가 붙게 된다.
이를 "호버링" 이라고 부르는데, 사용자가 현재 커서를 올려두고 있는 요소에 집중하게 해 주는 용도로
자주 사용된다.
아마 스타일링 장인분들은 다양한 사용처에 대해 알고 있겠지만... 나는 일단 요 정도로 알고 있다.
애니메이션까지 더하면 금상첨화겠지만, 기초부터 탄탄히 해야 한다는 나의 철학과는 비견될 수 밖에 없다.
글의 실용성을 위해, 잠시 transition 을 사용하기로 마음먹었다.
.interaction-button {
margin : 10px;
padding : 10px;
color : white;
background : black;
transition : background 0.3s ease-in-out;
&:hover {
background : dodgerblue;
}
}
<body>
<button class="interaction-button">btn 1</button>
<br/>
<button class="interaction-button">btn 2</button>
</body>
위의 예제의 버튼에 커서를 올려보면, 자연스럽게 파란색으로 변했다가,
다시 원래의 색으로 돌아오는 것을 볼 수 있다.
:active
이 가상 클래스는 특정 엘리먼트를 "클릭 한 후 뗄 때 까지" 해당 엘리먼트에 활성화된다.
주로 다른 페이지의 링크를 가르키는 a 태그에 사용된다고 하는데,
나는 인접 형제 선택자와 더불어서, 궁금할 수 있는 단어를 클릭하는 동안,
밑에 그 설명을 보조하는 공간이 있으면 어떨까 생각을 해 보았다.
<body>
<article>
<p>리액트란 무엇일까? - 클릭</p>
<ol>
<li>현대적인 웹 프로젝트를 위한 라이브러리이다.</li>
<li>Webpack, Babel 등등의 방법론을 통해 트랜스파일링 결과물이 나온다.</li>
</ol>
</article>
<article>
<p>CSS 란 무엇일까? - 클릭</p>
<ol>
<li>Cascading Style Sheet 의 약자이다.</li>
<li>HTML 파일 내의 엘리먼트를 스타일링 하기 위해 존재한다.</li>
</ol>
</article>
</body>
p {
padding : 3px;
border : 3px solid black;
border-radius : 4px;
}
ol {
display : none;
}
p:active + ol {
display : block;
}
해당 영역을 "클릭하는 동안", 직후에 나타나는
Ordered List 스타일의 설명이 나타날 수 있게 만들었다.
만약에 이 가상 클래스를 전문적으로 사용한다면,
블록을 자유자재로 옮길 수 있는 Notion 이나, Jira 같은 곳에서
타임라인을 옮기는 데에 사용하지 않을까? 하고 상상 해 본다.
:focus
주로 Tab 키 나, 실제 입력이 가능한 엘리먼트는 focus 가상 클래스를 가질 수 있다.
단, div, section, article, ... 등등 단순한 블록 선언 엘리먼트는 가질 수 없다.
대신, :focus-within 이라는 속성을 통해 자손이 포커싱을 받았을 때, 공유하는 개념은 존재한다.
이번에는 포커싱을 통해 무엇을 제작 해 볼까... 하다가,
form 내부에 여러 input 을 넣어 놓고,
input 이 포커싱을 받았을 때,
그리고 input 이 포커싱을 받았으므로 자손으로 두는 form 의 변화도 같이 다루기로 했다.
input {
margin : 10px;
padding : 10px;
background : #999;
transition : background 0.3s ease-in-out;
&:focus {
border : 3px solid dodgerblue;
background : #fff; /* white */
}
}
form {
border : 2px solid black;
border-radius : 10px;
padding : 15px;
transition : border 0.3s ease-in-out;
&:focus-within {
border : 3px solid blue;
}
}
<body>
<form>
<legend>이름 및 별명</legend>
이름 : <input type="text"></input> <br/> <br/>
별명 : <input type="text"></input>
</form>
<br/>
<form>
<legend>사용 언어 및 프레임워크</legend>
언어 : <input type="text"></input> <br/> <br/>
프레임워크 : <input type="text"></input>
</form>
</body>
위의 예제에서 각 form 내부에 존재하는 input 에 포커싱을 주면,
해당 input 과 더불어, 이를 포함하는 form 까지 같이 포커싱이 되도록 만들었다.
나중에 회원가입이나, 제출 양식 같은 것을 만들 때,
:focus-within 을 사용하면 더 좋은 인터랙션을 만들 수 있을 것 같아 같이 사용 해 보았다.
:nth-*
이 가상 클래스는 같은 요소가 나열되어 있을 때,
각 줄이 가독성을 가지게 만들 수 있다는 점에서 중요하다 판단했다.
예를 들어,
제품 리스트 수십 개가 한 번에 나열되어 있을 때, 가독성은 떨어질 수 밖에 없다.
특히 하나의 줄에 여러 Column 까지 있다면, 읽기는 더 힘들다.
따라서, 연속되는 속성에 따라 배경색을 달리 한다면, 가독성을 확보할 수 있겠다고 생각했다.
li:nth-child(2n) {
background : #333;
color : #aaa;
}
li:nth-child(odd) {
background : white;
color : black;
}
<body>
<ol id="ordered-list">
</ol>
<script>
const olObj = document.getElementById("ordered-list");
for(let i = 0; i < 20; i++) {
let newLiObj = document.createElement("li");
newLiObj.textContent = "item : " + i;
olObj.appendChild(newLiObj);
}
</script>
</body>
위의 예시 색상은 조금 극단적으로 가기는 했다.
위에서 css 예시를 보면, 보기 드문 괄호 (..) 가 들어갔다.
이는 "몇 번째?" 를 정확하게 하기 위함이다.
여기에 단순 숫자를 넣는다면, 해당 순번만 스타일링이 되며,
xn 형식으로 넣는다면, x 번째마다 스타일링이 된다.
혹은, even, odd 만 그대로 괄호에 넣어 번갈아 가며 스타일링 할 수 있게 해 주었다.
이 :nth-* 에는, 위와 같은 사용처 뿐만 아니라,
MDN (nth-* 예시)
문서를 통해 더 자세한 내용을 볼 수 있다.
이 글을 끝내며
맨 처음, 이 글을 시작하며 "작성하게 된 이유" 를 덧붙였다.
CSS 를 배우는데 이렇게 장황한 이유로 시작 할 이유가 있나? 라고 생각이 들 만큼 길게 작성한 것 같다.
그래도, 오랫동안 기억했으면 좋을 내용을 따로 만들어 작성하는 나로서는,
왜 이 글을 작성하는지 보자마자 떠올릴 수 있다.
아, 이 때 무엇을 했었고, 무엇을 배웠구나 하고 말이다.
아직 CSS 에서 중요한 부분은 너무나도 많이 남아 있다.
display 속성에 따른 스타일링 방식
- 더 많은 가상 클래스와, 아직 다루지 않은 가상 속성(pseudo elements)
- 애니메이션 및 트랜지션
- Modal (모달 만들기)
이러한 것들은 실제 프로젝트를 진행하면서, 더 파고들게 되면 그 때 글로 다룰 생각이다.
SASS 와의 차이점?
웹 브라우저의 CSS 전처리기가 발달하며 조금 복잡해 진 중첩 선택자도 알아들을 수 있게 되었지만,
여전히 브라우저가 "직접" 파싱한다는 점에서 클라이언트에게 일을 떠맡긴 셈이 되었다.
SASS 의 기능을 다수 기본 CSS 파일에서도 처리 할 수 있도록 만들었지만,
여전히 SASS 의 강점은 존재한다.
즉, 자체적인 동적 스크립팅은 SASS, SCSS 가 더 우세하다고 생각한다.
또한, 작성한 동적 스크립팅 함수에 대한 재사용성이 좋아, 개발 시에는 SASS 기반 스타일링이 편할 것 같다.
그리고 또 다른 차이점은, Bundler 의 이용 여부에 있다.
CSS 또한, 선언된 위치와 순위에 따라 우선순위가 달라지기는 하지만,
SASS 는 React 컴포넌트 파일과 함께 작성되기 마련이다.
이 때, 번들러의 의존성 Resolver 덕분에, CSS 파생 파일들이 한 군데 합쳐지거나,
사용자가 원하는 만큼의 Chunk 로 분해해서, 이를 브라우저가 Load 할 수 있게 만들어 준다.
이번 글에서 크게 배운 점.
CSS 를 잘 알지 못했기 때문에,
HTML 엘리먼트에서 복잡한 클래스를 선언하고, CSS 파일을 단순화 하는 방향으로 스타일링을 진행했었다.
이는 나중에 오히려 엘리먼트나 복합 컴포넌트를 추가 할 때 문제가 되었다.
아직도 CSS 에 대해서 "이해했냐?" 하면 기초를 조금 이해하게 되었다고 말할 수 있을 것 같다.
아직 여전히 많이 사용되는 기능과 표현에 대해서는 모르며, 이에 대한 실전 사용법을 잘 모르기 때문이다.
그러나, 이번에 다양한 선택자(Selector) 를 둘러보면서 실제 예제를 만들었다.
중첩 연산자(&), 형제 인접 연산자(+), 일반 형제 연산자(~) 를 통해
깔끔하게 작성하지 못하던 CSS 문법을 매끄럽게 작성할 수 있으리라는 생각이 든다.
독자들에게 전하는 말
궁금 한 것이 있다면,
이 곳으로 물어보시면 환영입니다!
참조 사이트
W3School CSS Tutorial
https://www.w3schools.com/css/default.asp
W3School CSS Reference
https://www.w3schools.com/CSSref/index.php
GeeksForGeeks - (CSS Properties Complete Reference)
https://www.geeksforgeeks.org/css/css-properties-complete-reference/
위키피디아 (CSS)
https://ko.wikipedia.org/wiki/CSS
MDN 문서 - (CSS 선택자)
https://developer.mozilla.org/ko/docs/Web/CSS/CSS_selectors