Đặt đường viền bên trong div và không nằm trên cạnh của nó


506

Tôi có một <div>yếu tố và tôi muốn đặt một đường viền trên nó. Tôi biết tôi có thể viết style="border: 1px solid black", nhưng điều này thêm 2px vào hai bên của div, đó không phải là điều tôi muốn.

Tôi muốn có đường viền này là -1px từ cạnh của div. Bản thân div là 100px x 100px, và nếu tôi thêm một đường viền, thì tôi phải thực hiện một số phép toán để làm cho đường viền xuất hiện.

Có cách nào để tôi có thể làm cho đường viền xuất hiện không và đảm bảo hộp vẫn sẽ là 100px (bao gồm cả đường viền)?


Để biết giá trị của nó, tôi đã đăng một giải pháp cho những người đến đây để tìm kiếm một đường viền bên trong có phần
Danield

Câu trả lời:


661

Đặt thuộc box-sizingtính thành 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>

Nó hoạt động trên IE8 trở lên .


12
+1. Để biết thêm một chút nền tảng: css-tricks.com/box-sizing hoặc paulirish.com/2012/box-sizing-border-box-ftw
isotrope

128
Chỉ có lỗi với cái này là bạn PHẢI khai báo chiều cao để nó hoạt động, không có chiều cao, đường viền vẫn nằm ngoài khối và ảnh hưởng đến kết xuất (tức là nhịp dọc).
jerclarke

1
điều này không cho phép tạo kiểu cho các mặt biên riêng lẻ và trong trường hợp này, nhiều người có thể sẽ hài lòng với việc sử dụng tài sản outline.
Lorenz Lo Sauer

1
Lưu ý jeremyclarke nên có trong câu trả lời, vì mã không hoạt động mà không thiết lập chiều cao. Lưu ý phụ: chiều cao tối đa cũng hoạt động, miễn là div SỬ DỤNG tài sản đó, nếu chiều cao không đạt được chiều cao tối đa thì nó sẽ không hoạt động.

7
Tiền tố của nhà cung cấp có thể được bỏ cho box-sizing caniuse.com/#search=box-sizing
thelostspore

378

Bạn cũng có thể sử dụng bóng hộp như thế này:

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

Ví dụ ở đây: http://jsfiddle.net/nVyXS/ (di chuột để xem viền)

Điều này chỉ hoạt động trong các trình duyệt hiện đại. Ví dụ: Không hỗ trợ IE 8. Xem caniuse.com (tính năng hộp bóng) để biết thêm thông tin.


30
Yêu giải pháp này vì nó giữ đường viền hoàn toàn bên trong hộp bất kể có chiều cao được đặt. Hoàn hảo nếu bạn muốn các đường viền không có hiệu lực ở bên ngoài hộp. Đây là CSS cho đường viền trên cùng là 2px: "inet 0px 2px 0px 0px #DDD"
jerclarke

11
Giải pháp ưu tiên. Btw, tất cả các trình duyệt chính hiện nay đều hỗ trợ bóng hộp đơn giản không có tiền tố.
Con trỏ Null

2
Một nhược điểm là một số trình duyệt không thể in bóng hộp chính xác và luôn in dưới dạng # 000. COULD này là một điểm dừng hiển thị nếu bạn cần có thể in trang.
Rob Fox

2
Tuyệt vời! Tôi nghĩ rằng điều này là tốt hơn so với câu trả lời đầu tiên.
AGamePlayer 20/03/2016

1
Đã thử tất cả những thứ khác .. cái này tốt hơn câu trả lời được chấp nhận.
Ahsan Arshad

88

Có lẽ đó là câu trả lời muộn màng, nhưng tôi muốn chia sẻ với những phát hiện của tôi. Tôi đã tìm thấy 2 cách tiếp cận mới cho vấn đề này mà tôi chưa tìm thấy ở đây trong các câu trả lời:

Biên giới bên trong thông qua box-shadowtài sản css

