Menempatkan perbatasan di dalam div dan tidak di tepinya

506

Saya memiliki <div>elemen dan saya ingin meletakkan perbatasan di atasnya. Saya tahu saya bisa menulis style="border: 1px solid black", tetapi ini menambahkan 2px ke kedua sisi div, yang bukan yang saya inginkan.

Saya lebih suka memiliki perbatasan ini menjadi -1px dari tepi div. Div itu sendiri 100px x 100px, dan jika saya menambahkan perbatasan, maka saya harus melakukan beberapa matematika untuk membuat perbatasan muncul.

Apakah ada cara agar saya dapat membuat perbatasan muncul, dan memastikan kotak itu masih 100px (termasuk perbatasan)?

TheMonkeyMan
sumber
Untuk apa nilainya, saya memposting solusi bagi mereka yang datang ke sini mencari perbatasan dalam dengan offset
Danield

Jawaban:

662

Setel box-sizingproperti ke border-box:

div {
    box-sizing: border-box;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    width: 100px;
    height: 100px;
    border: 20px solid #f00;
    background: #00f;
    margin: 10px;
}

div + div {
    border: 10px solid red;
}
<div>Hello!</div>
<div>Hello!</div>

Ini bekerja pada IE8 & di atas .

sandeep
sumber
12
+1. Untuk latar belakang lebih sedikit: css-tricks.com/box-sizing atau paulirish.com/2012/box-sizing-border-box-ftw
isotrope
128
Satu-satunya kelemahan dengan yang ini adalah Anda HARUS menyatakan ketinggian untuk itu untuk bekerja, tanpa ketinggian perbatasan masih duduk di luar blok dan mempengaruhi rendering (yaitu ritme vertikal).
jerclarke
1
ini tidak memungkinkan penataan sisi sisi individu, dan dalam hal ini banyak yang mungkin akan senang menggunakan properti outline.
Lorenz Lo Sauer
1
catatan jeremyclarke harus ada dalam jawaban, karena kode tidak berfungsi tanpa menetapkan tinggi. side-note: max-height juga berfungsi, selama div MENGGUNAKAN properti itu, jika ketinggiannya tidak mencapai max-height, itu tidak akan berfungsi.
7
Vendor prefiks dapat dijatuhkan untuk box-sizing caniuse.com/#search=box-sizing
thelostspore
378

Anda juga dapat menggunakan bayangan kotak seperti ini:

div{
    -webkit-box-shadow:inset 0px 0px 0px 10px #f00;
    -moz-box-shadow:inset 0px 0px 0px 10px #f00;
    box-shadow:inset 0px 0px 0px 10px #f00;
}

Contoh di sini: http://jsfiddle.net/nVyXS/ (arahkan kursor ke perbatasan)

Ini hanya berfungsi di browser modern. Misalnya: Tidak ada dukungan IE 8. Lihat caniuse.com (fitur bayangan kotak) untuk info lebih lanjut.

caitriona
sumber
30
Sukai solusi ini karena menjaga perbatasan sepenuhnya di dalam kotak terlepas dari memiliki ketinggian yang ditetapkan. Sempurna jika Anda menginginkan batas yang tidak memiliki efek sama sekali di luar kotak. Inilah CSS untuk batas atas 2px: "inset 0px 2px 0px 0px #DDD"
jerclarke
11
Solusi yang disukai. Btw, semua browser utama saat ini mendukung bayangan kotak sederhana tanpa awalan.
Pointer Null
2
Salah satu kelemahannya adalah beberapa browser gagal mencetak bayangan kotak dengan benar dan selalu mencetaknya sebagai # 000. Ini BISA menjadi penghenti acara jika Anda harus dapat mencetak halaman.
Rob Fox
2
Luar biasa! Saya pikir ini lebih baik daripada jawaban pertama.
AGamePlayer
1
Mencoba semua yang lain .. yang ini lebih baik daripada jawaban yang diterima.
Ahsan Arshad
88

Mungkin ini jawaban yang terlambat, tetapi saya ingin berbagi dengan temuan saya. Saya menemukan 2 pendekatan baru untuk masalah ini yang belum saya temukan di sini dalam jawabannya:

Perbatasan dalam melalui box-shadowproperti css

Ya, bayangan kotak digunakan untuk menambahkan bayangan kotak ke elemen. Tapi Anda bisa menentukan insetbayangan, yang akan terlihat seperti perbatasan bagian dalam, bukan seperti bayangan. Anda hanya perlu mengatur bayangan horizontal dan vertikal 0px, dan spreadproperti " " dari box-shadowdengan lebar perbatasan yang Anda inginkan. Jadi untuk batas 'batin' 10px Anda akan menulis yang berikut ini:

div{
    width:100px;
    height:100px;
    background-color:yellow;
    box-shadow:0px 0px 0px 10px black inset;
    margin-bottom:20px;
}

Berikut adalah contoh jsFiddle yang menggambarkan perbedaan antara box-shadowperbatasan dan perbatasan 'normal'. Dengan cara ini, batas Anda dan lebar kotak adalah total 100px termasuk batas.

