Bagaimana margin negatif dalam CSS bekerja dan mengapa (margin-top: -5! = Margin-bottom: 5)?

108

Trik umum untuk elemen pemosisian vertikal adalah dengan menggunakan CSS berikut:

.item {
    position:absolute;
    top:50%;
    margin-top:-8px; /* half of height */
    height: 16px;
}

Jika dilihat dalam tampilan metrik seperti di Chrome, inilah yang Anda lihat:

masukkan deskripsi gambar di sini

Namun, tidak ada margin visual yang digambarkan saat Anda mengarahkan kursor ke elemen, yaitu margin 'di luar' batas dan dapat divisualisasikan. Tetapi margin negatif tidak muncul. Bagaimana penampilan mereka dan apa yang membuatnya berbeda?

Kenapa margin-top:-8px tidak sama margin-bottom:8px ?

Jadi, bagaimana cara kerja margin negatif dan apa intuisi di baliknya. Bagaimana mereka 'menabrak' (dalam kasus margin-top < 0) suatu barang?

PhD
sumber

Jawaban:

89

Margin negatif berlaku di css dan memahami perilaku (patuh) mereka terutama didasarkan pada model kotak dan penurunan margin. Meskipun skenario tertentu lebih kompleks, banyak kesalahan umum yang dapat dihindari setelah mempelajari spesifikasi.

Misalnya, rendering kode sampel Anda dipandu oleh spesifikasi css seperti yang dijelaskan dalam menghitung ketinggian dan margin untuk elemen yang tidak diganti dengan posisi mutlak .

Jika saya membuat representasi grafis, saya mungkin akan menggunakan sesuatu seperti ini (bukan untuk skala):

margin atas negatif

Kotak margin hilang 8pxdi bagian atas, namun hal ini tidak mempengaruhi kotak konten & padding . Karena elemen Anda benar-benar diposisikan, memindahkan elemen 8px ke atas tidak menyebabkan gangguan lebih lanjut pada tata letak; dengan konten aliran statis yang tidak selalu demikian.

Bonus:

Masih perlu meyakinkan bahwa membaca spesifikasi adalah yang cara untuk pergi (sebagai lawan artikel seperti ini )? Saya melihat Anda mencoba untuk memusatkan elemen secara vertikal, jadi mengapa Anda harus mengatur margin-top:-8px;dan tidak margin-top:-50%;?

Nah, pemusatan vertikal di CSS lebih sulit dari yang seharusnya . Saat mengatur bahkan margin atas atau bawah dalam%, nilai dihitung sebagai persentase selalu relatif terhadap lebar blok yang memuat . Ini adalah kesalahan umum dan kekhasan jarang dijelaskan di luar dokumen w3

ov
sumber
84

Saya akan mencoba menjelaskannya secara visual:

/**
 * explaining margins
 */

body {
  padding: 3em 15%
}

.parent {
  width: 50%;
  width: 400px;
  height: 400px;
  position: relative;
  background: lemonchiffon;
}

.parent:before,
.parent:after {
  position: absolute;
  content: "";
}

.parent:before {
  top: 0;
  bottom: 0;
  left: 50%;
  border-left: dashed 1px #ccc;
}

.parent:after {
  left: 0;
  right: 0;
  top: 50%;
  border-top: dashed 1px #ccc;
}

.child {
  width: 200px;
  height: 200px;
  background: rgba(200, 198, 133, .5);
}

ul {
  padding: 5% 20px;
}

.set1 .child {
  margin: 0;
  position: relative;
}

.set2 .child {
  margin-left: 75px;
  position: relative;
}

.set3 .child {
  margin-left: -75px;
  position: relative;
}


/* position absolute */

.set4 .child {
  top: 50%;
  left: 50%;
  margin: 0;
  position: absolute;
}

.set5 .child {
  top: 50%;
  left: 50%;
  margin-left: 75px;
  position: absolute;
}

.set6 .child {
  top: 50%; /* level from which margin-top starts 
	- downwards, in the case of a positive margin
	- upwards, in the case of a negative margin	
	*/
  left: 50%; /* level from which margin-left starts 
	- towards right, in the case of a positive margin
	- towards left, in the case of a negative margin	
	*/
  margin: -75px;
  position: absolute;
}
<!-- content to be placed inside <body>…</body> -->
<h2><code>position: relative;</code></h2>
<h3>Set 1</h3>
<div class="parent set 1">
  <div class="child">
    <pre>
.set1 .child {
  margin: 0;
  position: relative;
}
		</pre>
  </div>
