การวางเส้นขอบด้านในของ div ไม่ใช่ที่ขอบ


506

ฉันมี<div>องค์ประกอบและฉันต้องการที่จะวางเส้นขอบบนมัน ฉันรู้ว่าฉันสามารถเขียนstyle="border: 1px solid black"ได้ แต่นี่เพิ่ม 2px ไปที่ด้านใดด้านหนึ่งของ div ซึ่งไม่ใช่สิ่งที่ฉันต้องการ

ฉันอยากให้เส้นขอบนี้เป็น -1px จากขอบของ div ตัวหารเองคือ 100px x 100px และถ้าฉันเพิ่มเส้นขอบแล้วฉันต้องทำคณิตศาสตร์เพื่อทำให้เส้นขอบปรากฏ

มีวิธีใดบ้างที่ฉันสามารถทำให้เส้นขอบปรากฏและตรวจสอบให้แน่ใจว่ากล่องนั้นยังคงเป็น 100px (รวมถึงเส้นขอบด้วย)


สำหรับสิ่งที่คุ้มค่าฉันโพสต์วิธีแก้ปัญหาสำหรับผู้ที่มาที่นี่เพื่อค้นหาเส้นขอบด้านในด้วยการชดเชย
Danield

คำตอบ:


661

ตั้งค่าbox-sizingคุณสมบัติเป็น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>

มันทำงานบนIE8 และข้างต้น


12
+1 สำหรับพื้นหลังเพิ่มเติมเล็กน้อย: css-tricks.com/box-sizingหรือpaulirish.com/2012/box-sizing-border-box-ftw
isotrope

128
ข้อบกพร่องเพียงอย่างเดียวคือคุณต้องประกาศความสูงเพื่อให้มันทำงานได้โดยไม่มีความสูงชายแดนยังคงอยู่นอกบล็อกและส่งผลกระทบต่อการแสดงผล (เช่นจังหวะแนวตั้ง)
jerclarke

1
สิ่งนี้ไม่อนุญาตให้จัดแต่งทรงผมด้านชายแดนแต่ละอันและในกรณีนี้หลายคนอาจจะพอใจกับการใช้คุณสมบัติoutlineนี้
Lorenz Lo Sauer

1
jeremyclarke note ควรอยู่ในคำตอบเนื่องจากรหัสจะไม่ทำงานหากไม่มีการตั้งค่าความสูง หมายเหตุด้านข้าง: ความสูงสูงสุดทำงานได้ดีตราบใดที่ div ใช้คุณสมบัตินั้นหากความสูงไม่ถึงความสูงสูงสุดมันจะไม่ทำงาน

7
คำนำหน้าผู้ขายสามารถลดลงสำหรับbox-sizing caniuse.com/#search=box-sizing
thelostspore

378

คุณสามารถใช้ box-shadow แบบนี้:

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;
}

ตัวอย่างที่นี่: http://jsfiddle.net/nVyXS/ (โฮเวอร์เพื่อดูเส้นขอบ)

ใช้งานได้กับเบราว์เซอร์สมัยใหม่เท่านั้น ตัวอย่างเช่น: ไม่รองรับ IE 8 ดู caniuse.com (คุณสมบัติกล่องเงา)สำหรับข้อมูลเพิ่มเติม


30
รักโซลูชันนี้เพราะมันทำให้เส้นขอบภายในกล่องสมบูรณ์โดยไม่คำนึงถึงชุดความสูง สมบูรณ์แบบถ้าคุณต้องการเส้นขอบที่ไม่มีผลกระทบเลยนอกกรอบ นี่คือ CSS สำหรับเส้นขอบบนของ 2px: "inset 0px 2px 0px 0px #DDD"
jerclarke

11
ทางออกที่ต้องการ Btw ทุกวันนี้เบราว์เซอร์หลักทั้งหมดสนับสนุน box-shadow ธรรมดาโดยไม่มีส่วนนำหน้า
ตัวชี้ Null