Lebih lanjut tentang bayangan kotak: di sini

Perbatasan melalui garis besar properti css

Berikut adalah pendekatan lain, tetapi dengan cara ini perbatasan akan berada di luar kotak. Berikut ini sebuah contoh . Sebagai berikut dari contoh, Anda dapat menggunakan outlineproperti css , untuk mengatur batas yang tidak mempengaruhi lebar dan tinggi elemen. Dengan cara ini, lebar perbatasan tidak ditambahkan ke lebar elemen.

div{
   width:100px;
   height:100px;
   background-color:yellow;
   outline:10px solid black;
}

Lebih lanjut tentang garis besar: di sini

Shukhrat Raimov
sumber
+1 untuk garis besar, ini adalah pendekatan yang sangat efektif dan bahkan halaman w3schools Anda menyebutkan: «IE8 mendukung properti garis besar hanya jika! DOCTYPE ditentukan.»
Armfoot
3
CATATAN: garis besar tidak menghormati radius batas (diuji di Chrome)
Nick
45

Yahoo! Ini sangat mungkin. Aku menemukannya.

Untuk Batas Bawah:

div {box-shadow: 0px -3px 0px red inset; }

Untuk Batas Atas:

div {box-shadow: 0px 3px 0px red inset; }
xBoss naYan
sumber
28

Gunakan elemen pseudo :

.button {
    background: #333;
    color: #fff;
    float: left;
    padding: 20px;
    margin: 20px;
    position: relative;
}

.button::after {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    border: 5px solid #f00;
}
<div class='button'>Hello</div>

Menggunakan ::afterAnda menata anak terakhir virtual dari elemen yang dipilih. contentproperti menciptakan elemen yang diganti anonim .

Kami mengandung elemen pseudo menggunakan posisi absolut relatif terhadap induknya. Kemudian Anda memiliki kebebasan untuk memiliki latar belakang dan / atau perbatasan khusus apa pun di latar belakang elemen utama Anda.

Pendekatan ini tidak mempengaruhi penempatan konten elemen utama, yang berbeda dari penggunaan box-sizing: border-box; .

Pertimbangkan contoh ini:

.parent {
    width: 200px;
}

.button {
    background: #333;
    color: #fff;
    padding: 20px;
    border: 5px solid #f00;
    border-left-width: 20px;
    box-sizing: border-box;
}
<div class='parent'>
    <div class='button'>Hello</div>
</div>

Di sini .buttonlebar dibatasi menggunakan elemen induk. Pengaturan border-left-widthmenyesuaikan ukuran kotak konten dan dengan demikian posisi teks.

.parent {
    width: 200px;
}

.button {
    background: #333;
    color: #fff;
    padding: 20px;
    position: relative;
}

.button::after {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    border: 5px solid #f00;
    border-left-width: 20px;
}
<div class='parent'>
    <div class='button'>Hello</div>
</div>

Menggunakan pendekatan elemen semu tidak mempengaruhi ukuran kotak konten.

Bergantung pada aplikasinya, pendekatan yang menggunakan elemen pseudo mungkin atau mungkin bukan perilaku yang diinginkan.

Gajus
sumber
Sempurna! Saya menemukan ini juga berfungsi jika Anda perlu menggunakannya :Before.
spasticninja
Luar biasa! Satu-satunya solusi yang bekerja untuk saya pada jangkar tag yang berisi gambar galeri. Saya suka fakta bahwa itu tidak menurunkan skala gambar, tetapi secara visual klip tepi.
Ryszard Jędraszyk
21

Meskipun pertanyaan ini sudah dijawab secara memadai dengan solusi menggunakan box-shadow dan outlineproperti, saya ingin sedikit memperluas ini untuk semua orang yang telah mendarat di sini (seperti saya) mencari solusi untuk perbatasan dalam dengan offset

Jadi katakanlah Anda memiliki 100px x 100px hitam divdan Anda harus memasukkannya dengan batas putih - yang memiliki offset bagian dalam 5px (katakanlah) - ini masih dapat dilakukan dengan properti di atas.

bayangan kotak

Kuncinya di sini adalah untuk mengetahui bahwa banyak bayangan kotak diperbolehkan, di mana bayangan pertama berada di atas dan bayangan berikutnya memiliki urutan z yang lebih rendah.

Dengan pengetahuan itu, deklarasi bayangan kotak akan:

box-shadow: inset 0 0 0 5px black, inset 0 0 0 10px white;

Pada dasarnya, apa yang dikatakan deklarasi itu adalah: render bayangan terakhir (putih 10px) terlebih dahulu, lalu render bayangan hitam 5px sebelumnya di atasnya.

outline dengan outline-offset

Untuk efek yang sama seperti di atas, deklarasi garis besar akan menjadi:

outline: 5px solid white;
outline-offset: -10px;

NB: outline-offset tidak didukung oleh IE jika itu penting bagi Anda.


Demo codepen

Danield
sumber
15

Anda dapat menggunakan properti outlinedan outline-offsetdengan nilai negatif alih-alih menggunakan biasa border, berfungsi untuk saya:

