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. 의 너비 child는parent
  2. 의 너비 parent는child

그러나 결과적으로 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.