Ukuran kotak CSS3: margin-box; Kenapa tidak?

139

Kenapa kita tidak punya box-sizing: margin-box;? Biasanya ketika kita memasukkan box-sizing: border-box;style sheet kita benar-benar berarti yang pertama.


Contoh:

Katakanlah saya memiliki tata letak halaman 2 kolom. Kedua kolom memiliki lebar 50%, tetapi terlihat agak jelek karena tidak ada selokan (celah di tengah); Di bawah ini adalah CSS:

.col2 {
    width: 50%;
    float: left;
}


Untuk menerapkan selokan, Anda mungkin berpikir kami bisa menetapkan margin kanan pada kolom pertama dari 2; sesuatu seperti ini:

.col2:first-child {
    margin-right: 24px;
}

Tetapi ini akan membuat kolom kedua membungkus ke baris baru, karena yang berikut ini benar:

50% + 50% + 24px > 100%

box-sizing: margin-box;akan menyelesaikan masalah ini dengan memasukkan margin dalam lebar elemen yang dihitung. Saya akan menemukan ini sangat berguna jika tidak lebih bermanfaat daripada box-sizing: border-box;.

Desainer web
sumber
30
"Kenapa kita tidak punya box-sizing: margin-box;?" Karena sementara margin horizontal tidak runtuh, proposisi seperti itu akan secara serius mengganggu keruntuhan margin vertikal. Bagaimanapun, jika Anda ingin mengusulkan sesuatu untuk standardisasi, Stack Overflow bukanlah tempat yang tepat. Coba milis.
BoltClock
16
Dalam situasi tertentu, Anda dapat menyiasatinya dengan menggunakan border: xxx solid transparent;, karena perbatasan disertakan border-box. Ini akan merusak beberapa hal lain, seperti box-shadow.
Nathan Osman
28
Apakah kita menutup semua pertanyaan tentang standar sebagai "tidak konstruktif" sekarang ?? Ini adalah pertanyaan yang wajar untuk ditanyakan, dan bahkan memiliki jawaban langsung: kita tidak punya box-sizing: margin-boxkarena tidak akan berfungsi dengan margin-collapse.
thomasrutter
@thomasrutter: Tidak ada alasan yang lebih baik untuk itu pada saat saya menutupnya, yang lebih dari setahun yang lalu. Ngomong-ngomong, "tidak konstruktif" sudah hilang sekarang (artinya tidak, kami tidak benar-benar menutup sesuatu yang tidak konstruktif lagi), dan karena keseluruhan "Saya punya ide, beginilah cara kerjanya, mari kita buat ini menjadi standar!" sesuatu telah dihapus sejak terakhir kali ditutup sekarang sebenarnya terdengar seperti praktis "mengapa X tidak bisa bekerja?" pertanyaan. Ini masih merupakan pertanyaan yang sangat spekulatif (alasan saya di atas sebenarnya tidak lebih dari sebuah tebakan yang terpelajar), tetapi saya tidak akan berkomentar lebih jauh tentang itu.
BoltClock
mengapa tidak hanya memiliki inner-wrap / div jika Anda ingin spasi: codepen.io/chriscoyier/pen/eGcLw
ashley

Jawaban:

55

Tidak bisakah kamu gunakan width: calc(50% - 24px);untuk cols kamu? Kemudian atur margin Anda.

