이 인라인 블록 요소가 아래로 밀린 이유는 무엇입니까?


238

다음은 내 코드이며 모든 브라우저에서 #firstDiv가 아래로 밀리는 이유 를 이해하고 싶습니다 . 나는 그것이 왜 다른 방향으로 그것을 위로 당기는 것이 아니라 아래로 밀리는 지에 대한 사실의 내부 작용 을 이해 하고 싶습니다 . (그리고 나는 그들의 상단을 정렬하는 방법을 알고있다 :))

그리고 나는 그것의 overflow : hidden을 알고 있지만 그것이 왜 div를 아래쪽으로 밀고 있는지 확실하지 않습니다.

body {
  width: 350px;
  margin: 0px auto;
}

#container {
  border: 15px solid orange;
}

#firstDiv {
  border: 10px solid brown;
  display: inline-block;
  width: 70px;
  overflow: hidden;
}

#secondDiv {
  border: 10px solid skyblue;
  float: left;
  width: 70px;
}

#thirdDiv {
  display: inline-block;
  border: 5px solid yellowgreen;
}
<div id="container">
  <div id="firstDiv">FIRST</div>
  <div id="secondDiv">SECOND</div>
  <div id="thirdDiv">THIRD
    <br>some more content<br> some more content
  </div>
</div>

http://jsfiddle.net/WGCyu/ .

답변:


361

기본적으로 코드에 혼란을 더하여 혼란을 더 많이 일으키므로 먼저 실제 문제를 이해하는 데 방해가되는 혼란을 제거하려고합니다.

우선 우리는 실제 질문이 무엇인지 확인해야합니다. 그 이유는 " inline-block"요소가 아래로 밀린 이유 입니다.

이제 우리는 그것을 이해하고 혼란을 먼저 제거합니다.

1- 세 div 모두에 동일한 테두리 너비를 지정하지 않는 이유는 무엇입니까? 줘 보자

2- 플로팅 요소에 인라인 블록 요소가 아래쪽으로 눌려 있습니까? 아니요, 그것과 관련이 없습니다.

따라서 해당 div를 모두 제거했습니다 . 그리고 인라인 블록 요소가 아래로 밀리는 것과 동일한 동작을 목격하고 있습니다.

여기에 일부 문헌 이 줄 상자의 개념을 이해하고 동일한 줄에 줄이 어떻게 배열되어 있는지 질문의 답이 있기 때문에 마지막 단락을주의 깊게 읽습니다.

'inline-block'의 기준선은 유입 흐름 선 상자가 없거나 'overflow'속성에 'visible'이외의 계산 된 값이없는 경우 일반 흐름에서 마지막 선 상자의 기준선입니다. 이 경우 기준선은 아래쪽 여백 가장자리입니다.

기준 에 대해 잘 모르는 경우 간단한 단어로 간단한 설명이 있습니다.

'gjpqy'를 제외한 모든 문자는 기준선에 작성됩니다.이 "무작위 문자"바로 아래에 밑줄과 같은 간단한 수평선을 그리는 것처럼 기준선으로 생각할 수 있습니다. 그러면 'gjpqy'를 쓰면 기준선이됩니다. 같은 줄에있는 문자는이 문자의 아래 부분이 줄 아래로 떨어집니다.

따라서 'gjpqy'를 제외한 모든 문자는 기준선 위에 완전히 쓰여지고 일부 문자는 기준선 아래에 쓰여 있다고 말할 수 있습니다.

3- 왜 우리의 기준선이 어디에 있는지 확인하지 않습니까? 우리 라인 의 기준선을 나타내는 문자를 몇 개 추가했습니다 .

4- 왜 우리의 div에 문자를 추가하여 div에서 기준선을 찾을 수 없습니까? 여기에 기준선을 명확히하기 위해 div에 일부 문자가 추가되었습니다 .

이제베이스 라인에 대해 이해하면 인라인 블록의베이스 라인에 대한 다음 단순화 된 버전을 읽으십시오.

i) 문제의 인라인 블록이 overflow 속성을 visible로 설정 한 경우 (기본적으로 설정하지 않아도 됨) 그런 다음 기준선은 포함하는 블록 블록의 기준선이됩니다.

