CSS 기초 | CSS guidelines, 나쁜 CSS 습관
안녕하세요! 요번 포스팅은 CSS 기초를 다뤄볼까합니다
SI 회사에 다니면서 CSS가 얼마나 말썽을 피우는지 절실하게 느꼈습니다
그리고 꼼꼼한 사수 밑에 작업하다보니
제가 웹표준과 웹접근성의 어긋나 트릭을 사용한 몇몇개도 알게되었고..
ie 호환성 이슈... (진짜 빡친다)
이미 구축 된 서비스에 일부분을 만들어 붙칠 때의 CSS 문제... 등등
원래 가장 쉬우면서도 가장 말썽이라는게 CSS라고는 하지만....
제가 잘 몰랐던게 꽤나 많구나를 느꼈습니다
그래서 MDN에서 제시하는 CSS 가이드라인과 제가 실무에서 느낀 가이드라인을 정리해서 써볼까합니다
MDN 내용은 아래 링크에서 확인 가능합니다
1. reset.css을 사용하지 마십시오
MDN에서는 리셋을 해놓고 다시 설정할 때의 시간이 많이 소요하니 지양하라고 말하고 있습니다
저는 실무에서 다른 이유로 쓰지 말라는 이야기를 들었는대요
처음부터 끝까지 서비스 전체를 만드는 프로젝트라면 상관은 없는데
일부분을 만들어서 납품(?)해야하는 서비스라면 이미 구축되어있는 서비스의 CSS와 충돌이 일어납니다
CSS는 우선 순위에따라 적용될 스타일이 결정됩니다 👉 캐스케이딩 Cascading
그래서 같은 태그에 같은 속성을 적용하면 마지막으로 작성한 스타일이 적용됩니다
보통 만들 때 reset.css와 common.css/main.css를 따로 분리해서 link로 겁니다
근데 그걸 그대로 끌고 와서 기존 서비스에 붙치면
<link href="기존서비스1.css>
<link href="기존서비스2.css>
<link href="reset.css>
<link href="우리회사.css">
이런식으로 된다는 겁니다.. 그럼 이제 기존 서비스 CSS도 꼬이고
기존 서비스 CSS와 충돌을 일으켜 우리 쪽 CSS도 망가지고~ 난리나는 겁니다
그래서 초기화는 부모 태그(감싸고 있는 상위 태그)에서 필요한 부분만 일일히 작성 해주고
자식 태그에서 스타일을 지정해주는게 좋습니다
2. 와일드카드(*), !important를 쓰지 마십시오
이 또한 위에 내용과 비슷합니다
와일드카드(*)는 전역 CSS 설정인데요. 초기화를위해 적당히 쓰는 것은 괜찮지만
많은 것들을 설정해서는 안됩니다. 그럴경우 HTML 엘리먼트 연산이 많아질수도 있다고 합니다
/* 적당한 수준 */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
!important는 CSS 우선 순위 최상위에 있는 속성 강제 적용입니다
위든 밑에서든 아무리 열심히 스타일 적용을 했어도 이게 설정 되어있으면 이걸로 적용됩니다ㅋㅋㅋㅋㅋ
이거는 정말정말 어쩔 수 없는 최후의 수단일때 쓰는건데
저는 한번도 써본적이 없습니다.. 가끔 font-family에서 쓰는걸 본 적이 있는데
협업에서 딱 쌍욕 먹기 좋습니다
애초에 이걸 쓸 상황이 안 나오게 코드를 잘 작성해야겠죠?
3. ID 선택자, 태그 선택자를 사용하지 마십시오
MDN과 실무에서 둘 다 들은 이야기입니다
이건 시맨틱 웹과 관련이 있는데요
다들 이런 구조로 짜는게 좋다고 많이 봐왔을겁니다
그 전에는 <div id="header">처럼 id로 지정해서 써온걸 많이 보실 수 있을겁니다
물론 위에 것들을 쓰지 말라는 의미는 아닌 것 같고...
단순 <header></header> 이렇게만 작성하는 것이 아닌 결국 각각의 class를 지정해줘야한다는 말인 것 같습니다
안그러면 재사용성이 떨어지거든요....
ID 선택자 같은 경우
MDN에서는 유연성이 떨어지고 필요한 경우 재정의하기가 어려우며 클래스보다 특이성이 높다고 말하고 있고
다른 게시물에서는 CSS에서 ID로 요소를 선택하는 것은 안티패턴으로 간주된다고 합니다 (가능은 함)
안티패턴 내용은 처음 알았네요 세상에나...😱
태그 선택자 같은 경우에는
CSS에서 실수로 전역 CSS와 같이 스타일 적용을 해버리게 되니깐 그런 것 같습니다
header h1 { ... }
section { ... }
이런식으로 작성하게 되면 모~든 페이지의 section이 동일하게 적용되겠죠 (
의도한거면 상관은 없겠지만...)
쨌뜬 협업에서는 재사용과 다른 CSS와의 충돌을 피하기위해 class 쓰는걸 추천합니다
자세한 내용 👉 csswizardry.com/2014/07/hacks-for-dealing-with-specificity/
4. HTML 기본 속성을 무시하지 마십시오
- span은 텍스트에만 사용
- h1, h2 태그는 최대한 초기화, 스타일 적용하지 않고 그대로 사용
- button 태그는 버튼에만 사용
이 외 등등...
inline 태그에 굳이 display:block; 을 부여하는 모습...
태그의 고유 속성을 초기화하고 새로운 스타일을 적용하는 모습들을 꽤나 많이 보셨을겁니다
(저 또한 저렇게 했다가 지적 많이 당했습니다 😂)
태그의 용도와 의미를 정확하게 파악하고 사용해야겠습니다
5. 선택자 길이를 길게 쓰지 마십시오
/* 안 좋은 습관 */
.container #main .section .section-slider .section-slider_img .slider_img_btn { ... }
/* 좋은 습관 */
.section-slider_img .slider_img_btn { ... }
이 실수는 CSS 전처리도구를 쓰면서 많이하게 되는 것 같습니다
Sass 같은 경우 들여쓰기를 하다보니 변환된 css 파일을 보면
무진장 길어진 선택자들을 보실 수 있을겁니다
(경험담임 ㅎ 사수한테 털린 부분...)
이건 가독성에 굉장히 안 좋습니다. 딱봐도 한 눈에 알아보기가 힘들죠
최대 3개가 넘지 않게 제한하고, 부모 선택자를 표시해야한다면 꼭 필요한 경우에만 작성하길 바랍니다
6. @import 사용을 피하십시오
@import 말고 link 사용월 권합니다. 속도면애서 link가 훨씬 빠르기 때문인데요
그리고 CSS에서 보통 웹폰트를 불러오기위해 @import를 쓰는 경우가 많습니다
이 또한 협업에서는 안 좋습니다
인터넷 연결이 되어있어야만 @import로 불러온 폰트를 쓸 수 있기 때문입니다
인터넷 연결이 안되어있다? 그럼 폰트가 다~ 깨진다는 의미겠죠
또한 납품(납품이란 의미가 맞을까...)할 때도 결국 사용한 폰트와 함께 다같이 넘겨줘야해서
웹폰트 파일을 다운받아 연결하는게 좋습니다
7. z-index를 규칙있게 묶어서 지정하세요
이 부분은 제가 실무에서 개인적으로 경험한 일입니다
저같은 경우 z-index를 여러 레이아웃에 줄 때 순차적으로 줬습니다
.header {
z-index: 1;
}
.header .btn {
z-index: 2;
}
.section {
z-index: 3;
}
.footer {
z-index: 4;
}
. footer .img {
z-index: 5;
}
만약 이렇게 줬다고 가정했을 경우
.section 부분에 새로운 컨텐츠가 들어가면서 z-index: 4를 줘버렸다면?
footer가 section의 가려지면서 z-index를 다시 설정해줘야 할 것입니다
이런 일이 계속 반복된다면 무한반복 전체 수정으로 이어지겠죠....?
그런 불필요한 반복을 덜고자 아래와 같이 레이아웃별로 크게 숫자 단위를 지정해주는 겁니다
/* header는 10~19 사이 숫자 사용 */
.header {
z-index: 10;
}
.header .btn {
z-index: 11;
}
/* section은 20~29 사이 숫자 사용 */
.section {
z-index: 20;
}
/* footer는 30~39 사이 숫자 사용 */
.footer {
z-index: 30;
}
. footer .img {
z-index: 31;
}
이런식으로 규칙을 정해놓으면 .section부분에 어떠한 콘텐츠가 들어서도
footer에는 영향이 안 가겠죠?!
이건 제 사수님께 아주 크게 배운 부분입니다. 매우 중요한 패턴이라고 생각합니다😊
👩💻 마무리
이 외에도 HTML, CSS 안티패턴에 관해서 따로 포스팅 해볼까합니다
위에 내용들은 현재 본인 회사의 상황, 어떠한 사람들과 협업을 하냐에따라
조금씩 바뀔 수 있는 규칙들이라고 생각합니다
꽤나 잘 알고 있던 CSS라고 생각했는데.....
진짜... 배울게 참 많습니다🤣
혹시 제가 놓친 부분, 잘못 표기한 내용이 있다면 댓글 부탁드립니다💗
➕ 솔루션 (SI) 프로젝트시 마크업 규칙
HTML 시멘틱 태그와 CSS의 가이드를 동시에 지키는 법이 무엇일까?를 고민해봤습니다
SI 회사 같은 경우에는 프로젝트를 처음부터 끝까지 만드는 경우도 있지만
의뢰를 받아 기존 서비스에 일부분만 개발하거나, 자사 서비스를 고객사에 일부분만 붙쳐
환경에 맞게 조금씩 수정해야하는 경우들이 있습니다
그럴 경우 CSS가 무너지기 쉽다고 했죠
사수한테 물어본 결과 이런 경우에는 보통 아래와 같이 작성하는 것 같습니다
HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<body>
<div id="kyung">
<header class="ky-header">
<p class="ky-txt">
<span>텍스트1</span>
</p>
<p class="ky-txt">
<span>텍스트2</span>
</p>
</header>
</div>
</body>
|
cs |
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#kyung {
width: 360px !important; min-height: 520px !important;
max-height: 720px !important;
height: 80% !important;
position: fixed !important;
bottom: 25px !important;
border-radius: 16px !important;
background-color: transparent !important;
box-shadow: rgba(81, 99, 120, 0.3) 0px 6px 60px 0px !important;
z-index: 1000000000 !important;
overflow: hidden !important;
animation: 0.25s ease-out 0s 1 normal none running jZyQVL !important;
}
header.ky-header{
...
}
header.ky-header p.ky-txt{
...
}
p.ky-txt > span{
...
}
|
cs |
이렇게 body 안에 컨텐츠를 감싸고 있는 최상위 태그인 <div id="kyung">를 만들어서
그 어떠한 외부 스타일에 영향을 받지 않게 !important 사용해 스타일을 작성해주는 겁니다
(초기화, 기본값을 작성하려면 여기서(최상위 태그) 작성해 넣으면 되는겁니다)
이러한 패턴을 네임스페이스라고 부릅니다
네임스페이스 패턴은 애플리케이션이나 라이브러리를 위한 전역 객체를 하나 만들고 모든 기능을 이 객체에 추가하는 방법이다.
제가 전에 HTML에서 시멘틱 태그를 작성하고 CSS에서 태그 선택자로 불러서 스타일을 적용하니 혼이 났었죠!
그러니 이제 예제처럼 저렇게 작성하면 다른 스타일과 부딛히지 않겠죠?
태그 선택자와 클래스 이름을 붙쳐서 작성해주니
이게 클래스 ky-header 라는 이름을 가진 header 태그의 스타일이구나 를 바로 알 수 있어서
가독성과 협업에서도 더 좋겠죠?!‼
💥 이건 특수한 상황에서 적용되는 규칙입니다. 일반적인 상황에서는 이렇게 작성하시면 안돼요!!