본문 바로가기

Development/Web

HTML + CSS 자주 등장하는 질문 정리

들어가며

작년 여름, 퇴사한 이후 처음으로 웹 개발의 매력에 빠져 혼자서 꾸준히 공부해온 탓에 지금은 Node.js를 사용한 API 서버 개발, React로 간단한 웹 사이트 개발은 가능한 수준이라고 생각은 되나, 제대로 된 기초가 없어서 그런지 매번 개발 과정이 순조롭지 않다고 생각하여 웹 개발 기초 교육를 통해 기초를 쌓아가자는 의미에서 스파르타코딩클럽 내일배움단의 '웹개발 종합반'을 신청하였다. 1주차 내용은 정말 기초적인 HTML, CSS, JavaScript에 대해 다루기 때문에 기초 개념 설명은 기록하지 않고, 슬랙(slack) 질문 채널에 자주 올라온 질문 중에서 중요하다고 생각하는 내용을 선택하여 스스로 답해보는 형식으로 정리해보겠다.

CSS 선택자의 우선순위를 결정하는 명시도

❓ Question

아래와 같이 div 태그를 두 개의 클래스 선택자로 스타일을 적용시켰는데 green으로 적용된다. 이 두 개의 class를 모두 사용하여 빨강색 글씨에 연두색 테두리로 스타일링하고 싶은데 어떻게 해야 할까?

<head>
    <style>
        .red {
            color: red;
        }

        .green {
            color: green;
            border: 1px solid green;
        }
    </style>
</head>
<body>
    <div class="red green"></div>
</body>

✔ Answer

위 상황에서 두 개의 클래스 선택자를 하나의 태그에 적용시키면 순서에 상관없이 .green에 해당하는 스타일로 적용이 되는데, 그 이유는 명시도라는 개념에 영향을 받기 때문이다. 명시도란 선택자의 종류에 따라 스타일이 적용되는 우선순라고 할 수 있다. 위 질문에서는 두 개의 class 선택자가 있는데, 이와 같이 선택자의 종류(요소, id, class 등)가 같은 경우 가장 최근에 정의한 스타일의 우선순위가 더 높기 때문에 .green에 해당하는 스타일이 적용된다. 질문에서 요구하는 스타일로 적용하는 방법에는 아래와 같이 3가지 정도 있다.

첫 번째로는 아래와 같이 CSS에 명시한 스타일의 순서를 바꿔주는 것이다. 위에서 언급하였듯이 선택자의 종류가 같은 경우 가장 최근에 정의한 스타일의 우선순위가 더 높게 지정되므로 원하는 스타일을 구현할 수 있다.

.green {
    color: green;
    border: 1px solid green;
}

.red {
    color: red;
}

두 번째로는 id 선택자로 변경하는 것이다. id 선택자는 class 선택자보다 우선순위가 높다. 따라서, 아래와 같이 코드를 수정한다면 원하는 스타일로 구현할 수 있다.

<head>
    <style>
        #red {
            color: red;
        }

        .green {
            color: green;
            border: 1px solid green;
        }
    </style>
</head>
<body>
    <div id="red" class="green"></div>
</body>

마지막으로는 스타일 요소에 !important 예외를 적용시켜주는 것이다. !important는 우선순위가 가장 높기 때문에 원하는 스타일로 구현할 수 있으나, 이는 스타일의 종속을 깨뜨려 디버깅을 더 어렵게 만들 수 있기 때문에 Bootstrap과 같은 외부 라이브러리의 스타일을 재정의하려는 등의 특수 경우에만 사용할 것을 권장하고 있다.

.red {
    color: red !impoarnt;
}

.green {
    color: green;
    border: 1px solid green;
}

display 속성의 block과 inline

❓ Question

label 태그와 div 태그를 한 줄로 구현하려면 어떻게 해야 할까?

<body>
    <div>
        <label>지금 바로</label>
        <div>주문하기</div>
    </div>
</body>

✔ Answer

이를 이해하기 위해서는 먼저 display의 block과 inline에 대해서 알아야 한다. display 속성으로 요소의 배치를 설정할 수 있는데, 속성의 값으로는 대표적으로 block과 inline이 있다. 이 중에서 block은 새롭게 줄바꿈을 하여 한 줄을 통째로 차지하는 방식이고, inline은 줄바꿈을 하지 않고 이미 존재하는 줄에 포함되어 나란히 배치되는 방식이다. 모든 요소에는 display 속성의 기본값이 존재하는데, block을 기본값으로 하는 요소는 <h1> ~ <h6>, <p>, <div> 등이 있다. 즉, div 태그는 display: block가 기본값으로 설정되어 있기 때문에 아래 코드와 같이 수정하면 원하는 스타일을 구현할 수 있다.

