Colocando el borde dentro del div y no en su borde

506

Tengo un <div>elemento y quiero ponerle un borde. Sé que puedo escribir style="border: 1px solid black", pero esto agrega 2px a cada lado del div, que no es lo que quiero.

Prefiero que este borde sea -1px desde el borde del div. El div en sí es 100px x 100px, y si agrego un borde, entonces tengo que hacer algunas matemáticas para que aparezca el borde.

¿Hay alguna forma de hacer que aparezca el borde y asegurarme de que el cuadro seguirá siendo de 100 px (incluido el borde)?

TheMonkeyMan
fuente
Por lo que vale, publiqué una solución para aquellos que vinieron aquí buscando un borde interior con un desplazamiento
Danield

Respuestas:

662

Establecer box-sizingpropiedad para 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 en IE8 y superior .

sandeep
fuente
12
+1. Para un poco más de antecedentes: css-tricks.com/box-sizing o paulirish.com/2012/box-sizing-border-box-ftw
isotrope
128
La única falla con este es que DEBE declarar una altura para que funcione, sin una altura, el borde aún se encuentra fuera del bloque y afecta el renderizado (es decir, el ritmo vertical).
jerclarke
1
esto no permite diseñar lados de borde individuales, y en este caso muchos probablemente estarían contentos con el uso de la propiedad outline.
Lorenz Lo Sauer
1
La nota jeremyclarke debería estar en la respuesta, ya que el código no funciona sin establecer la altura. nota al margen: max-height también funciona, siempre que el div USE esa propiedad, si la altura no alcanza la altura máxima, no funcionará.
77
Los prefijos de proveedor se pueden eliminar para box-sizing caniuse.com/#search=box-sizing
thelostspore
378

También puedes usar box-shadow como este:

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

Ejemplo aquí: http://jsfiddle.net/nVyXS/ (pase el cursor para ver el borde)

Esto funciona solo en navegadores modernos. Por ejemplo: No hay soporte para IE 8. Consulte caniuse.com (función de sombreado) para obtener más información.

caitriona
fuente
30
Me encanta esta solución porque mantiene el borde completamente dentro de la caja, independientemente de que tenga una altura establecida. Perfecto si quieres bordes que no tengan ningún efecto fuera de la caja. Aquí está el CSS para un borde superior de 2px: "recuadro 0px 2px 0px 0px #DDD"
jerclarke
11
Solución preferida Por cierto, todos los principales navegadores de hoy en día son compatibles con box-shadow sin prefijo.
Puntero nulo
2
Una desventaja es que algunos navegadores no imprimen correctamente la sombra de cuadro y siempre la imprimen como # 000. Esto PODRÍA ser un show stopper si necesita poder imprimir la página.
Rob Fox
2
¡Increíble! Creo que esto es mejor que la primera respuesta.
AGamePlayer
1
Intenté todos los demás ... este mejor que la respuesta aceptada.
Ahsan Arshad
88

Probablemente sea una respuesta tardía, pero quiero compartir con mis hallazgos. Encontré 2 nuevos enfoques para este problema que no he encontrado aquí en las respuestas:

Borde interno a través de la box-shadowpropiedad css

Sí, box-shadow se usa para agregar box-shadow a los elementos. Pero puede especificar la insetsombra, que se vería como un borde interior en lugar de una sombra. Solo necesita establecer sombras horizontales y verticales 0px, y la spreadpropiedad " " box-shadowdel ancho del borde que desea tener. Entonces, para el borde 'interno' de 10px, escribirías lo siguiente:

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

Aquí está el ejemplo de jsFiddle que ilustra la diferencia entre el box-shadowborde y el borde 'normal'. De esta manera, su borde y el ancho del cuadro son de un total de 100 píxeles, incluido el borde.

Más sobre box-shadow: aquí

Borde a través de la propiedad css del esquema

Aquí hay otro enfoque, pero de esta manera el borde estaría fuera de la caja. Aquí hay un ejemplo . Como se deduce del ejemplo, puede usar la outlinepropiedad css para establecer el borde que no afecta el ancho y la altura del elemento. De esta manera, el ancho del borde no se agrega al ancho de un elemento.

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

Más sobre el esquema: aquí

Shukhrat Raimov
fuente
+1 para el esquema, es un enfoque muy eficaz e incluso su página de w3schools menciona: «IE8 admite la propiedad de esquema solo si se especifica un! DOCTYPE».
Armfoot
3
NOTA: el esquema no respeta el radio del borde (probado en Chrome)
Nick
45

Yahoo! Esto es realmente posible. Lo encontré.

Para borde inferior:

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

Para borde superior:

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

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

Al ::afterusarlo, está estilizando el último hijo virtual del elemento seleccionado. contentLa propiedad crea un elemento anónimo reemplazado .

Estamos conteniendo el pseudo elemento usando la posición absoluta en relación con el padre. Entonces tiene libertad para tener cualquier fondo o borde personalizado en el fondo de su elemento principal.