Membungkuk
sumber
5
Ini sangat tergantung pada browser. Mungkin sekitar tahun 2020, ie15 akan mendukungnya dan Anda akan diizinkan untuk menggunakannya dalam pekerjaan Anda juga :-(
peterh - Reinstate Monica
1
Tampaknya tidak berfungsi dengan baik di Firefox? (atau sesuatu yang saya lakukan tidak)
Laurengineer
@ Morgan Feeney: Ya, tapi ukuran kotak tidak memiliki nilai yang disebut margin-box (yang merupakan inti dari pertanyaan ini). Bahkan jika nilai seperti itu diperkenalkan sekarang, bagaimana Anda mengusulkan patching / polyfilling / shimming ke browser yang ada?
BoltClock
Ya tapi ... secara khusus menanggapi jawaban yang menyarankan calc () sebagai solusi.
Morgan Feeney
Tidak yakin apakah ini berlaku untuk contoh spesifik tetapi negatif utama untuk menggunakan calc () dalam skenario kami (seperti pada FF 53.0.3) adalah bahwa perilakunya tidak analog dengan lebar: X%; Dari apa yang bisa kita lihat "calc" dilakukan pada saat rendering awal ke Xpx statis. Ini berarti bahwa tidak seperti lebar: X%, kolom yang dihitung tidak mengubah ukuran secara otomatis dengan ukuran kontainer.
Pancho
16

Saya pikir kita bisa memiliki box-sizing: margin-box . Model kotak css menunjukkan dengan tepat, apa posisi margin dari frame.

Ada masalah kecil - misalnya, kotak margin bisa tumpang tindih - tetapi mereka tidak sulit untuk dipecahkan.

Saya pikir, situasinya sama, seperti yang bisa kita lihat dengan overflow-x&overflow-y kombinasi, dengan divs posisi absolut dalam sel tabel, dengan kombinasi min | max-width | tinggi dengan ukuran kotak, dan sebagainya.

Ada fitur, fitur yang sangat sederhana, yang tidak dikembangkan oleh pengembang browser.

IMHO, box-sizing: margin-boxadalah fitur yang sangat berguna. Fitur lain yang bermanfaat adalah box-sizing: padding-box, itu ada setidaknya dalam standar, tetapi tidak diterapkan di salah satu browser utama. Bahkan di chrome terbaru!


Catatan: Komentar @Oriol: Firefox menerapkan kotak-ukuran: kotak-padding. Tetapi yang lain tidak, dan itu dihapus dari spec. Firefox akan menghapusnya di versi 50. Sedih.

peterh - Pasang kembali Monica
sumber
2
Firefox memang mengimplementasikan box-sizing: padding-box. Tetapi yang lain tidak, dan itu dihapus dari spec. Firefox akan menghapusnya di versi 50. Sedih.
Oriol
6

Pria di atas bertanya tentang menambahkan margin ke lebar keseluruhan, termasuk padding dan border. Masalahnya, margin diterapkan di luar kotak dan padding dan border tidak, saat digunakanborder-box .

Saya sudah mencoba mencapai border-marginide itu. Apa yang saya temukan adalah bahwa jika menggunakan margin Anda dapat menambahkan kelas .lastke item terakhir (dengan margin, lalu menerapkan margin nol, atau menggunakan:last-child/:last-of-type ). Atau tambahkan margin yang sama sepanjang jalan (mirip dengan versi padding di atas).

Lihat contoh di sini: http://codepen.io/mofeenster/pen/Anidc

border-boxmenghitung lebar elemen + paddingnya + batasnya sebagai total lebar. Jadi jika Anda memiliki 2 divs yang lebar 50%, mereka akan berdekatan. Jika Anda menambahkan 8pxpadding ke mereka, maka Anda akan memiliki selokan 16px. Kombinasikan itu dengan elemen pembungkus - yang juga memiliki bantalan 8px- Anda akan memiliki grid yang ditata dengan baik dengan talang yang sama sepanjang jalan.

Lihat contoh ini di sini: http://codepen.io/mofeenster/pen/vGgje

Yang terakhir adalah metode favorit saya.

Morgan Feeney
sumber
4

Saya yakin semua ini sudah jelas, tetapi saya tetap akan mengetiknya karena ... yah, saya perlu latihan. Apakah hasil berikut tidak akan seefisien box-sizing: margin-box;:

.col2 {
    width: 45%;
    height: 90%;
    margin: 5% 2.5%;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    float: left;
}

http://jsfiddle.net/Fg3hg/

box-sizingdigunakan untuk mengontrol dari titik mana padding dan border dinilai ke ukuran keseluruhan elemen. Jadi walaupun tidak halal untuk memasukkan pxmargin dengan %lebar (seperti biasanya selalu terjadi), lebih mudah untuk menghitung berapa jumlah persentase relatif seharusnya karena Anda tidak harus memasukkan padding dan berbatasan dengan lebar yang ditentukan.

Plummer
sumber
9
Kasus penggunaan untuk sesuatu seperti margin-box adalah untuk memungkinkan pencampuran lebar persentase dengan margin piksel. Jika Anda ingin dua kotak 50% dengan margin 1px di antaranya, ini tidak dapat dicapai dengan persentase margin 1% yang serupa - beberapa ukuran layar kecil akan membulatkan 1% ke 0 piksel dan tiba-tiba Anda tidak memiliki margin. Yang benar-benar kita butuhkan adalah lebih banyak dukungan browser untuk calc () seperti yang ditunjukkan @Slouch, atau model flexbox.
1
Jika itu yang menjadi perhatian, wadah induk akan kurang dari 100px, dan saya berharap beberapa elemen desain akan dipikirkan kembali pada saat itu. Ada beberapa hal lain yang bisa Anda lakukan dengan elemen bersarang dan sejenisnya, tetapi, ya, memiliki perhitungan variabel akan sangat bodoh. Jika Anda suka hal-hal seperti merendahkan atau kurang, saya pikir mereka melakukan banyak hal ini. Saya sudah bermain-main dengan mereka, tetapi saya belum menjadi Jedi.
Plummer
2
Apa yang Anda sarankan adalah bekerja. Ini bukan cara yang ideal untuk menulis CSS saat Anda bekerja dengan tata letak yang rumit. Anda berasumsi bahwa perancang atau penulis ingin menggunakan persentase dalam desain mereka. Juga terlepas dari masalah ini, bahkan jika Anda menggunakan fungsi calc () untuk menghitung spasi menggunakan margin piksel, masih membatasi perancang karena mereka harus menentukan terlebih dahulu apa talang air, daripada membiarkannya ditimpa menggunakan CSS.
limitlessloop
Saya tidak mengerti maksud Anda. Masalah yang dihadapi adalah bahwa memasukkan px dan% menyebabkan jeda baris karena margin tidak termasuk dalam perhitungan ukuran. Margin tidak termasuk dalam ukuran elemen, ini adalah ruang yang ingin Anda tampilkan di sekitar elemen. Plus, bagaimana margin-boxmenangani perhitungan margin multidimensi? @mediabreakpoints, max-widthdan min-widthbekerja dengan baik. Saya kira margin-boxmungkin mengurangi beberapa mengasapi, tetapi saya juga mendapatkan alasan mengapa itu dapat dianggap berlebihan.
Plummer
Mengapa tidak ada yang menyebutkan bahwa margin ini Persentase VALUE adalah persentase lebar untuk beberapa alasan ... tidak masalah tinggi atau lebar. Lebar induk digunakan. Yang aneh untuk sedikitnya ... jadi kode di atas seharusnya tidak berfungsi dan tidak berfungsi. kecuali jika Anda membuat tinggi dan lebar sama.
Muhammad Umer
4

Ini karena atribut ukuran kotak mengacu pada ukuran elemen setelah menghitung nilai dimensi spesifik tertentu (padding, batas). "box-sizing: border-box" mengatur tinggi / lebar elemen dan mempertimbangkan padding serta lebar perbatasan. Lingkup margin elemen lebih besar dari elemen itu sendiri, yang berarti ia memodifikasi aliran halaman dan elemen-elemen di sekitarnya, oleh karena itu secara langsung mengubah cara elemen tersebut cocok di dalam induknya relatif terhadap elemen-elemen saudaranya. Pada akhirnya nilai atribut "margin-box" akan menyebabkan masalah besar dan pada dasarnya sama dengan mengatur tinggi / lebar elemen secara langsung.

Ryan
sumber
1
permintaan maaf saya, tetapi saya tidak mengerti bagaimana memasukkan padding, border, dan margin dalam perhitungan spasial melalui "margin-box" akan berbeda secara konseptual dengan memasukkan padding dan border melalui "border-box". Tentunya itu hanya variasi pada tema yang sama?
Pancho
1

Pada Codrops ada beberapa artikel bagus tentang masalah efek margin dan baris yang dipaksa meluap. Mereka menyarankan menggunakan unit rem atau em dengan normalizer css mengatur ukuran font hingga 100% untuk semua browser, maka ketika Anda mengatur lebar dan margin, mudah untuk melacak efek pada lebar baris hanya dengan membuat catatan di komentar untuk total lebar. Konversi 16px ke 1 em adalah cara untuk menghitung total viewports yang ditargetkan dengan witdh.

Bekerja seperti itu untuk tahap dev setidaknya dan kemudian jika Anda ingin template 'responsif' Anda dapat mengkonversi lebar menjadi% termasuk lebar margin.

Cara lain dan seringkali lebih sederhana yang mereka sarankan untuk menangani talang adalah dengan menggunakan pseudo after dan content: '';pada masing-masing kolom Anda yang saya temukan berfungsi dengan sangat baik. Jika Anda menetapkan kelas div yang merupakan kolom terakhir yang ditentukan seperti akhir, maka Anda dapat menargetkan kelas tersebut untuk tidak memiliki pseudo setelah, atau memiliki yang lebih luas; mana yang paling cocok dengan tata letak Anda.

Bonus tambahan menggunakan metode elemen semu ini adalah juga memberi Anda target untuk bayangan yang dapat memberikan efek lebih 3d dan kedalaman yang lebih besar ke gambar datar pada monitor pembaca juga. Saya sedang bereksperimen dengan efek ini saat ini dengan meningkatkan efek yang digunakan pada tombol, 'mengubah' gradien, dan indeks-z.

Weedy101
sumber
1

Dimensi elemen tingkat blok, yang tidak diganti dalam aliran normal harus memuaskan

margin-kiri + batas-kiri-lebar + padding-kiri + lebar + padding-kanan + lebar-kanan-lebar + margin-kanan = lebar blok yang mengandung

Ketika terlalu dibatasi, browser harus menyesuaikan margin kiri atau kanan. Saya pikir itu berarti lebar kotak margin harus sama dengan lebar blok yang berisi (yaitu 100%).

Untuk kasus Anda, batas transparan dengan box-sizing: border-boxdapat berfungsi seperti margin .

sam
sumber
1

Mungkin mengatur batas ke 0% opacity menggunakan RGBA dan menggunakan perbatasan sebagai margin.

pengguna3236407
sumber
Kedengarannya seperti retasan, tetapi akan melakukan pekerjaan.
Morgan Feeney
Ini terbukti bermanfaat jika Anda tidak ingin menggunakan pembungkus untuk mencapai pekerjaan.
limitlessloop
... kecuali jika Anda benar-benar membutuhkan perbatasan
FrancescoMM
@FrancescoMM - sedikit "berisik", tetapi Anda dapat membuat kotak dengan batas transparan "lebar-margin" (dan tentu saja tidak ada margin) dan di dalam kotak itu ditempatkan sebuah kotak dengan batas lebar yang ingin Anda tampilkan (sekali lagi tidak memiliki margin)
Pancho
1
Saya tidak bisa mengikuti pemikiran seperti ini. Apakah ada yang lebih alami daripada mengatakan bahwa saya ingin dua kotak 1pxterpisah, masing-masing mengambil 50%ruang yang tersedia? Itulah tepatnya yang margin-boxakan dilakukan. Atau lupakan kotak margin dan pikirkan ruang yang tersedia. Bukan 50% dari wadah induk, tetapi 50% dari yang tersisa. Tidak ada "calc", tidak ada "5% margin", tidak berantakan seperti ...
maaartinus
0

Ada situasi yang menarik ketika menggunakan ukuran isi kotak di dalam tubuh

tidak ada konten tidak ada kotak batas tidak memberikan nilai pada margin kiri-kanan% recount dari dua algoritma recount box ini

  .body{
    box-sizing: border-box;
    margin:0 3%;
  }

Versi Firefox sebelum 57 juga mendukung nilai padding-box untuk ukuran-kotak, meskipun nilai ini telah dihapus dari spesifikasi dan versi browser yang lebih baru.

Jadi margin-box bahkan tidak direncanakan ...

Dmytro Yurchenko
sumber