Posizionamento del bordo all'interno del div e non sul suo bordo


506

Ho un <div>elemento e voglio metterlo un bordo. So di poter scrivere style="border: 1px solid black", ma questo aggiunge 2px a entrambi i lati del div, che non è quello che voglio.

Preferirei che questo bordo fosse -1px dal bordo del div. Il div stesso è 100px x 100px e se aggiungo un bordo, devo fare un po 'di matematica per far apparire il bordo.

Posso fare in modo che appaia il bordo e assicurarmi che la casella sia ancora 100px (incluso il bordo)?


Per quello che vale, ho pubblicato una soluzione per coloro che sono venuti qui alla ricerca di un confine interno con un offset
Danield,

Risposte:


662

Imposta la box-sizingproprietà su 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>

Funziona su IE8 e versioni successive .



128
L'unico difetto di questo è che DEVI dichiarare un'altezza per farlo funzionare, senza un'altezza il bordo si trova ancora fuori dal blocco e influenza il rendering (cioè il ritmo verticale).
jerclarke,

1
questo non consente lo stile dei singoli bordi e in questo caso molti sarebbero probabilmente contenti di usare la proprietà outline.
Lorenz Lo Sauer,

1
la nota jeremyclarke dovrebbe essere nella risposta, poiché il codice non funziona senza impostare l'altezza. nota a margine: l'altezza massima funziona pure, finché il div STA USANDO quella proprietà, se l'altezza non raggiunge l'altezza massima non funzionerà.

7
I prefissi del fornitore possono essere eliminati per box-sizing caniuse.com/#search=box-sizing
thelostspore

378

Puoi anche usare box-shadow in questo modo:

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

Esempio qui: http://jsfiddle.net/nVyXS/ (passa il mouse per visualizzare il bordo)

Funziona solo con i browser moderni. Ad esempio: nessun supporto per IE 8. Vedi caniuse.com (funzione box-shadow) per maggiori informazioni.


30
Adoro questa soluzione perché mantiene il bordo completamente all'interno della scatola indipendentemente dal fatto che abbia un'altezza impostata. Perfetto se vuoi bordi che non abbiano alcun effetto fuori dagli schemi. Ecco il CSS per un bordo superiore di 2px: "inset 0px 2px 0px 0px #DDD"
jerclarke,

11
Soluzione preferita. A proposito, oggi tutti i principali browser supportano il semplice box-shadow senza prefisso.
Puntatore Null,

2
Un aspetto negativo è che alcuni browser non riescono a stampare correttamente box-shadow e lo stampano sempre come # 000. Questo POTREBBE essere un blocco dello spettacolo se devi essere in grado di stampare la pagina.
Rob Fox,

2
Eccezionale! Penso che sia meglio della prima risposta.
AGamePlayer

1
Ho provato tutti gli altri .. questo meglio della risposta accettata.
Ahsan Arshad,

88

Probabilmente è una risposta tardiva, ma voglio condividere con i miei risultati. Ho trovato 2 nuovi approcci a questo problema che non ho trovato qui nelle risposte:

Bordo interno tramite box-shadowproprietà css

Sì, box-shadow viene utilizzato per aggiungere box-shading agli elementi. Ma puoi specificare l' insetombra, che sembrerebbe un bordo interno piuttosto che un'ombra. Devi solo impostare le ombre orizzontali e verticali 0pxe la spreadproprietà " " della box-shadowlarghezza del bordo che vuoi avere. Quindi per il bordo "interno" di 10px dovresti scrivere quanto segue:

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

Ecco l' esempio di jsFiddle che illustra la differenza tra box-shadowbordo e bordo "normale". In questo modo il bordo e la larghezza della casella sono di 100px totali incluso il bordo.

Maggiori informazioni su box-shadow: qui

Confine attraverso la proprietà css del contorno

Ecco un altro approccio, ma in questo modo il confine sarebbe fuori dagli schemi. Ecco un esempio . Come nell'esempio, puoi usare la outlineproprietà css per impostare il bordo che non influenza la larghezza e l'altezza dell'elemento. In questo modo, la larghezza del bordo non viene aggiunta alla larghezza di un elemento.

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

Maggiori informazioni sulla struttura: qui


+1 per lo schema, è un approccio molto efficace e anche la tua pagina w3schools menziona: «IE8 supporta la proprietà dello schema solo se è specificato un! DOCTYPE.»
Armfoot,

3
NOTA: il contorno non rispetta il raggio del bordo (testato in Chrome)
Nick,

45

Yahoo! Questo è davvero possibile. L'ho trovato.

Per bordo inferiore:

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

Per bordo superiore:

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

28

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

Usando ::aftersi sta disegnando l'ultimo figlio virtuale dell'elemento selezionato. contentLa proprietà crea un elemento sostituito anonimo .

Stiamo contenendo lo pseudo elemento usando la posizione assoluta rispetto al genitore. Quindi hai la libertà di avere qualsiasi sfondo e / o bordo personalizzati sullo sfondo del tuo elemento principale.

Questo approccio non influisce sul posizionamento dei contenuti dell'elemento principale, che è diverso dall'uso box-sizing: border-box;.