ii) 해당 인라인 블록의 overflow 속성이 OTHER THAN visible로 설정되어있는 경우. 그런 다음 아래쪽 여백은 포함 상자 행의 기준선에 있습니다.

  • 첫 번째 세부 사항

이제 녹색 div로 무슨 일이 일어나고 있는지 개념을 명확히하기 위해 이것을 다시 살펴보십시오 . 아직 혼란이 있다면 여기에 포함 블록의 기준선을 설정하기 위해 녹색 div에 더 많은 문자가 추가 되고 녹색 div 기준선이 정렬됩니다.

글쎄, 나는 그들이 동일한 기준을 가지고 있다고 주장하고 있습니까? 권리?

5- 그렇다면 왜 그것들을 겹치지 말고 서로 잘 맞습니까? 그래서 세 번째 div -left : 35px; 그들이 지금 같은 기준을 가지고 있는지 확인하기 위해 ?

이제 우리는 첫 번째 요점이 증명되었습니다.

  • 두 번째 요점

글쎄, 첫 번째 점에 대한 설명 후에 두 번째 점은 쉽게 소화 할 수 있으며 오버플로 속성이 표시 (숨김) 이외로 설정된 첫 번째 div는 선의 기준선에서 아래쪽 여백이 있음을 알 수 있습니다.

이제 몇 가지 실험을 통해 더 자세히 설명 할 수 있습니다.

  1. 첫 번째 div overflow : visible을 설정하십시오 (또는 완전히 제거하십시오) .
  2. visible 이외의 두 번째 div overflow를 설정하십시오 .
  3. visible 이외의 두 div overflow를 설정하십시오 .

이제 혼란을 다시 가져오고 모든 것이 잘 보이는지 확인하십시오.

  1. 떠 다니는 div를 가져 오십시오 (물론
    몸의 너비 를 늘려야 함) 효과가 없습니다.
  2. 동일한 홀수 마진을 다시 가져옵니다 .
  3. 설정 오버 플로우 녹색 사업부 : 보이는 당신은 귀하의 질문에 설정된 (오정렬 그래서 만약 5px하는 1 x 1 픽셀에서 테두리 너비의 증가 때문이라고 부정적인 왼쪽 조정 이 더 문제가없는 볼 수 있습니다)
  4. 이제 내가 이해하는 데 도움에 추가 추가 문자를 제거합니다 . (물론 부정적인 왼쪽을 제거하십시오)
  5. 마지막으로 몸 폭을 줄일 수 없습니다 우리는 더 이상 하나의 넓은 필요가 있기 때문이다.

그리고 이제 우리는 처음부터 시작했습니다.

잘만되면 나는 당신의 질문에 대답했습니다.


1
이러한 훌륭한 설명에 감사하지만 "그 기준선이 포함 된 블록의 기준선이 될 것"이라는 요점을 얻지 못했습니다. 두 번째 요점에서 명확히 한 것처럼 선의 기준선과 동일합니까?
Shawn Taylor

2
늦은 답장. 방금 동일한 문제를 언급했으며 NICE 설명에 게리 Lindahl에게 감사를 표하고 싶었습니다.
TimSPQR

: 나는 좋은 답변을 주셔서 감사합니다 비록 한 ntgCleaner는 게리 린달의 많은 읽을하고 'XY 솔루션'라는 곳 난 그냥 그 몇 줄을 잃었 너무입니다
기본 코더

이 자세한 설명이 믿을 수 없을만큼 유익하다는 것을 알았습니다. 감사합니다. 나는 한 가지 개념으로 잠시 어려움을 겪었고 다른 사람들을 명확히 할 수 있는 업데이트 된 바이올린 을 만들었 습니다.
jonsanders101

@ntgCleaner 고마워 .. 모든 설명 후에도 나는 그것을 작동시킬 수 없었다. 하지만 당신의 의견은 :)
supersan

330

기본값 vertical-align에서 CSS입니다 baseline및이 규칙도 함께 적용되어 inline-block이 글을 읽을 http://www.brunildo.org/test/inline-block.html

vertical-align:top당신의 inline-blockDIV에 쓰 십시오 .

이것을 확인하십시오 http://jsfiddle.net/WGCyu/1/


3
내 질문을 읽었습니까? 나는 문제를 해결하도록 요구하지 않았다.
Shawn Taylor