2
ข้อเสียอย่างหนึ่งคือเบราว์เซอร์บางตัวไม่สามารถพิมพ์เงาของกล่องอย่างถูกต้องและพิมพ์เป็น # 000 นี่อาจเป็นตัวหยุดการแสดงหากคุณจำเป็นต้องพิมพ์หน้าเอกสาร
Rob Fox

2
! น่ากลัว ฉันคิดว่านี่ดีกว่าคำตอบแรก
AGamePlayer

1
ลองทั้งหมด .. อีกอันนี้ดีกว่าคำตอบที่ยอมรับ
Ahsan Arshad

88

อาจเป็นคำตอบล่าช้า แต่ฉันต้องการแบ่งปันกับการค้นพบของฉัน ฉันพบวิธีใหม่ 2 วิธีสำหรับปัญหานี้ซึ่งฉันไม่พบในคำตอบ:

เส้นขอบด้านในผ่านbox-shadowคุณสมบัติ CSS

ใช่กล่องเงาใช้เพื่อเพิ่มเงากล่ององค์ประกอบ แต่คุณสามารถระบุinsetเงาซึ่งจะมีลักษณะเป็นเส้นขอบด้านในแทนที่จะเป็นเงา คุณต้องตั้งค่าเงาในแนวนอนและแนวตั้ง0pxเป็น " spread" และคุณสมบัติของbox-shadowความกว้างของขอบที่คุณต้องการ ดังนั้นสำหรับเส้นขอบ 'inner' ของ 10px คุณจะต้องเขียนสิ่งต่อไปนี้:

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

นี่คือตัวอย่างjsFiddleที่แสดงความแตกต่างระหว่างbox-shadowเส้นขอบและเส้นขอบ 'ปกติ' วิธีนี้ชายแดนของคุณและความกว้างของกล่องรวม 100px รวมถึงชายแดนด้วย

เพิ่มเติมเกี่ยวกับ box-shadow: ที่นี่

ชายแดนผ่านคุณสมบัติ css เค้าร่าง

นี่เป็นอีกวิธีหนึ่ง แต่วิธีนี้ชายแดนจะอยู่นอกกรอบ นี่คือตัวอย่าง ดังต่อไปนี้จากตัวอย่างคุณสามารถใช้outlineคุณสมบัติcss เพื่อตั้งค่าเส้นขอบที่ไม่มีผลต่อความกว้างและความสูงขององค์ประกอบ วิธีนี้ความกว้างชายแดนจะไม่ถูกเพิ่มเข้าไปในความกว้างขององค์ประกอบ

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

เพิ่มเติมเกี่ยวกับเค้าร่าง: ที่นี่


+1 สำหรับโครงร่างมันเป็นวิธีการที่มีประสิทธิภาพมากและแม้แต่หน้า w3schools ของคุณกล่าวถึง: « IE8 รองรับคุณสมบัติโครงร่างเฉพาะเมื่อระบุ! DOCTYPE »
Armfoot

3
หมายเหตุ: โครงร่างไม่เกี่ยวข้องกับรัศมีเส้นขอบ (ทดสอบใน Chrome)
นิค

45

Yahoo! เป็นไปได้จริง ๆ เจอแล้ว.

สำหรับขอบล่าง:

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

สำหรับขอบด้านบน:

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

28

ใช้องค์ประกอบปลอม :

.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>

การใช้::afterคุณกำลังกำหนดสไตล์ลูกสุดท้ายเสมือนขององค์ประกอบที่เลือก contentสถานที่ให้บริการสร้างที่ไม่ระบุชื่อองค์ประกอบแทนที่

เรากำลังประกอบด้วยองค์ประกอบเทียมโดยใช้ตำแหน่งสัมบูรณ์สัมพันธ์กับผู้ปกครอง จากนั้นคุณมีอิสระที่จะมีพื้นหลังที่กำหนดเองและ / หรือเส้นขอบในพื้นหลังขององค์ประกอบหลักของคุณ