Considera questo esempio:

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

Qui la .buttonlarghezza è vincolata usando l'elemento genitore. L'impostazione di border-left-widthregola la dimensione della casella di contenuto e quindi la posizione del testo.

.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'uso dell'approccio pseudo-elemento non influisce sulla dimensione della casella di contenuto.

A seconda dell'applicazione, l'approccio che utilizza uno pseudo-elemento potrebbe o meno essere un comportamento desiderabile.


Perfetto! Ho scoperto che funziona anche se è necessario utilizzarlo :Before.
spasticninja,

Eccezionale! L'unica soluzione che ha funzionato per me sul tag anchor contenente l'immagine della galleria. Mi piace il fatto che non ridimensiona l'immagine, ma tagli invece visivamente i bordi.
Ryszard Jędraszyk,

21

Sebbene a questa domanda sia già stata data una risposta adeguata con soluzioni che utilizzano le proprietà box-shadowe outline, vorrei espandermi leggermente su questo per tutti coloro che sono atterrati qui (come me) alla ricerca di una soluzione per un confine interno con un offset

Quindi supponiamo che tu abbia un 100px x 100px nero dive devi inserirlo con un bordo bianco - che ha un offset interno di 5px (diciamo) - questo può ancora essere fatto con le proprietà sopra.

box-ombra

Il trucco qui è sapere che sono consentite più ombre box, in cui la prima ombra è in cima e le ombre successive hanno un ordine z inferiore.

Con questa conoscenza, la dichiarazione box-shadow sarà:

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

Fondamentalmente, ciò che sta dicendo quella dichiarazione è: renderizza prima l'ultima ombra (10px bianca), quindi esegui il rendering dell'ombra nera precedente di 5p sopra di essa.

contorni con contorni sfalsati

Per lo stesso effetto di cui sopra, le dichiarazioni di contorno sarebbero:

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

NB: outline-offset non è supportato da IE se questo è importante per te.


Demo Codepen


15

Puoi usare le proprietà outlinee outline-offsetcon un valore negativo invece di usare un normale border, funziona per me:

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>


Grazie, questa risposta mi ha salvato la giornata nel 2019 :)
alx,

Bellissimo! Questo dovrebbe essere "l'unico"!
Pedro Ferreira,

7

So che questo è un po 'più vecchio, ma dal momento che le parole chiave "confine all'interno" mi hanno portato direttamente qui, vorrei condividere alcuni risultati che potrebbero valere la pena menzionare qui. Quando stavo aggiungendo un bordo sullo stato al passaggio del mouse, ho ottenuto gli effetti di cui parla OP. Il bordo inserisce i pixel nella dimensione del riquadro che lo ha reso instabile. Esistono altri due modi in cui uno può gestirlo, che funziona anche con IE7.

1) Avere un bordo già attaccato all'elemento e cambiare semplicemente il colore. In questo modo la matematica è già inclusa.

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

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

2) Compensare il bordo con un margine negativo. Ciò aggiungerà comunque i pixel extra, ma il posizionamento dell'elemento non sarà instabile

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

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

3

per un rendering coerente tra browser nuovi e meno recenti, aggiungi un doppio contenitore, l'esterno con la larghezza, l'interno con il bordo.

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

questo è ovviamente solo se la tua larghezza precisa è più importante che avere un markup extra!


2

Se usi il ridimensionamento del riquadro: border-box significa non solo bordo, riempimento, margine, ecc. Tutti gli elementi verranno inseriti nell'elemento genitore.

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>


che diavolo è quella citazione
Chud37

0

La migliore soluzione cross browser (principalmente per il supporto IE) come ha detto @Steve è quella di creare un div 98px in larghezza e altezza rispetto ad aggiungere un bordo 1px attorno ad esso, oppure potresti creare un'immagine di sfondo per div 100x100 px e disegnarne un bordo.


0

Puoi guardare il contorno con l'offset, ma questo ha bisogno di qualche imbottitura per esistere sul tuo div. Oppure puoi assolutamente posizionare un bordo div all'interno, qualcosa del genere

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

Potrebbe essere necessario giocherellare con i margini sui div dei bordi falsi per adattarlo come preferisci.


0

Una soluzione più moderna potrebbe essere quella di utilizzare CSS variablese calc. calcè ampiamente supportato ma variablesnon è ancora in IE11 (polyfill disponibili).

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

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

Anche se questo utilizza alcuni calcoli, che le domande originali stavano cercando di evitare. Penso che sia il momento giusto per usare i calcoli in quanto sono controllati dal CSS stesso. Inoltre non ha bisogno di markup aggiuntivi o di appropriazione indebita di altre proprietà CSS che potrebbero essere necessarie in seguito.

Questa soluzione è davvero utile solo se non è necessaria un'altezza fissa .


0

Una soluzione che non ho visto menzionato sopra è il caso in cui hai il padding sul tuo input, cosa che faccio il 99% delle volte. Puoi fare qualcosa sulla falsariga di ...

input {
  padding: 8px;
}

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

Quello che mi piace di questo è che ho il menu completo di border + padding + proprietà di transizione per ogni lato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.