Розміщення кордону всередині діва, а не на його краю


506

У мене є <div>елемент і я хочу поставити на ньому межу. Я знаю, що можу писати style="border: 1px solid black", але це додає 2px в обидві сторони діва, а це не те, що я хочу.

Я вважаю за краще, щоб ця межа була -1px від краю діва. Сам div - 100px x 100px, і якщо я додаю рамку, я повинен зробити деякі математики, щоб відобразити кордон.

Чи є спосіб, щоб я міг зробити межу відображенням і переконатися, що поле все ще буде 100 пікселів (включаючи кордон)?


Для чого це варто, я опублікував рішення для тих, хто приїхав сюди в пошуках внутрішнього кордону зі зміщенням
Даніелд

Відповіді:


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
ізотроп

128
Єдина вада з цим - Ви ОБОВ'ЯЗКОВО оголосите висоту, щоб вона працювала, без висоти межа все ще сидить поза блоком і впливає на візуалізацію (тобто вертикальний ритм).
jerclarke

1
це не дозволяє стилізувати окремі кордони, і в цьому випадку багато хто, мабуть, буде задоволений використанням цього ресурсу outline.
Лоренц Ло Зауер

1
Примітка jeremyclarke має бути у відповіді, оскільки код не працює без встановлення висоти. сторона-примітка: max-height працює також, якщо div використовує цю властивість, якщо висота не досягне максимальної висоти, вона не працюватиме.

7
Префікси можуть бути скинуті для box-sizing caniuse.com/#search=box-sizing
thelostspore

378

Ви також можете використовувати поле-тінь таким чином:

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
Краще рішення. До речі, всі основні веб-переглядачі сьогодні підтримують звичайну коробку-тінь без префіксу.
Вказівник Null

2
Недоліком є ​​те, що деякі веб-переглядачі не вдається правильно надрукувати тінь у полі і завжди друкують її як №000. Це БУДЬ-то стоп-шоу, якщо вам потрібно мати можливість надрукувати сторінку.
Роб Фокс

2
Дивовижно! Я думаю, це краще, ніж перша відповідь.
AGamePlayer

1
Спробував усіх інших .. цей краще, ніж прийняту відповідь.
Аксан Аршад

88

Можливо, це запізніла відповідь, але я хочу поділитися своїми висновками. Я знайшов два нові підходи до цієї проблеми, яких я тут не знайшов у відповідях:

Внутрішня межа через box-shadowвластивість css

Так, коробчаста тінь використовується для додавання елементів-тіней до елементів. Але ви можете вказати insetтінь, яка б виглядала як внутрішня межа, а не як тінь. Вам просто потрібно встановити горизонтальні та вертикальні тіні 0px, а також " spread" властивість box-shadowширини межі, яку ви хочете мати. Отже, для "внутрішньої" межі 10 пікселів ви напишете наступне:

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

Ось приклад jsFiddle, який ілюструє різницю між box-shadowкордоном та 'нормальним' кордоном. Таким чином ваша рамка та ширина поля становлять загальну 100 пікс., Включаючи кордон.

Більше про коробку-тінь: тут

Обмежуйте контур властивості 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

Видатний! Єдине рішення, яке працювало для мене над якорним тегом, що містить зображення галереї. Мені подобається те, що він не збільшує зображення вниз, а візуально затискає краї.
Рішард Єдрашик

21

Хоча на це питання вже відповіли належним чином рішення з використанням властивостей box-shadowта outlineвластивостей, я хотів би трохи розширити це для всіх тих, хто приземлився тут (як я), шукаючи рішення для внутрішньої межі зі зміщенням

Отже, скажімо, у вас чорний 100px x 100px, divі вам потрібно вставити його білою облямівкою, яка має внутрішнє зміщення 5px (скажімо) - це все одно можна зробити з вищезазначеними властивостями.

коробка-тінь

Хитрість тут полягає в тому, щоб знати, що дозволено декілька тіньових коробок, де перша тінь знаходиться зверху, а наступні тіні мають нижній z-упорядкування.

З урахуванням цих знань, поле-тіньова декларація буде:

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

В основному, про що йдеться в цій декларації: спочатку наведіть останню (10 пікселів білу) тінь, а потім зробіть попередню чорну тінь 5 пікселів над нею.

контур із контуром-зміщенням

Для такого ж ефекту, що і вище контурних декларацій, було б:

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

Примітка: outline-offset IE не підтримується, якщо це важливо для вас.


Codepen demo


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>


Дякую, ця відповідь врятувала мені день у 2019 році :)
alx

Гарний! Це має бути "єдине"!
Педро Феррейра

7

Я знаю, що це дещо старше, але оскільки ключові слова "межа всередині" висадили мене прямо тут, я хотів би поділитися деякими висновками, які, можливо, варто згадати тут. Коли я додавав межу стану наведення, я отримав наслідки, про які говорить ОП. Кордон рекламних пікселів відповідає розміру поля, що зробило його стрибком. Є ще два способи впоратися з цим, які також працюють для 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

Якщо ви використовуєте розміри коробки: border-box означає не тільки межу, прокладку, поле тощо. Усі елементи будуть надходити всередині батьківського елемента.

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

Можливо, вам доведеться познайомитись з полями на фальшивих кордонах Div, щоб відповідати тому, як вам подобається.


0

Більш сучасним рішенням може бути використання css variablesі calc. calcшироко підтримується, але variablesйого ще немає в IE11 (поліфіли доступні).

: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)"
}

Що мені в цьому подобається, це те, що у мене є повне меню межі + прокладки + властивості переходу для кожної сторони.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.