23
@ShawnTaylor : 질문 제목이 매우 잘못되었습니다. 본능적으로 제목을 읽은 다음 코드가 있으면 쏴보십시오. 우리는 실제 텍스트를 거의 읽지 않습니다. 나쁜 습관이지만 왜 그런지 이해해야 할 것입니다. : P
Purag

@sandeep : 편집과 관련하여 firstDiv가 수직 정렬이 제거 된
Shawn Taylor

@sandeep : 당신이 제공하는 링크 정보이지만의 동작 설명 아니에요 이후이 질문에 대한 도움말을하지 않는 display:inline-block결합을 float:left/right.
Zeta

2
@ThomasMcCabe 거의; 다른 사람이 나쁜 답변을 게시하면 좋은 의도와 상관없이 향후 시청자에게 문제가 있음을 알리기 위해 하향 투표를 받아야합니다. 즉, 나는이 답변에 공감대가 있다고 생각하지 않습니다. 원래 형태로도 허용 된 답변으로 생략 된 핵심 퍼즐 조각을 제공했습니다. 기준선 정렬이 요소를 수직으로 정렬하는 유일한 방법은 아니며 vertical-align속성 을 변경하면 속성에 변경 되는 복잡성이 없습니다. 허용 된 답변이 적용됩니다.
Mark Amery


9

보기 대안 예. 이러한 동작의 이유는 CSS3 모듈 : line : 3.2에 설명되어 있습니다. 라인 박스 포장 [1] :

일반적으로 라인 박스의 시작 가장자리는 포함 블록의 시작 가장자리에 닿고 끝 가장자리는 포함 블록의 끝 가장자리에 닿습니다. 그러나 플로팅 상자는 포함하는 블록 가장자리와 선 상자 가장자리 사이에있을 수 있습니다. 따라서, 동일한 인라인 포맷팅 컨텍스트의 라인 박스는 일반적으로 동일한 인라인 진행률 (포함 블록의 인라인 진행률)을 갖지만, 플로트로 인해 사용 가능한 인라인 진행 공간이 줄어들면 다를 수 있습니다 [...]

보시다시피, 세 번째 요소는 overflow속성 이 없지만 아래쪽으로 밀 립니다. 이유는 다른 곳에서 찾아야합니다. 두 번째 동작은 Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) 사양 : 9.5 Floats [2]에 설명되어 있습니다 .

플로트가 흐름에 없기 때문에 플로트 상자 전후에 생성 된 배치되지 않은 블록 상자는 플로트가없는 것처럼 수직으로 흐릅니다. 그러나 플로트 옆에 생성 된 현재 및 후속 라인 상자는 플로트의 여백 상자를위한 공간을 만들기 위해 필요한만큼 줄어 듭니다.

귀하의 모든 display:inline-block;div의 특별한 종류의를 사용하고 baseline,이 경우에는 10.8 라인 높이 계산 다음 '라인 높이'와 '수직 정렬의 속성 (매우 끝) [3] :

'inline-block'의 기준선은 유입 흐름 선 상자가 없거나 'overflow'속성에 'visible'이외의 계산 된 값이없는 경우 일반 흐름에서 마지막 선 상자의 기준선입니다. 이 경우 기준선은 아래쪽 여백 가장자리입니다.

따라서 부동 요소 및 inline-block요소를 사용하는 경우 부동 요소가 옆으로 밀리고 인라인 형식이 1 에 따라 다시 계산됩니다 . 반면에 다음 요소는 적합하지 않으면 줄어 듭니다. 이미 최소한의 공간으로 작업하고 있으므로 요소를 수정 한 다음 밀어 넣을 수있는 다른 방법은 없습니다 2 . 이 경우 가장 높은 요소는 줄 바꿈 div의 크기를 정의하여 baseline 3 을 정의하는 반면, 2에 명시된 위치 및 너비의 수정은 최소 간격의 최대 높이 요소에 적용 할 수 없습니다. 이 경우 첫 번째 데모에서와 같은 동작이 발생합니다.

마지막으로, 섹션 11 에서 이유를 찾을 수는 없지만 귀하의 overflow:hidden의지가 귀하 #firstDiv의 아래쪽 가장자리로 밀리지 #container않는 이유는 무엇 입니까 ? overflow:hidden그것이 없으면 23에 의해 정의되고 정의 된대로 작동합니다 . 데모

