WEB/CSS

[CSS] westagram - inline 속성에서 발생하는 여백에 대해

heeney 2021. 12. 11. 11:07
728x90

 

[CSS] westagram - inline 속성에서 발생하는 여백에 대해

westagram 구현 도중 main 페이지에서 피드에
사용자의 아이디와 댓글 사이에 여백을 주지 않았는데 자동으로 여백이 생성되는 문제가 발생했다.

 


 

문제 되는 자동 여백 🤯

이게 뭐야잇!!! 동일한 CSS와 동일한 class, 동일한 레이아웃 구조인데 이런 문제가 발생했다.
아니 대체... 왜? 나는 일단 저 둘 사이에 여백을 준 적이 없습니다 (결백)
새로 생성된 댓글에 여백이 없는 것은 이해가 되는데 왜 그 전에 미리 HTML 안에서 생성해둔 요소들 사이에는 여백이 있을까?

그로 인해 왜 나에게 혼돈을 주는가...?

 

시도해본 것들 🛠

우선 자바스크립트를 살펴보자.
자바스크립트를 리팩토링 했을 때는 또 정상적으로 4px정도의 여백이 생기는거 아닌가? 문제가 JS 안에 있는건가? 싶어서 고민했다.

처음 작성한 코드 - main.js
const addNewComment = () => {
            const newCommentLocation = document.getElementsByClassName('comment_list')[0];

            let newComment = document.createElement('li');
            let userInfoWrap = document.createElement('div');
            let userName = document.createElement('em'),
                userComment = document.createElement('span');
            let commentLikeBtn = document.createElement('button'),
                commentLikeIcon = document.createElement('i');

            userInfoWrap.classList.add('user_desc');
            userName.innerText = 'user01';
            userComment.innerText = `${commentInput.value}`;

            commentLikeBtn.appendChild(commentLikeIcon);
            commentLikeIcon.classList.add('far', 'fa-heart', 'fa-xs');

            userInfoWrap.appendChild(userName);
            userInfoWrap.appendChild(userComment);

            newComment.appendChild(userInfoWrap);
            newComment.appendChild(commentLikeBtn);

            newCommentLocation.appendChild(newComment);
            commentInput.value = '';
        }

처음에 westagram 가이드 내용을 잘못 읽어서 createElement로만 구현해야 하는줄 알고 삽질을 했다... 😇
번거로웠지만 일단 구현했다. 이래서 머리가 좋아야 고생을 덜 한다.

리팩토링한 코드 - main.js
const addNewComment = () => {
    const newCommentLocation = document.getElementsByClassName('comment_list')[0];
    const newComment = document.createElement('li');

    newComment.innerHTML = `
      <div class="user_desc">
        <em>iAmUser</em>
        <span>${commentInput.value}</span>
      </div>
      <button><i class="far fa-heart fa-xs"></i></button>
    `;

    newCommentLocation.appendChild(newComment);
    commentInput.value = '';
  }

아 왜 여백이 있냐구요.

 

신영님 🙍🏻‍♀️: 줄바꿈 하지 않으면 어떻게 되나 한번 볼까요?

// 줄바꿈
newComment.innerHTML = `
  <div class="user_desc">
    <em>iAmUser</em>
    <span>${commentInput.value}</span>
  </div>
  <button><i class="far fa-heart fa-xs"></i></button>
`;

// 줄바꿈 X
newComment.innerHTML = `
  <div class="user_desc">
    <em>iAmUser</em><span>${commentInput.value}</span>
  </div>
  <button><i class="far fa-heart fa-xs"></i></button>
`;

코드에서 줄바꿈을 하지 않은 상태

CSS에서 padding, margin을 따로 0 줘보기도 했는데 당최 이유를 못찾겠더라. 리팩토링을 하긴 했지만 저렇게 되는 이유를 꼭 찾고 싶어서 신영님을 찾아가 질문했다.
신영님도 이유를 찾지 못해서 혹시나 싶어 리팩토링한 코드에서 em, span 태그를 줄바꿈 하지 않고 붙여서 확인해주셨는데 놀랍게도 여백이 없이 딱 붙었다.

엥...? 그렇다. inline 요소는 변태적이다 (???)
신영님이 함께 구글링 해주셨고 한번에 답이 나오는 모습을 보고 .... 현타 ....

 

 

그래서 이유가 뭔가요 🤷🏻‍♀️

inline 속성을 가진 요소는 폰트의 영향을 받는다.

정확하게는 inline, inline-block 속성을 가진 요소들은 모두 폰트의 영향을 받는다.
줄바꿈을 할 때 태그와 태그 사이에는 엔터라는 공백이 있고 이 공백이 font-size에 영향을 받으면서 16px 기준으로 4px의 여백이 자동으로 생기는 것이다.

 

코드를 줄바꿈하지 않고 붙인다? => 여백 없음

<div class="user_desc">
    <em>iAmUser</em><span>${commentInput.value}</span>
</div>

 

코드를 줄바꿈한다? => 여백 있음

<div class="user_desc">
    <em>iAmUser</em>
    <span>${commentInput.value}</span>
</div>

 

 

 

그래서 어떻게 해야하는데요? 👀

그럼 여백이 생기지 않게 해보자.

 

주석으로 할 수 있다고?
<div class="parent">
	<span class="child">inline~</span><!-- 
  --><span class="child">inline~~</span>
</div>

주석으로 엔터를 쳐주면 어쨌든 태그 사이에 엔터라는 공백이 실질적으로는 없는 셈이니 여백은 안생기는데 비효율적이다.
이런 방법도 있어서 신기해서 넣어봤다.

 

display flex
.parent {
    display: flex;
}

부모 요소에 flex를 넣어주면 기본값으로 flex-direction이 row로 되어 있기에 옆으로 붙는다.
이렇게 하면 여백이 없다.

 

margin-right: -4px
span {
    margin-right: -4px;
}

span 태그의 경우 오른쪽에 여백이 생기므로 margin을 통해 여백을 없애준다.

 

float
.parent::after {
    content: "";
    display: block;
    clear: both;
}

.child {
    float:left;
}

자식에 float를 줘서 옆으로 붙게 하자.
이렇게 하면 여백이 사라지지만 float의 고질병을 해결해주기 위해 부모 요소에 clear를 부여한다.

 

 font-size: 0
img {
    font-size: 0;
}

/* or */

.parent {
    font-size: 0;
}

.child {
    font-size: 16px;
}

이 방법은 이미지에 가장 유용할 것 같아서 넣었으나 그냥 inline 요소에 있어서도 사용될 수 있다.
이미지의 경우 글귀가 들어갈 일은 없으니 font-size: 0을 해주면 용이할 것 같다.
그리고 부모 요소에 font-size: 0을 주고 자식 요소에 원래 적용해야할 폰트 사이즈를 지정해주는 것도 좋다.

 

 

 

마무리 ✨

어이는 없지만 뭐 어떡하나 받아들여야지 ... 🧘🏻‍♀️
그래도 신기하기도 하고 이런 숨은 진실(?)을 알게 되면 재밌다. 이유도 알아보았고 해결 방법도 찾았다.
나는 display flex를 줄곧 사용할 것 같다. 무지성으로 사용하면 여백은 사라지니까 해결 방법으로 충분하다.
이제 인라인 속성의 요소를 보고 갑작스레 여백이 생긴다면 당황하지 말고 해결 방법을 통해 해결해주자!!! 그까이꺼!!!

 

 

 

728x90