Có, bóng hộp được sử dụng để thêm bóng hộp cho các thành phần. Nhưng bạn có thể chỉ định insetbóng, nó sẽ trông giống như một đường viền bên trong chứ không giống như một cái bóng. Bạn chỉ cần đặt bóng ngang và dọc thành 0pxvà thuộc tính " spread" của box-shadowchiều rộng của đường viền bạn muốn có. Vì vậy, đối với đường viền 'bên trong' là 10px, bạn sẽ viết như sau:

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

Dưới đây là ví dụ jsFiddle minh họa sự khác biệt giữa box-shadowđường viền và đường viền 'bình thường'. Bằng cách này, đường viền của bạn và chiều rộng của hộp có tổng số 100px bao gồm cả đường viền.

Thông tin thêm về bóng hộp: tại đây

Biên giới qua tài sản css

Đây là một cách tiếp cận khác, nhưng theo cách này, đường viền sẽ nằm ngoài hộp. Đây là một ví dụ . Như sau từ ví dụ, bạn có thể sử dụng thuộc tính css outline, để đặt đường viền không ảnh hưởng đến chiều rộng và chiều cao của phần tử. Bằng cách này, chiều rộng đường viền không được thêm vào chiều rộng của một phần tử.

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

Thêm về phác thảo: ở đây


+1 cho phác thảo, đó là một cách tiếp cận rất hiệu quả và ngay cả trang w3schools của bạn cũng đề cập: «IE8 chỉ hỗ trợ thuộc tính phác thảo nếu a! DOCTYPE được chỉ định.»
Armfoot

3
LƯU Ý: phác thảo không tôn trọng bán kính đường viền (được thử nghiệm trong Chrome)
Nick

45

Yahoo! Điều này thực sự có thể. Tôi tìm thấy nó.

Đối với đường viền dưới:

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

Đối với biên giới hàng đầu:

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

28

Sử dụng phần tử giả :

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

Sử dụng ::afterbạn đang tạo kiểu con cuối cùng ảo của phần tử được chọn. contenttài sản tạo ra một yếu tố thay thế ẩn danh .

Chúng tôi đang chứa phần tử giả sử dụng vị trí tuyệt đối so với cha mẹ. Sau đó, bạn có quyền tự do có bất kỳ nền tùy chỉnh và / hoặc đường viền nào trong nền của thành phần chính của bạn.

Cách tiếp cận này không ảnh hưởng đến vị trí của nội dung của yếu tố chính, khác với việc sử dụng box-sizing: border-box; .

Xem xét ví dụ này:

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

Ở đây .buttonchiều rộng bị hạn chế sử dụng phần tử cha. Đặt border-left-widthđiều chỉnh kích thước hộp nội dung và do đó vị trí của văn bản.

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

Sử dụng phương pháp tiếp cận phần tử giả không ảnh hưởng đến kích thước hộp nội dung.

Tùy thuộc vào ứng dụng, cách tiếp cận sử dụng phần tử giả có thể hoặc không phải là một hành vi mong muốn.


Hoàn hảo! Tôi thấy điều này cũng hoạt động nếu bạn cần sử dụng nó trên :Before.
spasticninja

Nổi bật! Giải pháp duy nhất phù hợp với tôi trên thẻ neo chứa hình ảnh bộ sưu tập. Tôi thích thực tế là nó không thu nhỏ hình ảnh, nhưng thay vào đó là các cạnh trực quan.
Ryszard Jędras Hot

21

Mặc dù câu hỏi này đã được trả lời thỏa đáng với các giải pháp sử dụng các thuộc tính box-shadowoutlinetính chất, tôi muốn mở rộng một chút về vấn đề này cho tất cả những người đã đến đây (như bản thân tôi) để tìm giải pháp cho đường viền bên trong có

Vì vậy, giả sử bạn có 100px x 100px màu đen divvà bạn cần chèn nó với viền trắng - có độ lệch bên trong là 5px (giả sử) - điều này vẫn có thể được thực hiện với các thuộc tính trên.

bóng hộp

Mẹo ở đây là để biết rằng nhiều bóng hộp được cho phép, trong đó bóng đầu tiên ở trên và các bóng tiếp theo có thứ tự z thấp hơn.

Với kiến ​​thức đó, khai báo hộp bóng sẽ là:

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