TL; DR : W3 권장 사항과 브라우저의 구현에 대해 자세히 살펴보십시오. 내 소견에서 떠 다니는 요소는 주변 요소에 대한 모든 변경 사항을 모르는 경우 예기치 않은 동작을 나타내는 것으로 결정됩니다. 다음 은 수레에 대한 일반적인 문제를 보여주는 또 다른 데모 입니다.


3
이 "표준"은 믿을 수없는 혼란입니다. 그들이 브라우저에서 일관성을 유지하도록 할 수 있었다는 것이 놀랍습니다. 아 잠깐만 요, 그들은 그렇게 할 수 없었습니다.
Triynko

6

나는 원래이 질문 에 대답하기 시작 했지만 끝내기 전에 속임수로 잠겨 있으므로 대신 여기에 답변을 게시하십시오.

먼저, 무엇인지 이해해야합니다 inline-block. MDN
정의 는 다음과 같습니다.

이 요소는 마치 하나의 인라인 상자 인 것처럼 주변 내용과 함께 흐를 블록 요소 상자를 생성합니다 (대체 된 요소와 매우 유사한 동작)

여기서 무슨 일이 일어나고 있는지 이해하려면를 살펴보고 vertical-align기본값입니다 baseline.

수직 위치 시각화
이 그림에는 다음과 같은 컬러 차트가 있습니다.
파란색 : 기준선
빨간색 : 선 높이
의 위쪽 및 아래쪽 녹색 : 인라인 내용 상자의 위쪽 및 아래쪽

#left 요소에는베이스 라인을 제어하는 ​​텍스트 내용이 있습니다. 이것은 내부 텍스트가 #left의 기준을 정의한다는 것을 의미합니다.
# 오른쪽에는 콘텐츠가 없으므로 브라우저는 상자 하단을 기준으로 사용하는 것 외에 다른 옵션이 없습니다.

첫 번째 인라인 컨테이너에 텍스트가 있고 다음이 비어있는 예제에서 기준을 그린이 시각화를 참조하십시오.

그려진 기준선

하나의 요소를 맨 위에 정렬하면 실제로이 요소의 맨 위를 선 상자의 맨 위에 정렬한다고 말합니다.

예를 들어 이해하기가 더 쉬울 수 있습니다.

div {
    display: inline-block;
    width: 100px;
    height: 150px;
    background: gray;
    vertical-align: baseline;
}
div#middle {
    vertical-align: top;
    height: 50px
}
   
div#right {
    font-size: 30px;
    height: 100px
}
<div id="left">
  <span>groovy</span>
</div>
<div id="middle">groovy</div>

<div id="right">groovy</div>

결과는 다음과 같습니다. 그리고 파란색 기준선과 빨간색 선 상자를 추가했습니다. 여기서 발생하는 것은 선 상자의 높이가 전체 선의 내용이 어떻게 배치되는지에 달려 있다는 것입니다. 즉, 상단 정렬을 계산하려면 먼저 기준 정렬을 계산해야합니다. 소자 가지고 있으므로이 기준 위치 결정에 사용되지 않는다. 그러나 과 수직이므로 그 기준선이 정렬되도록 위치된다. 이 작업을 수행하면 글꼴 크기가 더 커져서 요소가 약간 위로 밀려 있기 때문에 행 상자의 높이가 증가했습니다 . 그런 다음 요소 의 상단 위치를 계산할 수 있으며 이것은 선 상자의 상단을 따릅니다.수직 정렬 설명
#middlevertical-align:top#left#right#right#middle


1

문제는 두 번째 div에 float : left를 적용했기 때문입니다. 두 번째 div가 왼쪽에 오게하고 첫 번째 div가 떨어지고 두 번째 div 뒤에옵니다. 첫 번째 div에 float : left를 적용하면 문제가 사라집니다.

overflow : hidden은 레이아웃에 문제를 일으키지 않습니다. overflow : hidden은 div의 내부 요소에만 영향을 미치며 외부의 다른 요소와는 아무런 관련이 없습니다.


float div 다음에 두 번째로 나오기 때문에 푸시되면 왜 thirdDiv가 아래로 내려 가지 않습니까?
Shawn Taylor

