CSS에서 여백 / 패딩 백분율이 항상 너비에 대해 계산되는 이유는 무엇입니까?


130

CSS box model spec 을 보면 다음을 관찰 할 수 있습니다.

[여백] 백분율은 생성 된 상자의 포함 블록 너비 와 관련하여 계산됩니다 . 이것은 '여백 상단'과 '여백 하단'에도 적용됩니다. 포함하는 블록의 너비가이 요소에 의존하는 경우 결과 레이아웃은 CSS 2.1에서 정의되지 않습니다. (강조 광산)

이것은 사실입니다. 그런데 ? 지구상에서 이런 식으로 디자인하도록 강요하는 것은 무엇입니까? 원하는 경우, 페이지 상단에서 항상 25 % 아래로 내려가는 시나리오를 생각하기는 쉽지만, 세로 패딩을 가로 크기에 상대적으로 맞추려는 이유는 찾기 어렵습니다. 부모.

다음은 제가 언급 한 현상의 예입니다.

<div style="border: 1px solid red; margin: 0; padding: 0; width: 200px; height: 800px;">
  This div is 200x800.
  <div style="border: 1px solid blue; margin: 10% 0 0 10%;">
    This div has top-margin of 10% and left-margin of 10% with respect to its parent.
  </div>
</div>

http://jsfiddle.net/8JDYD/


3
저의 초기 생각은 그것이 margin: 25%실제로 무엇 을 의미 하는지 모호하게 만들 것 입니다. 코드에서 제안 했더라도 짝수 마진이 아닙니다. 나는 이것을 뒷받침 할 증거가 없지만 합리적인 것으로 보인다.
Ryan Kinal

4
내 생각의 jsFiddle . 높이는 너비보다 훨씬 더 변경 가능하므로 내용이 변경 될 때마다 여백을 예측하기 어려운 방식으로 변경합니다.
RichardTowers 2016 년

1
@Ryan : 그것은 사실이지만, 여백이 아닐 수도 있지만, 다시 한 번 height: 10%; width: 10%사각형 요소를 얻지 못한다고 말하면 .
mqp 2016 년

4
에 따르면 dev.w3.org/csswg/css3-box/#the-margin-properties 이 상태 Note that in a horizontal flow, percentages on ‘margin-top’ and ‘margin-bottom’ are relative to the width of the containing block, not the height (and in vertical flow, ‘margin-left’ and ‘margin-right’ are relative to the height, not the width).는 두 가지를 간다 그래서
아담 스위니에게

1
@Ryan 나는 우리가 승자라고 생각한다. 꾼 여기 데모 - jsFiddle
RichardTowers

답변:


60

논리적으로 이해하기 때문에 내 의견을 답변에 전달합니다. 그러나 이것은 근거가없는 추측이라는 점에 유의하십시오. 스펙이 이런 식으로 작성된 이유에 대한 실제 추론은 여전히 ​​기술적으로 알려지지 않았습니다.

요소 높이는 자식의 높이로 정의됩니다. 요소에 padding-top : 10 % (부모 높이 기준)가있는 경우 부모 높이에 영향을줍니다. 자녀의 키는 부모의 키에 의존하고 부모의 키는 자녀의 키에 의존하기 때문에 키가 부정확하거나 무한 루프가 생깁니다. 물론 이것은 offset parent === parent 인 경우에만 영향을 주지만 여전히 영향을 미칩니다. 해결하기 어려운 경우입니다.

업데이트 : 마지막 몇 문장이 완전히 정확하지 않을 수 있습니다. 리프 요소 (자식이없는 자식)의 높이는 그 위에있는 모든 요소의 높이에 영향을 미치므로 여러 상황에 영향을 미칩니다.


1
이 규칙에는 예외가 있습니다-CSS2.1의 섹션 10.6은 다양한 유형의 상자에 대한 높이 계산의 거의 모든 인스턴스를 다룹니다. 실제로, 부모와 자녀 사이의 키 의존성이 관련된 사례는 정의되지 않은 행동을 유발하는 경향이 있습니다.
BoltClock

1
@sanjaypoyzer 가장 간단한 경우 브라우저는 외부에서 블록 너비를 계산하고 (루트에서 끝까지) 그런 다음 블록에 내용을 흘려서 높이를 결정합니다 (팁에서 루트까지).
sam

9
왜 W3C가 지속적으로 이것을 하는가? 분명히 W3C에 대한 '의미 적'은 논리적으로 생각할 수없는 사람들에게 음식을 제공하는 것과 같습니다. 세상에서 혼란스럽고 멍청한 사람들이 얼마나 혼란스럽고 더 혼란스럽고 어리석게 퍼지는 지 불평하는 것과 같습니다. 당신이 제공 한 추론은 의미가 없습니다. 같은 주장이 너비에도 적용되지만 잘 작동합니다. 부모의 높이가 픽셀 또는 불변으로 설정되지 않는 한 높이가 결정되는 컨텍스트와 방향을 설정하는 것만으로도 문제가 없습니다.
u353

3
그 의존도는 솔루션을 제공 할 것 대수 공식은 없습니다 당신이 존중하지 않는 방법으로 그것을 해결하기 위해 선택하지 않는 무한 루프가 발생할. 부모의 키가 h_p입니다. 패딩 상단이 10 %이면 자식의 높이가됩니다 h_c = h_ci + 0.1h_p. 여기서 자식 h_ci의 내부 높이는 부모 키에 의존하지 않습니다. 한 자녀의 경우 방정식 h_p = h_ci + 0.1h_p=> 에서 부모 높이를 간단히 찾을 수 h_p = h_ci / 0.9있습니다. 자녀 수에 관계없이 패딩이 다를 때에도 항상 이렇게 할 수 있습니다. 하나의 미지수 ( h_p)와 하나의 방정식입니다.
jeteon