div{
    height: 100px;
    width: 100px;
    background-color: grey;
    margin-bottom: 10px; 
}

div#border{
    border: 2px solid red;
}

div#outline{
    outline: 2px solid red;
    outline-offset: -2px;
}
Using a regular border.
<div id="border"></div>

Using outline and outline-offset.
<div id="outline"></div>

Wilson Delgado
sumber
Terima kasih, jawaban ini menyelamatkan hari saya di tahun 2019 :)
alx
Cantik! Ini harus menjadi "satu-satunya"!
Pedro Ferreira
7

Saya tahu ini agak lebih tua, tetapi karena kata kunci "border inside" langsung mendarat di sini, saya ingin berbagi beberapa temuan yang mungkin layak disebutkan di sini. Ketika saya menambahkan perbatasan pada status hover, saya mendapat efek yang dibicarakan OP. Perbatasan iklan piksel ke dimensi kotak yang membuatnya gelisah. Ada dua cara lagi yang bisa dilakukan untuk mengatasi hal ini yang juga berfungsi untuk IE7.

1) Memiliki perbatasan sudah terpasang ke elemen dan cukup ubah warna. Dengan cara ini matematika sudah termasuk.

div {
   width:100px;
   height:100px;
   background-color: #aaa;
   border: 2px solid #aaa; /* notice the solid */
}

div:hover {
   border: 2px dashed #666;
}

2) Kompensasi perbatasan Anda dengan margin negatif. Ini masih akan menambah piksel tambahan, tetapi penentuan posisi elemen tidak akan gelisah

div {
   width:100px;
   height:100px;
   background-color: #aaa;
}

div:hover {
  margin: -2px;
  border: 2px dashed #333;
}
Daniel
sumber
3

untuk rendering yang konsisten antara browser baru dan lama, tambahkan wadah ganda, bagian luar dengan lebar, bagian dalam dengan perbatasan.

<div style="width:100px;">
<div style="border:2px solid #000;">
contents here
</div>
</div>

ini jelas hanya jika lebar Anda yang tepat lebih penting daripada memiliki markup ekstra!

Evert
sumber
2

Jika Anda menggunakan ukuran kotak: kotak batas berarti tidak hanya bingkai, bantalan, margin, dll. Semua elemen akan masuk ke dalam elemen induk.

div p {
    box-sizing: border-box;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    width: 150px;
    height:100%;
    border: 20px solid #f00;
    background-color: #00f;
    color:#fff;
    padding: 10px;
  
}
<div>
  <p>It was popularised in the 1960s with the release of Letraset sheets</p>
</div>

Ayyappan K
sumber
apa sih kutipan itu
Chud37
0

Solusi cross browser terbaik (kebanyakan untuk dukungan IE) seperti @Steve katakan adalah membuat div 98px lebar dan tinggi daripada menambahkan perbatasan 1px di sekitarnya, atau Anda bisa membuat gambar latar belakang untuk div 100x100 px dan menggambar perbatasan di atasnya.

mdesdev
sumber
0

Anda dapat melihat garis besar dengan offset tetapi ini membutuhkan beberapa lapisan agar ada pada div Anda. Atau Anda benar-benar dapat memposisikan div perbatasan di dalam, sesuatu seperti

<div id='parentDiv' style='position:relative'>
  <div id='parentDivsContent'></div>
  <div id='fakeBordersDiv' 
       style='position: absolute;width: 100%;
              height: 100%;
              z-index: 2;
              border: 2px solid;
              border-radius: 2px;'/>
</div>

Anda mungkin perlu bermain-main dengan margin di perbatasan palsu agar sesuai dengan keinginan Anda.

Gorky
sumber
0

Solusi yang lebih modern mungkin menggunakan css variablesdan calc. calcdidukung secara luas tetapi variablesbelum dalam IE11 (polyfill tersedia).

:root {
  box-width: 100px;
  border-width: 1px;
}

#box {
  width: calc(var(--box-width) - var(--border-width));
}

Meskipun ini memang menggunakan beberapa perhitungan, yang ingin dihindari oleh pertanyaan awal. Saya pikir ini adalah waktu yang tepat untuk menggunakan perhitungan karena mereka dikendalikan oleh css itu sendiri. Itu juga tidak perlu markup tambahan atau penyalahgunaan properti css lain yang mungkin diperlukan nanti.

Solusi ini hanya sangat berguna jika ketinggian tetap tidak diperlukan .

Andy Polhill
sumber
0

Salah satu solusi yang saya tidak lihat disebutkan di atas adalah kasus di mana Anda memiliki padding pada input Anda, yang saya lakukan 99% dari waktu. Anda dapat melakukan sesuatu di sepanjang ...

input {
  padding: 8px;
}

input.invalid {
  border: 2px solid red;
  padding: 6px; // 8px - border or "calc(8px - 2px)"
}

Yang saya sukai dari ini adalah saya memiliki menu lengkap properti border + padding + transisi untuk setiap sisi.

Gobot
sumber