Về cơ bản, điều mà tuyên bố đó đang nói là: hiển thị bóng cuối cùng (10px trắng) trước, sau đó hiển thị bóng đen 5px trước đó phía trên nó.

phác thảo với phác thảo-offset

Để có hiệu lực tương tự như trên, các tuyên bố phác thảo sẽ là:

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

NB: outline-offset không được IE hỗ trợ nếu điều đó quan trọng với bạn.


Bản demo Codepen


15

Bạn có thể sử dụng các thuộc tính outlineoutline-offsetvới giá trị âm thay vì sử dụng thông thường border, hoạt động với tôi:

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>


Cảm ơn bạn, câu trả lời này đã cứu ngày của tôi vào năm 2019 :)
alx

Xinh đẹp! Đây phải là "cái"!
Pedro Ferreira

7

Tôi biết điều này có phần cũ hơn, nhưng vì các từ khóa "biên giới bên trong" đã trực tiếp đến đây, tôi muốn chia sẻ một số phát hiện có thể đáng được đề cập ở đây. Khi tôi thêm đường viền vào trạng thái di chuột, tôi đã nhận được các hiệu ứng mà OP đang nói đến. Các đường viền quảng cáo pixel theo kích thước của hộp làm cho nó tăng vọt. Có hai cách khác người ta có thể đối phó với điều này cũng hoạt động cho IE7.

1) Có một đường viền đã được gắn vào thành phần và chỉ cần thay đổi màu sắc. Bằng cách này, toán học đã được bao gồm.

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

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

2) Bồi thường đường viền của bạn với một lề âm. Điều này vẫn sẽ thêm các pixel phụ, nhưng vị trí của phần tử sẽ không tăng vọt

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

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

3

để hiển thị nhất quán giữa các trình duyệt mới và cũ hơn, hãy thêm một thùng chứa kép, bên ngoài có chiều rộng, bên trong có viền.

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

điều này rõ ràng chỉ khi chiều rộng chính xác của bạn quan trọng hơn việc đánh dấu thêm!


2

Nếu bạn sử dụng kích thước hộp: hộp viền có nghĩa là không chỉ đường viền, phần đệm, lề, v.v ... Tất cả phần tử sẽ nằm bên trong phần tử cha.

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>


câu nói đó là cái quái gì vậy
Chud37

0

Giải pháp trình duyệt chéo tốt nhất (chủ yếu là hỗ trợ IE) như @Steve đã nói là tạo div 98px về chiều rộng và chiều cao hơn là thêm viền 1px xung quanh nó, hoặc bạn có thể tạo ảnh nền cho div 100x100 px và vẽ đường viền trên đó.


0

Bạn có thể nhìn vào phác thảo với offset nhưng điều này cần một số phần đệm để tồn tại trên div của bạn. Hoặc bạn hoàn toàn có thể định vị một div viền bên trong, đại loại như

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

Bạn có thể cần phải nghịch ngợm với lề trên div viền giả để phù hợp với nó như bạn muốn.


0

Một giải pháp hiện đại hơn có thể là sử dụng css variablescalc. calcđược hỗ trợ rộng rãi nhưng variableschưa có trong IE11 (có sẵn polyfill).

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

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

Mặc dù điều này không sử dụng một số tính toán, điều mà các câu hỏi ban đầu đang tìm cách tránh. Tôi nghĩ rằng đây là thời gian ok để sử dụng các tính toán vì chúng được kiểm soát bởi chính css. Nó cũng không có nhu cầu đánh dấu bổ sung hoặc chiếm dụng các thuộc tính css khác có thể cần thiết sau này.

Giải pháp này chỉ thực sự hữu ích nếu không cần một chiều cao cố định .


0

Một giải pháp tôi không thấy được đề cập ở trên là trường hợp bạn có phần đệm trên đầu vào của bạn, mà tôi thực hiện 99% thời gian. Bạn có thể làm một cái gì đó dọc theo dòng ...

input {
  padding: 8px;
}

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

Điều tôi thích ở đây là tôi có menu đầy đủ các thuộc tính viền + đệm + chuyển tiếp cho mỗi bên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.