inline요소와 block요소에 margin 적용

괴발·2023년 2월 2일
0
post-thumbnail

인라인 요소 margin top-bottom 미적용

사건

html-css 과제를 하다가 a태그에 문제 발생.

<!--내가 짠 html -->
<a href="/">
  <div>
    <img src=""/>
  </div>
</a>

<!--브라우저에서 확인되는 html-->
<a href="/">
</a>
<div>
  <img src=""/>
</div>

a태그 내부에 다른 태그들을 넣었더니 실제 브라우저에서는 a만 뽑혀서 따로 있었다. 왜이럴까.

발단

왜그러니 싶어서 찾아보니,

?? : 하하! a 안에 다른 태그들이 오면 닫힌단다.
나 : 근데 img 만 넣었을 때는 또 되는데요?

해서 혼자 a 하나 놓고 이렇게 저렇게 만져보고 있었다.
그러다 알게 된 또다른 사실.

<style>
  body{
    margin: 0;
  }
  a{
    border: 1px solid #000;
    margin: 10px;
    padding: 10px;
  }
</style>

<body>
  <a href="/">여기는 a태그 입니다.</a>
</body>

난 분명 margin과 padding을 전부 다 줬는데 왜 위는 저렇게 꽉막혀 있는 걸까?

값이 들어가긴 다 들어감.
대체 a자식이 왜 이런건가 싶었다.

전개

나는 해당 문제의 원인이 1) 내가 거지같이 짠 html 구조 + 2) a태그의 특성을 이해 못한 채 사용한 것 으로 생각했다.
결과적으로 2)가 어느정도는 맞았다.

내가 간과한 점은 하나. a 태그는 inline 요소 라는 점이다.

inline 요소의 기본적인 특징은 다음과 같다.

  • 요소의 width,height 값은 content 값을 기본으로 갖는다.
  • 요소들이 가로,수평으로 쌓인다.

📍 이로인해 내가 처음 맞닥뜨린 문제

문제 :: a태그 안에 다른 요소를 넣으니 a가 먼저 닫혔다.
답안 ::
a 태그는 인라인 요소이므로 내부에 블록 요소인 div 가 오면 당연히 a 태그의 content 크기를 div가 뽝! 뚫고 나오게 되므로,
a 태그는 옆구리가 터지지 않기 위해 호다닥 문을 닫을 수 밖에 없던 것이다.
그래서 div로 감싼 img는 문제가 발생했지만 a 태그 안에 같은 inline 요소인 img를 넣는 것은 가능했던 것!

📍 그럼 두번째 문제.

문제 :: a 태그 top/bottom 여백이 제대로 들어가지 않는 것은 왜 그런걸까?
답안 ::
이것도 inline 요소 전체의 특징이다.
원래 inline 요소는 margin top-bottom이 안들어 간다고 한다.
위 이미지에서는 마치 padding top이 적용되지 않는 것 처럼 보이지만 실제론 들어간 거다.(브라우저 가려진 듯)

위에 블록요소인 div를 놓아보면 좀더 눈에 잘 보인다.

<style>
  body{
    margin: 0;
    padding: 0;
  }
  a{
    border: 1px solid #000;
    margin: 10px;
    padding: 10px;
  }
  span{
    border: 1px solid #ac2;
    margin: 10px;
    padding: 10px;
  }
  div{
    border: 1px solid #91d;
    margin: 10px;
    padding: 10px;
  }
</style>

<body>
  <div>div-block</div>
  
  <a href="/">여기는 a태그 입니다.</a>

  <span>span-inline</span>
</body>

브라우저에서 실제 블록요소와 인라인 요소가 적용된 모습을 보면

블록요소인 div는 margin과 padding 둘다 상하좌우 모두 적용 된 것이 확인된다.

📍 인라인 요소는 padding은 상하좌우가 모두 적용되었지만 margin은 좌우여백은 적용되지만 상하여백은 적용되지 않는 것이 확인된다. 게다가 div의 margin도 적용이 엥? 왜안되지?

oh 인라인은 블록라인에 적용된 margin도 적용이 안되는군.