Este enfoque no afecta la ubicación de los contenidos del elemento principal, que es diferente del uso box-sizing: border-box;.

Considere este ejemplo:

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

Aquí el .buttonancho está restringido usando el elemento padre. La configuración border-left-widthajusta el tamaño del cuadro de contenido y, por lo tanto, la posición del 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>

El uso del enfoque de pseudoelementos no afecta el tamaño del cuadro de contenido.

Dependiendo de la aplicación, el enfoque que utiliza un pseudo-elemento podría o no ser un comportamiento deseable.

Gajus
fuente
¡Perfecto! Descubrí que esto también funciona si necesitas usarlo :Before.
spasticninja
¡Excepcional! La única solución que funcionó para mí en la etiqueta de ancla que contiene la imagen de la galería. Me gusta el hecho de que no reduce la imagen, sino que recorta visualmente los bordes.
Ryszard Jędraszyk
21

Aunque esta pregunta ya se ha respondido adecuadamente con soluciones que utilizan las propiedades box-shadowy outline, me gustaría ampliar ligeramente esto para todos aquellos que han aterrizado aquí (como yo) en busca de una solución para un borde interior con un desplazamiento

Entonces, supongamos que tiene un negro de 100px x 100px divy necesita insertarlo con un borde blanco, que tiene un desplazamiento interno de 5px (digamos), esto todavía se puede hacer con las propiedades anteriores.

sombra de la caja

El truco aquí es saber que se permiten varias sombras de cuadro, donde la primera sombra está en la parte superior y las sombras posteriores tienen un orden z menor.

Con ese conocimiento, la declaración de cuadro de sombra será:

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

Básicamente, lo que dice esa declaración es: primero renderice la última sombra (10 px en blanco), luego renderice la sombra negra anterior de 5 px encima.

esquema con desplazamiento de esquema

Para el mismo efecto que el anterior, las declaraciones generales serían:

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

NB: outline-offset IE no lo admite si eso es importante para usted.


Codepen demo

Danield
fuente
15

Puede usar las propiedades outliney outline-offsetcon un valor negativo en lugar de usar un regular border, funciona para mí:

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
fuente
Gracias, esta respuesta me salvó el día en 2019 :)
alx
¡Hermoso! ¡Esto debería ser "el indicado"!
Pedro Ferreira
7

Sé que esto es algo antiguo, pero dado que las palabras clave "borde interior" me llevaron directamente aquí, me gustaría compartir algunos hallazgos que vale la pena mencionar aquí. Cuando estaba agregando un borde en el estado de desplazamiento, obtuve los efectos de los que habla OP. El borde anuncia píxeles a la dimensión del cuadro que lo hizo saltar. Hay dos formas más de lidiar con esto que también funcionan para IE7.

1) Tenga un borde ya unido al elemento y simplemente cambie el color. De esta manera las matemáticas ya están incluidas.

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

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

2) Compensa tu borde con un margen negativo. Esto todavía agregará los píxeles adicionales, pero la posición del elemento no será irregular.

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

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

Para una representación coherente entre navegadores nuevos y antiguos, agregue un contenedor doble, el exterior con el ancho, el interior con el borde.

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

obviamente, esto es solo si su ancho preciso es más importante que tener un marcado adicional

Evert
fuente
2

Si usa box-sizing: border-box significa no solo borde, relleno, margen, etc. Todos los elementos entrarán dentro del elemento padre.

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
fuente
¿Qué demonios es esa cita
Chud37
0

La mejor solución de navegador cruzado (principalmente para soporte de IE) como @Steve dijo es hacer un div 98px de ancho y alto que agregar un borde 1px a su alrededor, o podría hacer una imagen de fondo para div 100x100 px y dibujar un borde en él.

mdesdev
fuente
0

Puede mirar el esquema con desplazamiento, pero esto necesita algo de relleno para existir en su div. O puede posicionar absolutamente un borde div dentro, algo así 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>

Es posible que deba jugar con los márgenes en el div de bordes falsos para ajustarlo a su gusto.

Gorki
fuente
0

Una solución más moderna podría ser usar CSS variablesy calc. calces ampliamente compatible pero variablesaún no está en IE11 (polyfills disponibles).

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

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

Aunque esto usa algunos cálculos, que las preguntas originales buscaban evitar. Creo que este es un buen momento para usar cálculos, ya que están controlados por el propio CSS. Tampoco tiene necesidad de marcas adicionales o de apropiación indebida de otras propiedades css que puedan necesitarse más adelante.

Esta solución solo es realmente útil si no se necesita una altura fija .

Andy Polhill
fuente
0

Una solución que no vi mencionada anteriormente es el caso en el que tiene relleno en su entrada, que hago el 99% del tiempo. Puedes hacer algo en la línea de ...

input {
  padding: 8px;
}

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

Lo que me gusta de esto es que tengo el menú completo de borde + relleno + propiedades de transición para cada lado.

Gobot
fuente