Colocando a borda dentro da div e não na borda

506

Eu tenho um <div>elemento e quero colocar uma borda nele. Eu sei que posso escrever style="border: 1px solid black", mas isso adiciona 2px a ambos os lados da div, o que não é o que eu quero.

Prefiro que essa borda seja -1px da borda da div. A div em si é 100px x 100px, e se eu adicionar uma borda, preciso fazer algumas matemáticas para que a borda apareça.

Existe alguma maneira de fazer a borda aparecer e garantir que a caixa ainda tenha 100px (incluindo a borda)?

TheMonkeyMan
fonte
Para o que vale a pena, publiquei uma solução para quem veio aqui em busca de uma borda interna com um deslocamento
Danield

Respostas:

661

Defina a box-sizingpropriedade como 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>

Funciona no IE8 e acima .

sandeep
fonte
12
+1. Para um pouco mais fundo: css-tricks.com/box-sizing ou paulirish.com/2012/box-sizing-border-box-ftw
isotrope
128
O único problema com este é que você DEVE declarar uma altura para que funcione, sem uma altura em que a borda ainda fique do lado de fora do bloco e afeta a renderização (ritmo vertical).
jerclarke
1
isso não permite o estilo de bordas individuais e, nesse caso, muitos provavelmente ficariam felizes em usar a propriedade outline.
Lorenz Lo Sauer
1
Nota do jeremyclarke deve estar na resposta, pois o código não funciona sem definir a altura. observação lateral: max-height também funciona, desde que a div esteja USANDO essa propriedade, se a altura não atingir a altura máxima, ela não funcionará.
7
Prefixos de fornecedor pode ser descartado para box-sizing caniuse.com/#search=box-sizing
thelostspore
378

Você também pode usar sombra de caixa como esta:

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

Exemplo aqui: http://jsfiddle.net/nVyXS/ (passe o mouse para exibir a borda)

Isso funciona apenas em navegadores modernos. Por exemplo: Não há suporte para o IE 8. Consulte caniuse.com (recurso box-shadow) para obter mais informações.

caitriona
fonte
30
Adore esta solução, pois mantém a borda completamente dentro da caixa, independentemente de ter uma altura definida. Perfeito se você quiser bordas que não tenham nenhum efeito fora da caixa. Aqui está o CSS para um top-fronteira 2px: "inset 0px 2px 0px 0px #DDD"
jerclarke
11
Solução preferida. Aliás, todos os principais navegadores hoje suportam sombra de caixa simples sem prefixo.
Ponteiro Nulo
2
Uma desvantagem é que alguns navegadores não conseguem imprimir a sombra da caixa corretamente e sempre a imprimem como # 000. Isso pode ser uma rolha de exibição, se você precisar imprimir a página.
Rob Fox
2
Impressionante! Eu acho que isso é melhor do que a primeira resposta.
AGamePlayer
1
Tentei todos os outros .. este melhor do que a resposta aceita.
Ahsan Arshad
88

Provavelmente é uma resposta tardia, mas quero compartilhar com minhas descobertas. Encontrei 2 novas abordagens para esse problema que não encontrei aqui nas respostas:

Borda interna através box-shadow propriedade css

Sim, sombra de caixa é usada para adicionar sombras de caixa aos elementos. Mas você pode especificar a insetsombra, que pareceria uma borda interna e sim uma sombra. Você só precisa definir sombras horizontais e verticais para 0px, e a spreadpropriedade " " box-shadowda largura da borda que você deseja ter. Portanto, para a borda 'interna' de 10 px, você deve escrever o seguinte:

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

Aqui está o exemplo do jsFiddle que ilustra a diferença entre a box-shadowborda e a borda 'normal'. Dessa forma, sua borda e a largura da caixa são de 100px, incluindo a borda.

Mais sobre box-shadow: aqui

Borda através da propriedade CSS de estrutura de tópicos

Aqui está outra abordagem, mas dessa maneira a borda estaria fora da caixa. Aqui está um exemplo . Como segue do exemplo, você pode usar a outlinepropriedade css para definir a borda que não afeta a largura e a altura do elemento. Dessa forma, a largura da borda não é adicionada à largura de um elemento.

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

Mais sobre o esboço: aqui

Shukhrat Raimov
fonte
+1 para estrutura de tópicos, é uma abordagem muito eficaz e até a página do w3schools menciona: «O IE8 suporta a propriedade estrutura de tópicos somente se um! DOCTYPE for especificado.»
Armfoot
3
NOTA: o contorno não respeita o raio da borda (testado no Chrome)
Nick
45

Yahoo! Isso é realmente possível. Eu encontrei.

Para borda inferior:

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

Para borda superior:

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

Use pseudo elemento :

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

Ao usar ::aftero estilo do último filho virtual do elemento selecionado. contentA propriedade cria um elemento substituído anônimo .

Estamos contendo o pseudo elemento usando a posição absoluta em relação ao pai. Então você tem liberdade para ter qualquer plano de fundo personalizado e / ou borda no plano de fundo do seu elemento principal.