</div>

<h3>Set 2</h3>
<div class="parent set2">
  <div class="child">
    <pre>
.set2 .child {
  margin-left: 75px;
  position: relative;
}
		</pre>
  </div>
</div>

<h3>Set 3</h3>
<div class="parent set3">
  <div class="child">
    <pre>
.set3 .child {
  margin-left: -75px;
  position: relative;
}
		</pre>
  </div>
</div>

<h2><code>position: absolute;</code></h2>

<h3>Set 4</h3>
<div class="parent set4">
  <div class="child">
    <pre>
.set4 .child {
  top: 50%;
  left: 50%;
  margin: 0;
  position: absolute;
}
		</pre>
  </div>
</div>

<h3>Set 5</h3>
<div class="parent set5">
  <div class="child">
    <pre>
.set5 .child {
  top: 50%;
  left: 50%;
  margin-left: 75px;
  position: absolute;
}
		</pre>
  </div>
</div>

<h3>Set 6</h3>
<div class="parent set6">
  <div class="child">
    <pre>
.set6 .child {
  top: 50%;
  left: 50%;
  margin: -75px;
  position: absolute;
}
		</pre>
  </div>
</div>

Ana
sumber
33

Margin adalah jarak di luar elemen Anda, seperti padding adalah jarak di dalam elemen Anda.

Mengatur margin bawah menunjukkan jarak yang Anda inginkan di bawah blok saat ini. Menetapkan margin atas negatif menunjukkan bahwa Anda menginginkan spasi negatif di atas blok Anda. Jarak negatif dengan sendirinya bisa menjadi konsep yang membingungkan, tetapi seperti cara margin atas positif mendorong konten ke bawah, margin atas negatif menarik konten ke atas.

David Hedlund
sumber
2
+1 Saya suka Jawaban Anda. Dapat ditingkatkan dengan menyuntikkan kata onsetdan offset. Memang benar begitu banyak orang yang selalu menggunakan kata offset( negatif ) saat diartikan onset( positif ). Pesan ini akan hancur dengan sendirinya jika Anda memperbarui jawaban Anda. Bersulang!
arttronics
1
Tentang apa margin-bottom: -8px;? Kenapa margin-bottom:-8pxtidak sama margin-top:-8px?
Rick
27

Margin-atas -8px berarti akan menjadi 8px lebih tinggi daripada jika marginnya 0.

Margin-bawah 8px berarti bahwa hal di bawahnya akan menjadi 8px lebih jauh ke bawah jika memiliki 0 margin.

Bradshaw kaya
sumber
1
Saya hanya mencoba untuk membuat hal-hal sederhana, tetapi saya setuju, ini mungkin yang terburuk dari jawaban saya!
Rich Bradshaw
2
Saya pikir jawaban cukup bagus. Tidak ada gunanya jawaban yang sangat teknis yang separuh dari kita tidak mengerti.
Nomor 945
1
Tentang apa margin-bottom: -8px;? Kenapa margin-bottom:-8pxtidak sama margin-top:-8px?
Rick
22

poin bagus sudah dibuat di sini, tetapi meskipun ada banyak informasi tentang bagaimana rendering margin dilakukan oleh browser, alasannya belum cukup dijawab:

"Mengapa margin-top: -8px tidak sama dengan margin-bottom: 8px?"

yang juga bisa kami tanyakan adalah:

Mengapa margin bawah positif tidak 'menaikkan' elemen sebelumnya, sedangkan margin atas positif 'menabrak' elemen berikut?

jadi apa yang kita lihat adalah bahwa ada perbedaan dalam rendering margin tergantung pada sisi penerapannya - margin atas (dan kiri) berbeda dari margin bawah (dan kanan).

hal-hal menjadi lebih jelas ketika melihat (disederhanakan) bagaimana gaya diterapkan oleh browser: elemen dirender dari atas ke bawah di viewport, dimulai dari pojok kiri atas (mari tetap dengan rendering vertikal untuk saat ini, dengan mengingat bahwa yang horizontal diperlakukan sama).

perhatikan html berikut:

<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>

analog dengan posisi mereka dalam kode, ketiga kotak ini tampak bertumpuk 'top-down' di browser ( menjaga hal-hal sederhana, kami tidak akan menganggap di sini sebagai orderproperti dari modul 'flex-box' css3 ). jadi, setiap kali gaya diterapkan ke kotak 3, posisi elemen sebelumnya (untuk kotak 1 dan 2) telah ditentukan, dan tidak boleh diubah lagi demi kecepatan rendering.