box-sizing: border-box;วิธีนี้ไม่ได้ส่งผลกระทบต่อการจัดวางเนื้อหาขององค์ประกอบหลักซึ่งจะแตกต่างจากการใช้

ลองพิจารณาตัวอย่างนี้:

.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>

.buttonความกว้างที่นี่ถูก จำกัด โดยใช้องค์ประกอบหลัก การตั้งค่าborder-left-widthปรับขนาดกล่องเนื้อหาและทำให้ตำแหน่งของข้อความ

.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>

การใช้วิธีการหลอกองค์ประกอบจะไม่ส่งผลกระทบต่อขนาดของกล่องเนื้อหา

ขึ้นอยู่กับแอปพลิเคชันแนวทางการใช้องค์ประกอบหลอกอาจหรือไม่อาจเป็นพฤติกรรมที่ต้องการ


ที่สมบูรณ์แบบ! :Beforeฉันพบนี้ยังใช้งานได้หากคุณต้องการที่จะใช้ใน
spasticninja

ที่โดดเด่น! ทางออกเดียวที่ทำงานสำหรับฉันบนแท็กสมอที่มีภาพแกลเลอรี่ ฉันชอบความจริงที่ว่ามันไม่ได้ลดขนาดภาพ แต่มองเห็นคลิปขอบแทน
Ryszard Jędraszyk

21

แม้ว่าคำถามนี้ได้รับการตอบคำถามอย่างเพียงพอแล้วด้วยการแก้ปัญหาโดยใช้box-shadowและoutlineคุณสมบัติฉันต้องการที่จะขยายตัวเล็กน้อยสำหรับผู้ที่ลงจอดที่นี่ (เหมือนตัวเอง) ค้นหาวิธีแก้ปัญหาสำหรับเส้นขอบด้านในที่มีการชดเชย

สมมุติว่าคุณมีสีดำ 100px x 100px divและคุณต้องแทรกด้วยเส้นขอบสีขาว - ซึ่งมีค่าชดเชยภายใน 5px (พูด) - สิ่งนี้ยังสามารถทำได้ด้วยคุณสมบัติด้านบน

กล่องเงา

เคล็ดลับที่นี่คือการรู้ว่าอนุญาตให้ใช้หลายกล่องเงาซึ่งเงาแรกอยู่ด้านบนและเงาต่อมามีลำดับ Z ต่ำกว่า

ด้วยความรู้นั้นการประกาศกล่องเงาจะเป็น:

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

โดยพื้นฐานแล้วสิ่งที่ประกาศนั้นคือ: แสดงเงาสุดท้าย (10px สีขาว) ก่อนจากนั้นแสดงเงาดำขนาด 5px ก่อนหน้านี้เหนือมัน

เค้าร่างกับเค้าร่างชดเชย

สำหรับผลเช่นเดียวกับข้างต้นการประกาศโครงร่างจะเป็น:

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

NB: outline-offset IE ไม่ได้รับการสนับสนุนถ้ามันสำคัญสำหรับคุณ


การสาธิต Codepen


15

คุณสามารถใช้คุณสมบัติoutlineและoutline-offsetด้วยค่าลบแทนการใช้แบบปกติborderได้ผลสำหรับฉัน:

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>


ขอบคุณคำตอบนี้บันทึกวันของฉันในปีพ. ศ. 2562 :)
alx

สวย! นี่ควรเป็น "หนึ่งเดียว"!
Pedro Ferreira

7

ฉันรู้ว่านี่ค่อนข้างเก่า แต่เนื่องจากคำหลัก "เส้นขอบด้านใน" ทำให้ฉันเข้ามาที่นี่โดยตรงฉันอยากจะแบ่งปันสิ่งที่ค้นพบซึ่งอาจคุ้มค่าที่จะกล่าวถึงที่นี่ เมื่อฉันเพิ่มเส้นขอบบนสถานะโฮเวอร์ฉันได้รับเอฟเฟกต์ที่ OP พูดถึง เส้นขอบโฆษณาพิกเซลไปยังมิติของกล่องซึ่งทำให้มันน่ากลัว มีอีกสองวิธีที่เราสามารถจัดการกับสิ่งนี้ได้ซึ่งก็ใช้ได้กับ IE7 เช่นกัน