Essa abordagem não afeta a localização do conteúdo do elemento principal, que é diferente do uso de box-sizing: border-box; .

Considere este exemplo:

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

Aqui a .buttonlargura é restrita usando o elemento pai. A configuração de border-left-widthajusta o tamanho da caixa de conteúdo e, portanto, a posição do texto.

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

O uso da abordagem de pseudoelementos não afeta o tamanho da caixa de conteúdo.

Dependendo do aplicativo, a abordagem usando um pseudoelemento pode ou não ser um comportamento desejável.

Gajus
fonte
Perfeito! Descobri que isso também funciona se você precisar usá-lo :Before.
Spasticninja
Excepcional! A única solução que funcionou para mim na âncora contendo a imagem da galeria. Eu gosto do fato de que ela não diminui a escala da imagem, mas visualmente corta as bordas.
Ryszard Jędraszyk
21

Embora essa pergunta já tenha sido respondida adequadamente com soluções usando as propriedades box-shadowe outline, eu gostaria de expandir um pouco isso para todos aqueles que chegaram aqui (como eu) à procura de uma solução para uma borda interna com um deslocamento

Então, digamos que você tenha um 100px x 100px preto dive precise inseri-lo com uma borda branca - que possui um deslocamento interno de 5px (por exemplo) - isso ainda pode ser feito com as propriedades acima.

Sombra da caixa

O truque aqui é saber que várias sombras de caixa são permitidas, onde a primeira sombra está no topo e as sombras subsequentes têm ordem z mais baixa.

Com esse conhecimento, a declaração box-shadow será:

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

Basicamente, o que essa declaração está dizendo é: renderize a última sombra (10px em branco) primeiro e depois renderize a sombra em preto anterior de 5px acima dela.

contorno com deslocamento de contorno

Para o mesmo efeito acima, as declarações gerais seriam:

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

Nota: outline-offset não é suportado pelo IE se isso é importante para você.


Codepen demo

Danield
fonte
15

Você pode usar as propriedades outlinee outline-offsetcom um valor negativo, em vez de usar um regular border, funciona para mim:

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
fonte
Obrigado, esta resposta salvou meu dia em 2019 :)
alx
Bonita! Este deve ser "o único"!
Pedro Ferreira
7

Sei que isso é um pouco mais antigo, mas como as palavras-chave "border inside" me chegaram diretamente aqui, gostaria de compartilhar algumas descobertas que podem ser mencionadas aqui. Quando eu estava adicionando uma borda no estado de foco, obtive os efeitos que o OP está falando. A borda exibe pixels na dimensão da caixa, o que a deixa agitada. Existem mais duas maneiras de lidar com isso que também funcionam para o IE7.

1) Tenha uma borda já anexada ao elemento e simplesmente altere a cor. Desta forma, a matemática já está incluída.

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

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

2) Compensar sua borda com uma margem negativa. Isso ainda adicionará pixels extras, mas o posicionamento do elemento não será irregular em

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

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

para renderização consistente entre navegadores novos e antigos, adicione um contêiner duplo, o externo com a largura e o interno com a borda.

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

obviamente, isso é apenas se sua largura precisa for mais importante do que ter uma marcação extra!

Evert
fonte
2

Se você usar o tamanho da caixa: border-box significa não apenas borda, preenchimento, margem etc. Todo o elemento entrará dentro do elemento pai.

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
fonte
o que diabos é que a citação
Chud37
0

A melhor solução para vários navegadores (principalmente para suporte ao IE), como o @Steve disse, é fazer uma div 98px em largura e altura do que adicionar uma borda 1px em torno dela, ou você pode criar uma imagem de plano de fundo para div 100x100 px e desenhar uma borda nela.

mdesdev
fonte
0

Você pode olhar o contorno com deslocamento, mas isso precisa de algum preenchimento para existir em sua div. Ou você pode posicionar absolutamente uma div de borda dentro, algo como

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

Pode ser necessário mexer nas margens das divs das bordas falsas para ajustá-las como quiser.

Gorky
fonte
0

Uma solução mais moderna pode ser usar css variablese calc. calcé amplamente suportado, mas variablesainda não está no IE11 (polyfills disponível).

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

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

Embora isso use alguns cálculos, que as perguntas originais estavam procurando evitar. Eu acho que este é um bom momento para usar cálculos, pois eles são controlados pelo próprio css. Ele também não precisa de marcação adicional ou apropriação indébita de outras propriedades css que podem ser necessárias posteriormente.

Esta solução é realmente útil apenas se uma altura fixa não for necessária .

Andy Polhill
fonte
0

Uma solução que não vi mencionada acima é o caso em que você tem preenchimento de sua entrada, o que eu faço 99% do tempo. Você pode fazer algo como ...

input {
  padding: 8px;
}

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

O que eu gosto sobre isso é que tenho o menu completo de borda + preenchimento + propriedades de transição para cada lado.

Gobot
fonte