왜냐하면 세 번째 div에는 float : left가없는 두 번째 div가 있기 때문입니다.
Pal Singh

그러나이 규칙은 일부 div가 부동 div 뒤에 올 경우 아래로 떨어질 것이라고 언급 한 곳은 어디입니까? w3.org를 확인했습니다.
Shawn Taylor

베이스 라인과 경우에 방울을 떠되지 않는 요소는 내가 그것을 가장 논리적 인 대답이라고 말을해야보다 반대 투표를했던
래 싱

아니요, 부정 투표하지 않았습니다. 예, 귀하의 답변에 부정적 가치가 없습니다. 그냥 위로 투표했다.
Shawn Taylor

0

padding:0;본문에 추가 하고 div의 여백을 제거하십시오.

background-color:*any차이를 확인하려면 배경 * 이외의 색상을 추가하십시오 .


형식 코드에 대한 답변 편집 코드를 시작하기 전과 코드를 종료 한 후`기호를 추가하여 코드의 서식을 지정할 수 있습니다. code예 를 들면 다음 과 같습니다. background-color:any color
지노 샤지

0

모든 Elements의 모든 CSS 속성을 동일하게 만드십시오.

비슷한 문제가 있었고이를 수정하는 동안 Font 속성을 가진 Element를 Div Element에 드롭하고 있음을 확인했습니다.

해당 요소를 글꼴 속성으로 삭제 한 후 모든 DIV의 정렬이 방해되었습니다. 이 문제를 해결하기 위해 Font 속성을 모든 DIV 요소에 드롭 된 요소와 동일하게 설정했습니다.

다음 예제에서 font.size : 30 px로 정의 된 ".dldCuboidButton"클래스의 Dropped 요소

그래서 DIV 요소에 사용되는 나머지 클래스, 즉 .cuboidRecycle, .liCollect, .dldCollect에 동일한 속성을 추가했습니다. 이런 식으로 모든 DIV 요소는 요소를 요소에 놓기 전후에 동일한 측정을 따릅니다.

.cuboidRecycle {
    height:40px; 
    width:'20px; float:right';
    overflow:'none';
    background-color:#cab287;
    color:#ffffff; 
    border-radius:8px; 
    text-align:'center'; 
    vertical-align:'top';
    display: inline-block;
    font-size: 30px; /* Set a font-size */
}


.liCollect {
    height:40px; 
    width:'20px; float:right';
    overflow:'none';
    background-color:#cab287;
    color:#ffffff; 
    border-radius:8px; 
    text-align:'center'; 
    vertical-align:'top';
    display: inline-block;
    font-size: 30px; /* Set a font-size */
}

.dldCollect {
    height:40px; 
    width:'20px; float:right';
    overflow:'none';
    background-color:#009933;
    color:#ffffff; 
    border-radius:8px; 
    text-align:'center'; 
    vertical-align:'top';
    display: inline-block;
    font-size: 30px; /* Set a font-size */
}


.dldCuboidButton {
    background-color:  #7c6436;
    color: white; /* White text */
    font-size: 30px; /* Set a font-size */
    border-radius: 8px;
    margin-top: 1px;
  }

다음은 위 CSS를 사용하여 동적으로 생성 된 HTML의 예입니다.

$("div#tabs").append(
  "<div id='" + newTabId + "'>#" + uniqueId + 
  "<input type=hidden id=hdn_tmsource_" + uniqueId + "  value='" + divTmpfest + "'>" + 
  "<input type=hidden id=leCuboidInfo_" + uniqueId + " value=''>" + 
  "<div id='" + divRecycleCuboid + "' class=cuboidRecycle ondrop='removeDraggedCuboids(event, ui)'  ondragover='allowDrop(event)'><font size='1' color='red'> Trash bin </font></div>" +
  "<div id='" + divDropLeCuboid  + "' class=liCollect ondrop='dropForLinkExport(event)'  ondragover='allowDrop(event)'><font size='1' color='red'>Drop Template Manifest Cuboid here</font></div>" +
  "<div id='" + divDropDwldCuboid  + "' class=dldCollect ondrop='dropForTMEntry(event)'  ondragover='allowDrop(event)'><font size='1' color='red'>Drop Template Cuboids here..</font></div>" +
  "</div>" 
);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.