2
나는 무한 계산이 이유라고 생각하지 않습니다. 간단한 이유는 다음과 같습니다. 사용 width하면 동일한 문제가 수평으로 발생합니다.
Joy

30

"N %"마진 (패딩)가되기 위해서는 동일한 마진 정상 / 마진 / 오른쪽 마진 바닥 / 왼쪽 마진에 대한 4 개의 모든 동일한 기지국에 대하여해야한다. 상단 / 하단이 왼쪽 / 오른쪽 '과 다른 기준을 사용하는 경우 "n %"여백 (및 패딩)이 모든면에서 동일한 것을 의미하지는 않습니다.

( 너비 와 관련하여 상단 / 하단 여백을 가지면 상자 크기를 조정하더라도 종횡비가 변하지 않는 상자를 지정할 수있는 이상한 CSS 해킹이 가능합니다.)


... 놀랍게도 간단한 대답. 위의 모든 추측에는 장점이 있지만 이것은 꽤 좋은 지적입니다. 여러 솔루션이 정확할 수 있으므로 아마도 가장 많이 사용되는 솔루션을 선택했을 것입니다.
dudewad

1
나는 당신이 say라고 쓸 수 있도록 문법에 여분의 요소를 갖는 것이 좋을 것이라고 생각합니다 padding: n [type]. 따라서 이전 버전과의 호환성을 위해 두 번째 매개 변수가 기본적으로 "width" padding: 5% logical로 설정되는 것과 반대로 (OP에서 제안하는 것)을 갖게 padding: 5% width됩니다.
jeteon

5
"n % 마진 (및 패딩)이 모든면에서 동일한 것을 의미하지는 않습니다."-왜 이것이 문제가 될까요?
Herbertusz

4

JSFiddle (Chrome 46.0.2490.86)을 가지고이 게시물 (중국어로 작성 )을 언급 한 후 @ChuckKollars의 답변에 투표합니다 .


대하여 주원인 무한 계산 하여이 : 추측이다 width동일한 대향 무한 계산 문제.

JSFiddle을 살펴보십시오 . parent디스플레이는 inline-block여백 / 패딩을 정의 할 수 있습니다. 는 child마진 값을 갖는다 20%. 우리가 무한 계산 추측을 따르면 :

  1. 의 너비 childparent
  2. 의 너비 parentchild

그러나 결과적으로 Chrome은 계산을 중단하고 결과는 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

JSFiddle에서 "결과"패널을 가로로 확장하려고하면 너비가 변경되지 않습니다. 의 내용 child두 줄 (한 줄이 아님)로 묶여있는 이유는 무엇입니까? Chrome이 어딘가에 하드 코딩 한 것 같습니다. child더 많은 콘텐츠를 만들기 위해 콘텐츠를 편집하면 ( JSFiddle ) 가로로 여유 공간이 있으면 Chrome에서 콘텐츠를 두 줄로 유지합니다.

그래서 우리는 볼 수 있습니다 : 무한 계산을 막는 방법이 있습니다.


나는이 디자인이 단지 동일한 측정에 기초하여 네 개의 마진 / 패딩 값을 유지하는 것이라고 추측에 동의한다.

이 게시물 (중국어로 작성)은 또 다른 이유를 제시합니다. 그것은 읽기 / 조판의 방향 때문입니다. 너비가 고정되고 높이가 무한대로 (가상) 위에서 아래로 읽습니다.


웹 페이지는 일반적으로 무한한 방향으로 세로로 스크롤되기 때문입니다. 브라우저 창의 너비에서 너비를 계산할 수 있습니다. 화면보다 요소가 더 넓은 유일한 방법은 너비를 더 크게 지정하는 것입니다. 일반적인 블록 요소는 너비가 100 %이며 세로 방향으로 자동 확장됩니다 (알 수 없음). 이것이 너비에 동일한 문제가없는 이유입니다.
Lucent Fox

3

OP가 CSS 사양에서 상단 / 하단 여백 백분율을 너비의 백분율 (높이가 아닌 것으로 가정)로 정의 하는지 묻는 것을 알고 있지만 잠재적 인 솔루션을 게시하는 것이 유용 할 수도 있다고 생각했습니다.

대부분의 최신 브라우저는 이제 vw 및 vh를 지원하므로 뷰포트 너비 및 뷰포트 높이에 대해 여백 번호를 지정할 수 있습니다.

100vw / 100vh는 스크롤바가없는 경우 100 % 너비 / 100 % 높이 (각각)입니다. 스크롤 막대가 있으면 뷰포트 번호가이를 설명하지 않습니다 (% 숫자는). 고맙게도 거의 모든 브라우저가 17px의 스크롤 막대 크기를 사용하므로 ( here 참조 ) CSS 계산 기능을 사용하여이를 해결할 수 있습니다. 스크롤 막대의 표시 여부를 모르면이 솔루션이 작동하지 않습니다.

예를 들어, 가로 스크롤 막대가없는 경우 (높이의 50 % 인 여백) "margin-top : 50vh;"로 정의 할 수 있습니다. 가로 스크롤 막대를 사용하면 "margin-top : calc (0.5 * (100vh-17px))"; (calc의 빼기 및 더하기 연산자에는 양쪽에 공백이 필요합니다!).


1
많은 경우에 유용한 해결 방법이지만, 작동하지 않는 많은 예제가 있습니다 (예 : 컨텐츠를 사용 가능한 공간을 채우기 위해 커지는 flexbox 컨테이너의 크기에 비례하여 다른 상자가있는 경우) 가변 콘텐츠).
Jules
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.