<body>
    <div>
        <label>지금 바로</label>
        <div style="display: inline;">주문하기</div>
    </div>
</body>

button 태그 가운데 정렬

❓ Question

button 태그를 가운데로 정렬하려면 어떻게 해야 할까?

<head>
    <style>
        .wrapper {
            width: 500px;
            margin: auto;
        }

        .wrapper > div {
            width: fit-content;
            margin: auto;
        }

        .wrapper > button {
            margin: auto;
        }
    </style>
</head>
<body>
    <div class="wrapper">
        <div><input type="text" placeholder="아이디"></div>
        <div><input type="password" placeholder="비밀번호"></div>
        <button>로그인</button>
    </div>
</body>

✔ Answer

바로 위에서 언급한 display 속성값을 변경하여 쉽게 해결할 수 있다(물론, flex로 구현하는 방법도 있지만 여기서는 설명하지 않겠다). button 태그의 display 속성은 기본값으로 inline-block으로 설정되어 있는데, 이는 inline과 block의 특징을 결합하여 외부는 inline으로 내부는 block으로 나타내는 속성값이다.

위에서 언급하지는 않았지만, inline과 block은 또 다른 특징 차이가 존재한다. block은 해당 태그가 한 줄을 따로 차지하는 영역이 있기 때문에 width와 height을 통해 태그의 크기를 조절할 수 있으며, 모든 방향의 padding과 margin을 설정할 수 있다. 반면에, inline은 해당 태그가 마크업하고 있는 컨텐트의 크기 만큼만 공간을 차지하기 때문에 width와 height이 적용되지 않으며, 가로 방향의 padding과 margin만 설정할 수 있다(대신에 line-height 속성으로 높이를 조절할 수는 있다). 즉, inline-block 줄바꿈없이 width, height, 모든 방향의 margin과 padding을 조절할 수 있다.

즉, inline-block은 가로 방향의 margin을 조절할 수 있지만, 한 줄을 따로 차지하지 않기 때문에 margin: auto로는 margin을 조절할 수 없다. 따라서, display 속성을 block으로 변경하면 원하는 스타일로 구현할 수 있다.

.wrapper > button {
    display: block;
    margin: auto;
}

margin과 padding의 차이

❓ Question

두 개의 div 태그에 배경색을 green으로 설정해놓고 각각 margin과 padding을 지정하였더니, padding을 적용한 div 태그의 크기가 커진 것을 확인하였다. 도대체 margin과 padding의 차이가 무엇이길래 이와 같은 현상이 발생하는 것일까?

<head>
    <style>
        div {
            width: 40px;
            height: 30px;
            background-color: green;
        }

        .margin {
            margin: 30px;
        }

        .padding {
            padding: 30px;
        }    
        </style>
</head>
<body>
    <div class="margin"></div>
    <div class="padding"></div>
</body>

✔ Answer

태그에는 경계선인 border가 있는데, 이 border를 기준으로 안쪽 여백을 padding, , 바깥쪽 여백을 margin이라고 한다. 즉, padding의 값을 크게 지정할 수록 요소의 내부를 차지하는 공백이 늘어나기 때문에 요소의 크기가 늘어난다.

마치며

오늘부로 스온스에 참여한지 4일째 되는 날이다. 하지만, 안타깝게도 오늘은 스온스에 제대로 참여하지 못했다. 오후 1시부터 게더스쿨 맨 앞자리에 참석했지만, 하필 스온스가 시작하기 5분 전에 외주 요청 업무를 처리하느라 제대로 참여하지 못했다(저녁 8시까지 작업한 끝에 모든 일은 끝냈지만, 오늘 공부는 하나도 못했다는거... ). 그래서 집에 돌아온 후 강의 진도만 빼놓고, 웹 개발 1주차 개발일지를 쓰고 있는데 하루를 통째로 날려버린 느낌이라 굉장히 아쉽다. 어떤 외주 업무였는지는 시간나면 따로 포스팅하도록 하고, 내일을 위해 이만 여기서 마치겠다.