1) มีเส้นขอบติดกับองค์ประกอบแล้วเพียงแค่เปลี่ยนสี วิธีนี้รวมคณิตศาสตร์แล้ว

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

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

2) ชดเชยชายแดนของคุณด้วยอัตรากำไรติดลบ สิ่งนี้จะยังคงเพิ่มพิกเซลพิเศษ แต่การวางตำแหน่งขององค์ประกอบจะไม่น่ากลัว

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

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

3

สำหรับการแสดงผลที่สอดคล้องกันระหว่างเบราว์เซอร์ใหม่และเก่าให้เพิ่มคอนเทนเนอร์คู่ด้านนอกที่มีความกว้างด้านในกับขอบ

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

เห็นได้ชัดว่านี่ก็ต่อเมื่อความกว้างที่แม่นยำของคุณสำคัญกว่าการมีมาร์กอัปเป็นพิเศษ!


2

หากคุณใช้การปรับขนาดกล่อง: กล่องเส้นขอบหมายถึงไม่เพียง แต่เส้นขอบช่องว่างภายในขอบ ฯลฯ องค์ประกอบทั้งหมดจะอยู่ภายในองค์ประกอบหลัก

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>


คำพูดนั้นคืออะไร
Chud37

0

โซลูชันเบราว์เซอร์ข้ามที่ดีที่สุด (ส่วนใหญ่รองรับ IE) อย่าง @Steve กล่าวคือการทำ div 98px ในความกว้างและความสูงกว่าการเพิ่มเส้นขอบ 1px รอบ ๆ หรือคุณสามารถสร้างภาพพื้นหลังสำหรับ div 100x100 px และวาดเส้นขอบบน


0

คุณสามารถดูโครงร่างด้วยออฟเซ็ต แต่สิ่งนี้จำเป็นต้องมีช่องว่างภายในบน div ของคุณ หรือคุณสามารถวางตำแหน่ง div border ไว้ข้างในได้

<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>

คุณอาจต้องเล่นซอกับขอบบนกองปลอมเพื่อให้พอดีกับที่คุณต้องการ


0

วิธีการแก้ปัญหาที่ทันสมัยมากขึ้นอาจจะมีการใช้ CSS และvariables ได้รับการสนับสนุนอย่างกว้างขวาง แต่ยังไม่ได้อยู่ใน IE11 (มีให้เลือกหลายสี)calccalcvariables

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

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

แม้ว่าจะใช้การคำนวณบางอย่างซึ่งเป็นคำถามดั้งเดิมที่ต้องการหลีกเลี่ยง ฉันคิดว่านี่เป็นเวลาที่เหมาะสมที่จะใช้การคำนวณเนื่องจากควบคุมโดย css เอง นอกจากนี้ยังไม่จำเป็นต้องมีมาร์กอัปเพิ่มเติมหรือนำคุณสมบัติ css อื่นไปใช้ในทางที่ผิดซึ่งอาจจำเป็นในภายหลัง

การแก้ปัญหานี้เป็นเพียงประโยชน์จริงๆถ้าความสูงคงไม่จำเป็นต้อง


0

ทางออกหนึ่งที่ฉันไม่ได้กล่าวถึงข้างต้นคือกรณีที่คุณมีช่องว่างภายในของคุณซึ่งฉันทำ 99% ของเวลา คุณสามารถทำอะไรบางอย่างตามสาย ...

input {
  padding: 8px;
}

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

สิ่งที่ฉันชอบเกี่ยวกับเรื่องนี้คือฉันมีเมนูเต็มของคุณสมบัติการเปลี่ยนขอบ + การเติม + สำหรับแต่ละด้าน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.