sekarang, bayangkan margin atas -10px untuk kotak 3. alih-alih menggeser semua elemen sebelumnya untuk mengumpulkan beberapa ruang, browser hanya akan mendorong kotak 3 ke atas, jadi itu ditampilkan di atas (atau di bawah, tergantung pada z-index ) elemen sebelumnya. bahkan jika kinerja bukan menjadi masalah, memindahkan semua elemen ke atas dapat berarti memindahkannya dari viewport, sehingga posisi pengguliran saat ini harus diubah agar semuanya terlihat lagi.

hal yang sama berlaku untuk margin bawah untuk kotak 3, baik negatif maupun positif: alih-alih memengaruhi elemen yang sudah dievaluasi, hanya 'titik awal' baru untuk elemen mendatang yang ditentukan. sehingga menetapkan margin bawah positif akan menekan elemen berikut ; yang negatif akan mendorong mereka.

schellmax.dll
sumber
Jawaban TERBAIK. Yang ini juga menjelaskan "mengapa", sedangkan jawaban yang lain hanya menjelaskan "bagaimana".
Amir Hossein Ahmadi
1
Jawaban ini membantu saya memahami mengapa lebih baik. Terima kasih @schellmax
iRamesh
3

Karena Anda telah menggunakan pemosisian absolut, dan menentukan persentase teratas, hanya margin-top yang akan memengaruhi lokasi objek .item Anda. Jika sebaliknya Anda memposisikannya menggunakan bottom: 50%, maka Anda memerlukan margin-bottom -8px untuk memusatkannya, dan margin-top tidak akan berpengaruh.

Margin memengaruhi batas-batas elemen dalam hal memposisikannya, baik secara absolut seperti dalam kasus Anda, atau relatif terhadap elemen tetangga. Bayangkan margin itu adalah fondasi elemen Anda di mana ia berada. Mereka biasanya memiliki ukuran yang sama, tetapi dapat dibuat lebih besar atau lebih kecil pada salah satu atau semua dari keempat tepinya.

CSS Anda memberi tahu browser untuk memposisikan bagian atas elemen Anda margin pada titik 50% ke bawah halaman. Namun, karena semua elemen bukan satu piksel, browser perlu mengetahui bagian mana yang berbaris 50% ke bawah halaman. Untuk menyejajarkan bagian atas elemen, ini menggunakan margin atas. Secara default, ini sejalan dengan bagian atas elemen, tetapi Anda dapat mengubahnya dengan CSS.

Dalam kasus Anda, 50% teratas akan menghasilkan elemen atas yang dimulai di tengah halaman. Dengan menerapkan margin atas negatif, browser menggunakan titik 8px ke dalam elemen dari atas (yaitu garis di tengahnya) sebagai tempat untuk memposisikan pada 50%.

Jika Anda menerapkan margin positif ke bawah, ini memperluas garis yang digunakan browser untuk memposisikan bagian bawah menjauh dari elemen itu sendiri, memberikan celah antara itu dan elemen yang berdekatan di bawah, atau mempengaruhi di mana ia ditempatkan secara mutlak jika pemosisian didasarkan pada bagian bawah.

Rob Trickey
sumber
+1. Masuk akal ... akan sangat bagus untuk menambahkannya dengan isyarat visual untuk melengkapi visualisasi .
PhD
3

Saya bertanya-tanya apakah pertanyaan ini telah dijawab dengan baik: bagaimana margin css bekerja dan mengapa margin-top itu: -5; tidak sama dengan margin-bottom: 5 ;?

Margin adalah jarak dari sekeliling elemen. margin-top mengatakan "... jarak dari lingkungan seperti yang kita ukur dari 'sisi' atas 'kotak' elemen dan margin-bottom adalah jarak dari 'sisi' bawah 'kotak'". Kemudian margin-top: 5; berkaitan dengan perimeter 'sisi' atas, -5 dalam kasus itu; apa pun yang mendekati dari 'sisi' atas dapat menimpa 'sisi' atas elemen sebesar 5, dan margin-bottom: 5; Berarti jarak antara elemen bawah 'sisi' dan sekitarnya adalah 5.

Pada dasarnya itu tetapi dipengaruhi oleh elemen float'ed dan sejenisnya: http://www.w3.org/TR/CSS2/box.html#margin-properties .

http://coding.smashingmagazine.com/2009/07/27/the-definitive-guide-to-using-negative-margins/

Saya berdiri untuk dikoreksi.

Mungkin
sumber