그럼 inline-block을 주면 어캐되나?

a 태그에 inline-block을 주니 a 태그에 준 margin이 적용되면서 주변 블록 요소의 margin도 이제는 영향을 준다.
다만 같은 선상에 있던 인라인 요소 span은 여전히 margin top-bottom이 적용되지 않음에도
a 태그가 inline-block으로 바뀌어 margin의 영향을 받으니 같이 영향을 받는 것을 확인할 수 있다.

아주 신기하다.

한번 데였으니 이제 인라인 안에 블록을 넣는 바보짓은 하지 않겠지! 하하하 (사망플래그)

인라인 요소 예시

<a>, <abbr>, <acronym>, <b>, <bdo>, <big>, 
<br/>, <button>, <cite>, <code>, <dfn>,
<em>, <i>, <img>, <input>, <kbd>, <label>,
<map>, <object>, <q>, <samp>, <small>,
<script>, <select>, <span>, <strong>, <sub>, 
<sup>, <textarea>, <tt>, <var>  

블록 요소 예시

<address>, <article>, <aside>, <audio>, 
<blockquote>, <canvas>, <dd>, <div>, <dl>, 
<fieldset>, <figcaption>, <figure>, <footer>, 
<form>, <h1>, <h2>, <h3>, <h4>, <h5>, <h6>,
<header>, <hgroup>, <hr>, <noscript>, <ol>, 
<output>, <p>, <pre>, <section>, <table>, 
<ul>, <video>

🚨 블록 요소는 내부 중첩으로 블록라인, 인라인 요소 모두 올 수 있지만
< p >만 내부에 인라인 요소가 와야 한다.





블록요소의 마진상쇄(margin collapsing)

블록 얘도 margin에 억한 심정이 있나보다.
블록요소는 블록요소의 margin top과 bottom이 만났을 때 더 큰 margin값 하나만 적용되는 현상이 있다.

case 1. 인접 형제간의 margin 중첩


  <div>div-block1</div>
  <div>div-block2</div>

div{
      border: 1px solid #91d;
      width: 100px;
      height: 100px;
      padding: 10px;
      
      margin-top: 10px;
      margin-bottom: 30px;
      margin-left: 10px;
      margin-right: 10px;
    }

이미지는 div-block1의 margin을 표현한 것이다.
코드를 보면 margin-bottom은 30px 나머지는 다 10px 씩 적용했다.
블록요소인 div가 만나는 부분은 div-block1의 bottom값 30px과 div-block2의 top값 10px이 적용되어 총 40px 만큼의 간격이 떨어져야 하는데 보다시피 div-block1의 bottom값 30px 만 적용된 것을 확인할 수 있다. 물론 div-block2의 top 10px이 div-block2에 적용은 되어있다.
즉, 중첩적용이 안된다는 것.

case 2. 부모-자신 간의 margin 중첩

<div class="parent">
  <div class="child">div-block1</div>
  <div class="child">div-block2</div>
</div>

부모-자식 요소가 중첩된 상태에서 first-child의 margin-top과 부모의 margin-top, last-child의 margin-bottom과 부모의 margin-bottom 이 만나는 경우 마진상쇄(margin collapsing) 현상이 발생한다.
이는 부모가 boder도 없고, padding도 없는 상태에서 자식요소의 margin과 부모요소의 margin이 만났을 때 발생한다.

case 3. 자식요소에 content가 없는 빈 블록일 때 margin 중첩

말 그대로 자식 요소가 content 없는 비어있는 블로 요소이고 부모 요소가 boder도 없고, padding도 없는 상태에서 자식요소의 margin과 부모요소의 margin이 만났을 때 발생한다.

마진 상쇄를 만난 경우 오류라고 생각할 수 있으나 공식문서에 적혀있는 사실이자 현상이다.
왜인지는 모름. 그치만 해당 현상을 맞닥뜨렸을 때 오류나 버그로 인지해 당황하지 말고 해결 방안을 생각해보는 것이 좋다.

profile
괴발개발

0개의 댓글