Jeśli spojrzysz na specyfikację modelu pudełkowego CSS , zauważysz, co następuje:
Procent [marginesu] jest obliczany w odniesieniu do szerokości bloku zawierającego wygenerowane pudełko. Zauważ, że dotyczy to również „margin-top” i „margin-bottom”. Jeśli szerokość zawierającego bloku zależy od tego elementu, to wynikowy układ jest niezdefiniowany w CSS 2.1. (podkreślenie moje)
To jest rzeczywiście prawda. Ale dlaczego ? Co u licha zmusiłoby kogoś do zaprojektowania tego w ten sposób? Łatwo jest wymyślić scenariusze, w których chcesz, np. Pewna rzecz zawsze znajduje się 25% w dół od góry strony, ale trudno jest wymyślić jakikolwiek powód, dla którego chcesz, aby dopełnienie pionowe było względem poziomego rozmiaru rodzic.
Oto przykład zjawiska, do którego się odnoszę:
<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>
margin: 25%
właściwie oznacza. Nie byłby to równy margines, mimo że kod sugeruje, że tak. Nie mam dowodów na poparcie tego, ale wydaje się to rozsądne.height: 10%; width: 10%
, że nie dostaniesz też elementu kwadratowego.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).
że to idzie w obie stronyOdpowiedzi:
Przeniesienie mojego komentarza do odpowiedzi, bo ma to logiczny sens. Należy jednak pamiętać, że jest to bezpodstawne przypuszczenie. Faktyczne uzasadnienie, dlaczego specyfikacja jest napisana w ten sposób, jest nadal technicznie nieznane.
Aktualizacja: ostatnie kilka zdań może nie być do końca poprawne. Wysokość elementu liścia (dziecko bez dzieci) ma wpływ na wysokość wszystkich elementów nad nim, więc ma to wpływ na wiele różnych sytuacji.
źródło
h_p
. Wypełnienie o wysokości 10% zapewni wzrost dzieckah_c = h_ci + 0.1h_p
, gdzieh_ci
jest to wewnętrzna wysokość dziecka i nie zależy od wzrostu rodzica. W przypadku jednego dziecka po prostu znajdź wysokość rodzica z równaniah_p = h_ci + 0.1h_p
=>h_p = h_ci / 0.9
. Zawsze możesz to zrobić, bez względu na to, ile masz dzieci, nawet w przypadku różnych wypełnień. To tylko jedna nieznana (h_p
) i jedno równanie.width
prowadzi do tego samego problemu w poziomie.Aby margines „n%” (i wypełnienie) był taki sam dla marginesu górnego / prawego marginesu / dolnego marginesu / lewego marginesu, wszystkie cztery muszą odnosić się do tej samej podstawy. Gdyby góra / dół używały innej podstawy niż lewa / prawa, wtedy margines „n%” (i wypełnienie) nie oznaczałby tego samego ze wszystkich czterech stron.
(Zwróć również uwagę, że margines górny / dolny w stosunku do szerokości umożliwia dziwny hack CSS, który pozwala określić pudełko z niezmiennym współczynnikiem proporcji ... nawet jeśli zostanie przeskalowane).
źródło
padding: n [type]
. Tak więc miałbyśpadding: 5% logical
(co sugeruje OP) w przeciwieństwie dopadding: 5% width
drugiego parametru domyślnego na „szerokość” dla kompatybilności wstecznej.Głosuję na odpowiedź od @ChuckKollars po zabawie tym JSFiddle (na Chrome 46.0.2490.86) i odwołaniu się do tego postu (napisanego po chińsku).
Głównym powodem przemawiającym przeciwko hipotezie nieskończonych obliczeń jest to, że: używanie
width
napotyka ten sam nieskończony problem obliczeniowy .Spójrz na ten JSFiddle ,
parent
wyświetlacz jestinline-block
, który może zdefiniować margines / wypełnienie na nim.child
Ma wartość depozytu20%
. Jeśli podążymy za nieskończoną hipotezą obliczeniową :child
zależy odparent
parent
zależy odchild
W rezultacie Chrome gdzieś zatrzymuje obliczenia, w wyniku czego:
Jeśli spróbujesz rozwinąć panel „wynik” w poziomie w JSFiddle, zauważysz, że ich szerokość się nie zmieni. Zwróć uwagę, że zawartość w
child
tagu jest zawinięta w dwa wiersze (nie, powiedzmy, jeden wiersz), dlaczego? Myślę, że Chrome gdzieś go na stałe zakodował. Jeśli edytujeszchild
zawartość, aby była bardziej widoczna ( JSFiddle ), zauważysz, że dopóki jest dodatkowa przestrzeń w poziomie, Chrome zachowuje zawartość w dwóch wierszach.Widzimy więc: istnieje sposób, aby zapobiec nieskończonym obliczeniom .
Zgadzam się z przypuszczeniem, że: ten projekt ma po prostu zachować cztery wartości marginesu / wypełnienia w oparciu o tę samą miarę.
ten post (napisany po chińsku) proponuje również inny powód: wynika to z orientacji na czytanie / skład. Czytamy od góry do dołu, ze stałą szerokością i nieskończoną wysokością (praktycznie).
źródło
Zdaję sobie sprawę, że OP pyta, dlaczego specyfikacja CSS definiuje wartości procentowe górnego / dolnego marginesu jako% szerokości (a nie, jak można by przypuszczać, wysokości), ale pomyślałem, że może być również przydatne opublikowanie potencjalnego rozwiązania.
Większość nowoczesnych przeglądarek obsługuje teraz vw i vh, co pozwala na określenie wartości marginesów względem szerokości i wysokości widoku.
100 vw / 100 vh równa się odpowiednio 100% szerokości / 100% wysokości, jeśli nie ma paska przewijania; jeśli jest pasek przewijania, numery rzutni nie uwzględniają tego (podczas gdy% liczb tak). Na szczęście prawie wszystkie przeglądarki używają paska przewijania o rozmiarze 17 pikseli ( patrz tutaj ), więc możesz to uwzględnić przy użyciu funkcji css calc. Jeśli nie wiesz, czy pojawi się pasek przewijania, czy nie, to rozwiązanie nie zadziała.
Na przykład: Zakładając, że nie ma poziomego paska przewijania, górny margines o wysokości 50% można zdefiniować jako „margin-top: 50vh;”. W przypadku poziomego paska przewijania można to zdefiniować jako „margin-top: calc (0,5 * (100vh - 17px));” (pamiętaj, że operatory minus i plus w kalkulatorze wymagają spacji po obu stronach!).
źródło
Wiem, że to pytanie jest trochę stare, ale chciałbym je odświeżyć w CSS3. Chociaż prawdą jest, że specyfikacja CSS2.1 mówi, że procentowe wypełnienie i marginesy są definiowane w stosunku do szerokości bloku zawierającego, nie zawsze tak jest. To zależy od trybu pisania. Wynika to prosto ze specyfikacji CSS3 :
Omówię to w moim samouczku dotyczącym współczynników proporcji w CSS .
W szczególności znajduje się sekcja dotycząca wypełnienia procentowego w trybach pisania poziomego i pionowego . Domyślnie element ma poziomy tryb pisania, w którym tekst przepływa poziomo (w kierunku „w wierszu”) od lewej do prawej. Jednak używając
writing-mode
właściwości CSS, możesz w rzeczywistości ustawić tryb na pionowy (z tekstem przepływającym od prawej do lewej lub od lewej do prawej). Oto kilka diagramów poziomych i pionowych trybów pisania:Są one zaczerpnięte z dokumentacji MDN dotyczącej trybów pisania .
W pionowych trybach pisania procentowe wypełnienie będzie zależało od wysokości bloku zawierającego, a nie szerokości.
Oto dowód:
.document { writing-mode: vertical-rl; width: 100%; height: 100vh; } .parent { width: 100%; height: 200px; background-color: black; color: white; } .child { padding: 10%; background-color: white; color: black; border: solid 1px; }
<div class="document"> <div class="parent"> <div class="child"> Child </div> </div> </div>
Dziecko otrzymuje 20 pikseli wypełnienia, co stanowi 10% wysokości zawierającego blok (200 pikseli).
Jeśli chodzi o powody, dla których w tym pytaniu, zostało to dobrze omówione w innych postach tutaj.
źródło