Jika Anda melihat spec model kotak CSS , Anda akan mengamati yang berikut:
Persentase [margin] dihitung sehubungan dengan lebar blok berisi kotak yang dihasilkan. Perhatikan bahwa ini juga berlaku untuk 'margin-top' dan 'margin-bottom'. Jika lebar blok yang mengandung tergantung pada elemen ini, maka tata letak yang dihasilkan tidak terdefinisi dalam CSS 2.1. (penekanan milikku)
Ini memang benar. Tapi mengapa ? Apa yang akan memaksa orang untuk mendesainnya dengan cara ini? Sangat mudah untuk memikirkan skenario di mana Anda inginkan, misalnya hal tertentu untuk selalu turun 25% dari bagian atas halaman, tetapi sulit untuk datang dengan alasan mengapa Anda ingin bantalan vertikal relatif terhadap ukuran horizontal dari orang tua.
Berikut adalah contoh dari fenomena yang saya maksudkan:
<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%
sebenarnya. Itu tidak akan menjadi margin yang genap, meskipun kode menunjukkan itu. Saya tidak punya bukti untuk mendukung ini, tetapi tampaknya masuk akal.height: 10%; width: 10%
Anda tidak akan mendapatkan elemen persegi juga.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).
Jadi berjalan dua arahJawaban:
Mentransfer komentar saya ke jawaban, karena itu masuk akal. Namun, harap dicatat bahwa ini adalah dugaan yang tidak berdasar. Alasan sebenarnya mengapa spec ditulis dengan cara ini masih, secara teknis, tidak diketahui.
Pembaruan: Kalimat pasangan terakhir mungkin tidak sepenuhnya akurat. Ketinggian elemen daun (anak tanpa anak) memiliki efek pada ketinggian semua elemen di atasnya, jadi ini mempengaruhi banyak situasi yang berbeda.
sumber
h_p
. Bagian atas padding 10% akan membuat anak tinggih_c = h_ci + 0.1h_p
, di manah_ci
tinggi bagian dalam anak dan tidak tergantung pada tinggi orangtua. Untuk satu anak Anda cukup menemukan tinggi orangtua dari persamaanh_p = h_ci + 0.1h_p
=>h_p = h_ci / 0.9
. Anda selalu dapat melakukan ini, tidak peduli berapa banyak anak yang Anda miliki, bahkan untuk lapisan yang berbeda. Hanya satu yang tidak diketahui (h_p
) dan satu persamaan.width
hasil dalam masalah yang sama secara horizontal.Agar margin "n%" (dan padding) sama dengan margin-atas / margin-kanan / margin-bawah / margin-kiri, keempatnya harus relatif terhadap basis yang sama. Jika atas / bawah menggunakan basis berbeda dari kiri / kanan ', maka margin "n%" (dan bantalan) tidak akan berarti hal yang sama di keempat sisi.
(Perhatikan juga bahwa margin atas / bawah relatif terhadap lebar memungkinkan peretasan CSS aneh yang memungkinkan Anda untuk menentukan kotak dengan rasio aspek yang tidak berubah ... bahkan jika kotak tersebut diperbesar ulang.)
sumber
padding: n [type]
. Jadi Anda akan memilikipadding: 5% logical
(apa yang OP sarankan) sebagai lawanpadding: 5% width
dengan parameter kedua default ke "width" untuk kompatibilitas mundur.Saya memilih jawaban dari @ChuckKollars setelah bermain dengan ini JSFiddle (di Chrome 46.0.2490.86) dan merujuk ke posting ini (ditulis dalam bahasa Cina).
Alasan utama menentang dugaan perhitungan tak terbatas adalah bahwa: menggunakan
width
menghadapi masalah perhitungan tak terbatas yang sama .Lihat JSFiddle ini ,
parent
layarnyainline-block
, yang memenuhi syarat untuk menentukan margin / padding di atasnya. Thechild
memiliki nilai marjin20%
. Jika kita mengikuti dugaan perhitungan tak terbatas :child
tergantung padaparent
parent
tergantung padachild
Tetapi sebagai hasilnya, Chrome menghentikan perhitungan di suatu tempat, menghasilkan:
Jika Anda mencoba memperluas panel "hasil" secara horizontal di JSFiddle, Anda akan menemukan bahwa lebar mereka tidak akan berubah. Harap perhatikan bahwa konten dalam
child
terbungkus menjadi dua baris (bukan, katakanlah, satu baris), mengapa? Saya kira Chrome hanya menuliskannya di suatu tempat. Jika Anda mengeditchild
konten untuk membuatnya lebih ( JSFiddle ), Anda akan menemukan bahwa selama ada ruang tambahan secara horizontal, Chrome menyimpan konten dua baris.Jadi kita bisa melihat: ada beberapa cara untuk mencegah perhitungan yang tak terbatas .
Saya setuju dengan dugaan bahwa: desain ini hanya untuk menjaga empat nilai margin / padding berdasarkan ukuran yang sama.
posting ini (ditulis dalam bahasa Cina) juga mengusulkan alasan lain adalah bahwa: itu karena orientasi membaca / mengeset. Kita membaca dari atas ke bawah, dengan lebar tetap dan tinggi tak terbatas (sebenarnya).
sumber
Saya menyadari OP bertanya mengapa spesifikasi CSS mendefinisikan persentase margin atas / bawah sebagai% dari lebar (dan tidak, seperti yang akan diasumsikan, tinggi), tapi saya pikir itu mungkin juga berguna untuk memposting solusi potensial.
Sebagian besar browser modern mendukung vw dan vh sekarang yang memungkinkan Anda menentukan angka margin terhadap lebar viewport dan tinggi viewport.
100vw / 100vh sama dengan 100% lebar / tinggi 100% (masing-masing) jika tidak ada scrollbar; jika ada bilah gulir, nomor viewport tidak menjelaskan hal ini (sementara% angka melakukannya). Untungnya, hampir semua browser menggunakan ukuran scrollbar 17px ( lihat di sini ), sehingga Anda dapat menggunakan fungsi css calc untuk menjelaskan hal ini. Jika Anda tidak tahu apakah bilah gulir akan muncul atau tidak, maka solusi ini tidak akan berfungsi.
Sebagai contoh: Dengan asumsi tidak ada scrollbar horizontal, margin atas 50% tinggi, dapat didefinisikan sebagai "margin-top: 50vh;". Dengan scrollbar horizontal, ini dapat didefinisikan sebagai "margin-top: calc (0,5 * (100vh - 17px));" (ingat bahwa operator minus dan plus di calc membutuhkan ruang di kedua sisi!).
sumber