Placer la bordure à l'intérieur de div et non sur son bord

506

J'ai un <div>élément et je veux mettre une frontière dessus. Je sais que je peux écrire style="border: 1px solid black", mais cela ajoute 2 pixels de chaque côté du div, ce qui n'est pas ce que je veux.

Je préfère que cette bordure soit à -1px du bord de la div. Le div lui-même est 100px x 100px, et si j'ajoute une bordure, alors je dois faire quelques calculs pour faire apparaître la bordure.

Existe-t-il un moyen de faire apparaître la bordure et de s'assurer que la boîte sera toujours de 100 pixels (y compris la bordure)?

TheMonkeyMan
la source
Pour ce que ça vaut, j'ai posté une solution pour ceux qui sont venus ici à la recherche d'une bordure intérieure avec un décalage
Danield

Réponses:

662

Définissez la box-sizingpropriété sur 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>

Il fonctionne sur IE8 et supérieur .

sandeep
la source
12
+1. Pour un peu plus d'informations: css-tricks.com/box-sizing ou paulirish.com/2012/box-sizing-border-box-ftw
isotrope
128
Le seul défaut de celui-ci est que vous DEVEZ déclarer une hauteur pour qu'il fonctionne, sans hauteur, la bordure se trouve toujours à l'extérieur du bloc et affecte le rendu (c'est-à-dire le rythme vertical).
jerclarke
1
cela ne permet pas de styliser les côtés de bordure individuels, et dans ce cas, beaucoup seraient probablement satisfaits de l'utilisation de la propriété outline.
Lorenz Lo Sauer
1
jeremyclarke note devrait être dans la réponse, car le code ne fonctionne pas sans définir la hauteur. note latérale: la hauteur max fonctionne également, tant que la div UTILISE cette propriété, si la hauteur n'atteint pas la hauteur max, cela ne fonctionnera pas.
7
Les préfixes des fournisseurs peuvent être supprimés pour box-sizing caniuse.com/#search=box-sizing
thelostspore
378

Vous pouvez également utiliser l'ombre de boîte comme ceci:

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

Exemple ici: http://jsfiddle.net/nVyXS/ (survolez pour voir la bordure)

Cela fonctionne uniquement dans les navigateurs modernes. Par exemple: pas de support IE 8. Voir caniuse.com (fonctionnalité d'ombre de boîte) pour plus d'informations.

caitriona
la source
30
J'adore cette solution, car elle maintient la bordure complètement à l'intérieur de la boîte, quelle que soit la hauteur définie. Parfait si vous voulez des bordures qui n'ont aucun effet en dehors de la boîte. Voici le CSS pour une bordure supérieure de 2px: "inset 0px 2px 0px 0px #DDD"
jerclarke
11
Solution préférée. Btw, tous les principaux navigateurs supportent aujourd'hui le shadow box simple sans préfixe.
Pointer Null
2
Un inconvénient est que certains navigateurs ne parviennent pas à imprimer correctement l'ombre de boîte et l'impriment toujours en tant que # 000. Cela POURRAIT être un bouchon d'exposition si vous avez besoin de pouvoir imprimer la page.
Rob Fox
2
Impressionnant! Je pense que c'est mieux que la première réponse.
AGamePlayer
1
J'ai essayé tous les autres .. celui-ci mieux que la réponse acceptée.
Ahsan Arshad
88

C'est probablement une réponse tardive, mais je veux partager mes conclusions. J'ai trouvé 2 nouvelles approches à ce problème que je n'ai pas trouvées ici dans les réponses:

Bordure intérieure via la box-shadowpropriété CSS

Oui, l'ombre de boîte est utilisée pour ajouter des ombres de boîte aux éléments. Mais vous pouvez spécifier une insetombre, qui ressemblerait plutôt à une bordure intérieure qu'à une ombre. Il vous suffit de définir les ombres horizontales et verticales sur 0px, et la spreadpropriété " " de la box-shadowsur la largeur de la bordure que vous souhaitez avoir. Ainsi, pour la bordure «intérieure» de 10 pixels, vous écririez ce qui suit:

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

Voici un exemple jsFiddle qui illustre la différence entre box-shadowbordure et bordure «normale». De cette façon, votre bordure et la largeur de la boîte sont de 100 pixels au total, bordure comprise.

En savoir plus sur box-shadow: ici

Bordure à travers la propriété CSS de contour

Voici une autre approche, mais de cette façon, la frontière serait en dehors de la boîte. Voici un exemple . Comme indiqué dans l'exemple, vous pouvez utiliser la outlinepropriété css pour définir la bordure qui n'affecte pas la largeur et la hauteur de l'élément. De cette façon, la largeur de bordure n'est pas ajoutée à la largeur d'un élément.

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

En savoir plus sur le plan: ici

Shukhrat Raimov
la source
+1 pour le plan, c'est une approche très efficace et même votre page w3schools mentionne: «IE8 ne supporte la propriété plan que si un! DOCTYPE est spécifié.»
Armfoot
3
REMARQUE: le contour ne respecte pas le rayon de la bordure (testé dans Chrome)
Nick
45

Yahoo! C'est vraiment possible. Je l'ai trouvé.

Pour la bordure inférieure:

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

Pour la bordure supérieure:

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

Utilisez un pseudo-élément :

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

À l'aide de ::aftervous, vous stylisez le dernier enfant virtuel de l'élément sélectionné. contentLa propriété crée un élément remplacé anonyme .

Nous contenons le pseudo-élément en utilisant la position absolue par rapport au parent. Ensuite, vous avez la liberté d'avoir n'importe quel arrière-plan et / ou bordure personnalisé à l'arrière-plan de votre élément principal.

Cette approche n'affecte pas le placement du contenu de l'élément principal, ce qui est différent de l'utilisation box-sizing: border-box;.

Considérez cet exemple:

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

Ici, la .buttonlargeur est contrainte à l'aide de l'élément parent. La définition de border-left-widthajuste la taille de la zone de contenu et donc la position du texte.

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

L'utilisation de l'approche pseudo-élément n'affecte pas la taille de la zone de contenu.

Selon l'application, l'approche utilisant un pseudo-élément peut être ou non un comportement souhaitable.

Gajus
la source
Parfait! J'ai trouvé que cela fonctionne également si vous devez l'utiliser :Before.
spasticninja
Exceptionnel! La seule solution qui a fonctionné pour moi sur une balise d'ancrage contenant une image de galerie. J'aime le fait qu'il ne réduit pas l'image, mais coupe visuellement les bords à la place.
Ryszard Jędraszyk
21

Bien que cette question ait déjà reçu une réponse adéquate avec des solutions utilisant les propriétés box-shadowet outline, je voudrais développer légèrement cela pour tous ceux qui ont atterri ici (comme moi) à la recherche d'une solution pour une bordure intérieure avec un décalage

Disons donc que vous avez un noir 100px x 100px divet que vous devez l' insérer avec une bordure blanche - qui a un décalage interne de 5px (disons) - cela peut toujours être fait avec les propriétés ci-dessus.

boîte ombre

L'astuce ici est de savoir que plusieurs ombres de boîte sont autorisées, où la première ombre est au-dessus et les ombres suivantes ont un ordre z inférieur.

Avec cette connaissance, la déclaration box-shadow sera:

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

Fondamentalement, ce que dit cette déclaration, c'est: restituez d'abord la dernière ombre (10px blanche), puis rendez l'ombre noire précédente de 5px au-dessus.

contour avec contour-offset

Pour le même effet que ci-dessus, les grandes lignes des déclarations seraient:

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

NB: outline-offset n'est pas pris en charge par IE si cela est important pour vous.


Démo Codepen

Danield
la source
15

Vous pouvez utiliser les propriétés outlineet outline-offsetavec une valeur négative au lieu d'utiliser un régulier border, fonctionne pour moi:

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
la source
Merci, cette réponse m'a sauvé la journée en 2019 :)
alx
Beau! Ce devrait être "celui"!
Pedro Ferreira
7

Je sais que c'est un peu plus ancien, mais comme les mots clés "border inside" m'ont atterri directement ici, je voudrais partager quelques résultats qui méritent d'être mentionnés ici. Lorsque j'ajoutais une bordure sur le survol, j'ai eu les effets dont OP parle. La bordure annonce des pixels à la dimension de la boîte, ce qui la rend nerveuse. Il existe deux autres façons de gérer cela, qui fonctionnent également pour IE7.

1) Ayez une bordure déjà attachée à l'élément et changez simplement la couleur. De cette façon, les mathématiques sont déjà incluses.

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

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

2) Compensez votre frontière avec une marge négative. Cela ajoutera toujours les pixels supplémentaires, mais le positionnement de l'élément ne sera pas instable

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

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

