이 CSS 마진 스타일이 작동하지 않는 이유는 무엇입니까?


321

다른 div 내부의 div에 여백 값을 추가하려고합니다. 최고 값을 제외하고는 모두 잘 작동하지만 무시되는 것 같습니다. 그런데 왜?

내가 기대 한 것 :
여백으로 예상 한 것 : 50px 50px 50px 50px;

내가 얻는 것 :
여백으로 얻는 것 : 50px 50px 50px 50px;

암호:

#outer {
    	width: 500px; 
    	height: 200px; 
    	background: #FFCCCC;
    	margin: 50px auto 0 auto;
    	display: block;
}
#inner {
    	background: #FFCC33;
    	margin: 50px 50px 50px 50px;
    	padding: 10px;
    	display: block;
}
<div id="outer">
  <div id="inner">
  	Hello world!
  </div>
</div>

W3Schools 는 왜 마진이 이런 식으로 행동하는지에 대한 설명이 없습니다.


4
당신은 내부를 떠 시도 했습니까?
Rooster

6
흠 .. float:left;그것은 작동하지만 ... 왜 이것이 필요합니다. 나는 그것이 뜨고 싶지 않습니다. 왜 왼쪽 / 오른쪽 여백이 작동합니까?
jamietelin

44
CSS 마진 붕괴 알고리즘의 재미있는 세계에 오신 것을 환영합니다!
GordonM

10
W3Schools vs. W3CDocs ... 우승자가 있다고 생각합니다. : D
enderskill 17.41에

15
그것의 jsFiddle 25 초 다음 사람을 저장 jsfiddle.net/kLeu9
CodyBugstein

답변:


453

실제로 #inner요소 의 위쪽 여백이 요소 의 위쪽 가장자리로 축소 되어 여백 #outer#outer그대로 유지됩니다 (이미지에는 표시되지 않음). 두 상자의 상단 가장자리는 여백이 같기 때문에 서로 플러시됩니다.

W3C 사양의 관련 사항은 다음과 같습니다.

8.3.1 붕괴 마진

CSS에서는 두 개 이상의 상자 (형제 일 수도 있고 아닐 수도 있음)의 인접한 여백을 결합하여 단일 여백을 형성 할 수 있습니다. 이러한 방식 으로 결합 된 여백은 축소 되었다고 말하며 결과로 생성 된 결합 마진을 축소 마진 이라고합니다 .

인접한 수직 여백 축소 [...]

다음 과 같은 경우에만 두 개의 마진이 인접 합니다.

  • 둘 다 동일한 블록 형식화 컨텍스트에 참여하는 인플 로우 블록 레벨 상자에 속합니다.
  • 라인 박스 없음, 간격 없음, 패딩 없음 및 경계선 없음
  • 둘 다 세로로 인접한 상자 가장자리에 속합니다. 즉 다음 쌍 중 하나를 형성합니다.
    • 상자의 상단 여백 및 첫 번째 유입 아이의 상단 여백

여백이 무너지지 않도록 다음 중 하나를 수행 할 수 있습니다.

위의 옵션으로 여백이 무너지는 것을 방지하는 이유는 다음과 같습니다.

  • 플로팅 된 상자와 다른 상자 사이의 여백은 무너지지 않습니다 (플로트와 플로우중인 자식 사이도 마찬가지).
  • 플로팅 및 '보이는'이외의 '오버플로'가있는 요소와 같은 새로운 블록 서식 컨텍스트를 설정하는 요소의 여백은 인플 로우 하위 요소와 함께 축소되지 않습니다.
  • 인라인 블록 박스의 여백은 무너지지 않습니다 (유입 아이와도).

왼쪽 및 오른쪽 여백은 다음과 같은 이유로 예상대로 작동합니다.

가로 여백은 절대 축소되지 않습니다.



2
이 대답은 흔들린다! 추가해야 할 것. w3c에 대한 당신의 인용은 그것을 말하지만 지금은 깨달았습니다. 따라서 다른 사람들에게 명확하게하기 위해 #outer에 테두리를 줄 수도 있습니다.
driechel

플로팅의 링크가 끊어진 것 같습니다.
EP

@episanty : 댓글에 링크 할 때 일어나는 일입니다. 연결되지 않았습니다.
BoltClock

알아요-그냥 알려 드리고 싶어요 ♦를 사용하도록 설정했기 때문에 의견을 다시 작성하거나 게시물을 적절하게 변경하고 싶을 것입니다. 그런데 좋은 답변 주셔서 감사합니다.
EP

92

display: inline-block;내부 div에서 사용하십시오 .

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:block;
}
#inner {
    background:#FFCC33;
    margin:50px 50px 50px 50px;
    padding:10px;
    display:inline-block;
}

6
좋은 대답입니다. 이 변경으로 문제가 해결되는 이유를 설명하면 더 좋습니다.
JohnFx

1
알았어, 이상해! 왜 작동합니까? 왜 예상대로 작동하지 않는지에 대한 논리적 설명은 무엇입니까? 여백 왼쪽 / 오른쪽없이 작동합니다 display:inline-block;. 또한 사용할 때 다시 설정 display:inline-block;하면 div에서 너비를 100 % 잃게됩니다.
jamietelin

3
인라인 블록으로 전환하면 배치 및 다른 규칙이 적용된 후 브라우저가 div의 크기를 다시 평가해야합니다.
Rooster

내 문제로 시험해 보았고 계단 효과를 만들었습니다.
Jonny