pour un rendu cohérent entre les nouveaux navigateurs et les anciens, ajoutez un double conteneur, l'extérieur avec la largeur, l'intérieur avec la bordure.

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

ce n'est évidemment que si votre largeur précise est plus importante que d'avoir un balisage supplémentaire!

Evert
la source
2

Si vous utilisez le dimensionnement de la boîte: border-box signifie non seulement la bordure, le remplissage, la marge, etc. Tous les éléments entreront à l'intérieur de l'élément parent.

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
la source
ce que l'enfer est cette citation
Chud37
0

La meilleure solution de navigateur croisé (principalement pour le support IE) comme @Steve a dit est de faire une div 98px en largeur et en hauteur que d'ajouter une bordure 1px autour d'elle, ou vous pouvez créer une image d'arrière-plan pour div 100x100 px et dessiner une bordure dessus.

mdesdev
la source
0

Vous pouvez regarder le contour avec décalage, mais cela nécessite un remplissage pour exister sur votre div. Ou vous pouvez absolument positionner une div frontière à l'intérieur, quelque chose comme

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

Vous devrez peut-être jouer avec les marges sur les fausses bordures div pour l'adapter à votre guise.

Gorky
la source
0

Une solution plus moderne pourrait être d'utiliser css variableset calc. calcest largement pris en charge mais variablesn'est pas encore dans IE11 (polyfills disponibles).

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

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

Bien que cela utilise certains calculs, ce que les questions originales cherchaient à éviter. Je pense que c'est un bon moment pour utiliser les calculs car ils sont contrôlés par le CSS lui-même. Il n'a également pas besoin de balisage supplémentaire ou de détournement d'autres propriétés css qui pourraient être nécessaires plus tard.

Cette solution n'est vraiment utile que si une hauteur fixe n'est pas nécessaire .

Andy Polhill
la source
0

Une solution que je n'ai pas vue mentionnée ci-dessus est le cas où vous avez un remplissage sur votre entrée, ce que je fais 99% du temps. Vous pouvez faire quelque chose comme ...

input {
  padding: 8px;
}

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

Ce que j'aime à ce sujet, c'est que j'ai le menu complet des propriétés border + padding + transition pour chaque côté.

Gobot
la source