1
display:inline-block나를 위해 일했다. 정말 고맙습니다.
starkeen

24

@BoltClock이 언급 한 것은 꽤 견고합니다. 그리고이 문제에 대한 몇 가지 솔루션을 추가하고 싶습니다. 이 w3c_collapsing margin을 확인하십시오 . 녹색 부분은이 문제를 어떻게 해결할 수 있는지에 대한 잠재적 인 생각입니다.

해결책 1

플로팅 된 상자와 다른 상자 사이의 여백은 무너지지 않습니다 (플로트와 플로우중인 자식 사이도 마찬가지).

즉 , demo1 또는에 추가 float:left할 수 있습니다 .#outer#inner

또한 마진을 float무효화 할 것 auto입니다.

해결책 2

플로팅 및 '보이는'이외의 '오버플로'가있는 요소와 같은 새로운 블록 서식 컨텍스트를 설정하는 요소의 여백은 인플 로우 하위 요소와 함께 축소되지 않습니다.

이외 visible,하자 넣어 overflow: hidden#outer. 그리고이 방법은 매우 간단하고 괜찮은 것처럼 보입니다. 나는 그것을 좋아한다.

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    overflow: hidden;
}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;
}

해결책 3

절대 위치 상자의 여백은 축소되지 않습니다 (유입 자녀도 포함).

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: absolute; 
}
#inner{
    background: #FFCC33;
    height: 50px;
    margin: 50px;
}

또는

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: relative; 
}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;
    position: absolute;
}

이 두 가지 방법은 정상적인 흐름을 깰 것입니다 div

해결책 4

인라인 블록 박스의 여백은 무너지지 않습니다 (유입 아이와도).

@enderskill과 동일

해결책 5

동위가 클리어런스가없는 한, 유입 블록 레벨 요소의 하단 여백은 항상 다음 유입 블록 레벨 형제의 상단 여백과 함께 축소됩니다.

형제 사이의 무너진 마진이므로 질문과 관련이 없습니다. 그것은 일반적으로 최상위 박스가 margin-bottom: 30px있고 형제 박스가 있는지를 의미합니다 margin-top: 10px. 그들 사이의 총 마진은 30px대신에 40px있습니다.

해결책 6

요소에 상단 테두리가없고 상단 패딩이없고 하위에 여유가없는 경우 유입 블록 요소의 상단 여백이 첫 번째 유입 블록 레벨 하위의 상단 여백과 함께 축소됩니다.

이것은 매우 흥미롭고 하나의 상단 경계선을 추가 할 수 있습니다

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    border-top: 1px solid red;

}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;

}

또한 <div>기본적으로 블록 수준이므로 의도적으로 선언 할 필요가 없습니다. 초보자 평판으로 인해 2 개 이상의 링크와 이미지를 게시 할 수 없어서 죄송합니다. 적어도 다음에 비슷한 것을 볼 때 문제가 어디에서 오는지 알고 있습니다.


14

왜 작동하지 않는지 모르지만 추가 할 수 있습니다

overflow: auto;

외부 사업부.


이 문제에 대한 다양한 솔루션이 있습니다. 감사! 이 답변은 @BoltClock의 답변과 결합 하여이 솔루션이 작동하는 이유에 대한 좋은 정보를 제공합니다.
jamietelin

12

에 패딩을 추가 #outer하면 작동합니다.

데모

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:block;
    padding-top:1px;
}

11

왜 그런지 확실하지 않지만 내부 CSS를

display:inline-block;

작동하는 것 같다;


3

"왜"(무너지는 마진이 있어야 함)에는 대답하지 않지만 수행하려는 작업을 수행하는 가장 쉽고 논리적 인 방법 은 외부 div에 추가 padding-top하는 것 같습니다. 같습니다.

http://jsfiddle.net/hpU5d/1/

사소한 참고 사항- display:block;코드에 차단하지 말라고 알려주지 않는 한 div를 설정할 필요는 없습니다 .


3

이 시도:

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:table;
}
#inner {
    background:#FFCC33;
    margin:50px 50px 50px 50px;
    padding:10px;
    display:block;
}​

http://jsfiddle.net/7AXTf/

행운을 빕니다


2

#inner div 의 position 속성 을 relative로 설정 하면 효과를 얻는 데 도움이 될 수 있습니다. 그러나 어쨌든 IE9 및 최신 Chrome에 대한 질문에 붙여 넣은 원본 코드를 사용해 보았지만 이미 수정하지 않고 원하는 효과를 냈습니다.


2

padding-top:50px외부 div에 사용하십시오 . 이 같은:

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:table;}

참고 : 패딩은 div의 크기를 증가시킵니다. 이 경우 div의 크기가 중요한 경우 특정 높이를 가져야하는지 의미합니다. 높이를 50px 줄입니다. :

#outer {
    width:500px; 
    height:150px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:table;}

1

당신은! 중요한 것을 시도 했습니까?

margin:50px 50px 50px 50px !important;

-1

빠른 수정을 위해 자식 요소를 다음 div과 같은 요소로 래핑하십시오.

<div id="outer">
   <div class="divadjust" style="padding-top: 1px">
      <div id="inner">
         Hello world!
      </div>
   </div>
</div>

의 마진 inner사업부는의 패딩으로 인해 붕괴되지 않습니다 1px그 사이 outerinnerDIV. 따라서 논리적으로 1px기존의 innerdiv 여백과 함께 추가 공간이 생깁니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.