Controlla la lunghezza del tratto del bordo tratteggiato e la distanza tra i tratti


124

È possibile controllare la lunghezza e la distanza tra i tratti del bordo tratteggiato in CSS?

Questo esempio di seguito viene visualizzato in modo diverso tra i browser:

div {
  border: dashed 4px #000;
  padding: 20px;
  display: inline-block;
}
<div>I have a dashed border!</div>

Grandi differenze: IE 11 / Firefox / Chrome

Confine di IE 11Firefox BorderBordo cromato

Esistono metodi in grado di fornire un maggiore controllo dell'aspetto dei bordi tratteggiati?

Risposte:



157

Il valore della proprietà del bordo tratteggiato nativo non offre il controllo sui trattini stessi ... quindi porta la border-imageproprietà!

Crea il tuo confine con border-image

Compatibilità : offre un ottimo supporto del browser (IE 11 e tutti i browser moderni). È possibile impostare un bordo normale come riserva per i browser meno recenti.

Creiamo questi

Questi bordi mostreranno esattamente lo stesso cross-browser!

Esempio di obiettivo Esempio di obiettivo con spazi più ampi

Passaggio 1: creare un'immagine adatta

Questo esempio è largo 15 pixel per 15 pixel di altezza e gli spazi sono attualmente larghi 5 px. È un .png con trasparenza.

Ecco come appare in Photoshop quando ingrandito:

Esempio di sfondo dell'immagine del bordo esploso

Ecco come appare in scala:

Dimensioni reali dello sfondo dell'immagine del bordo di esempio

Controllo della distanza e della lunghezza della corsa

Per creare spazi o tratti più ampi / più corti, allargare / accorciare gli spazi o i tratti nell'immagine.

Ecco un'immagine con spazi più ampi di 10 px:

Spazi più ampi correttamente ridimensionato = Divari più grandi da scalare

Passaggio 2: creare il CSS: questo esempio richiede 4 passaggi di base

  1. Definisci l' origine dell'immagine del bordo :

    border-image-source:url("http://i.stack.imgur.com/wLdVc.png");  
  2. Facoltativo : definire la larghezza dell'immagine del bordo :

    border-image-width: 1;

    Il valore predefinito è 1. Può anche essere impostato con un valore in pixel, un valore percentuale o un altro multiplo (1x, 2x, 3x ecc.). Questo sovrascrive qualsiasi border-widthset.

  3. Definisci la sezione di immagine del bordo :

    In questo esempio, lo spessore dei bordi superiore, destro, inferiore e sinistro delle immagini è 2px e non c'è spazio al di fuori di essi, quindi il nostro valore di slice è 2:

    border-image-slice: 2; 

    Le sezioni hanno questo aspetto, a 2 pixel dall'alto, da destra, dal basso e da sinistra:

    Esempio di fette

  4. Definisci il bordo-immagine-ripetizione :

    In questo esempio, vogliamo che il pattern si ripeta in modo uniforme attorno al nostro div. Quindi scegliamo:

    border-image-repeat: round;

Scrivere stenografia

Le proprietà sopra possono essere impostate individualmente o in forma abbreviata utilizzando border-image :

border-image: url("http://i.stack.imgur.com/wLdVc.png") 2 round;

Esempio completo

Nota il border: dashed 4px #000fallback. I browser non supportati riceveranno questo bordo.

.bordered {
  display: inline-block;
  padding: 20px;
  /* Fallback dashed border
     - the 4px width here is overwritten with the border-image-width (if set)
     - the border-image-width can be omitted below if it is the same as the 4px here
  */
  border: dashed 4px #000;
  
  /* Individual border image properties */
  border-image-source: url("http://i.stack.imgur.com/wLdVc.png");
  border-image-slice: 2;
  border-image-repeat: round;  
  
  /* or use the shorthand border-image */
  border-image: url("http://i.stack.imgur.com/wLdVc.png") 2 round;
}


/*The border image of this one creates wider gaps*/
.largeGaps {
  border-image-source: url("http://i.stack.imgur.com/LKclP.png");
  margin: 0 20px;
}
<div class="bordered">This is bordered!</div>

<div class="bordered largeGaps">This is bordered and has larger gaps!</div>


Nota che devi specificare border-style: solid(o qualcosa di simile) se ometti il ​​fallback.
Robbendebiene

Questa soluzione non funziona con l'attributo "border-color"
Michael Rovinsky

102

Oltre alla border-imageproprietà, ci sono alcuni altri modi per creare un bordo tratteggiato con il controllo sulla lunghezza del tratto e sulla distanza tra loro. Sono descritti di seguito:

Metodo 1: utilizzo di SVG

Possiamo creare il bordo tratteggiato utilizzando pathun polygonelemento o e impostando la stroke-dasharrayproprietà. La proprietà accetta due parametri in cui uno definisce la dimensione del trattino e l'altro determina lo spazio tra di loro.

Professionisti:

  1. Gli SVG per natura sono grafici scalabili e possono adattarsi a qualsiasi dimensione del contenitore.
  2. Può funzionare molto bene anche se è border-radiuscoinvolto. Dovremmo semplicemente sostituire il pathcon un circlesimile in questa risposta (o) convertire il pathin un cerchio.
  3. Il supporto del browser per SVG è abbastanza buono e il fallback può essere fornito utilizzando VML per IE8-.

Contro:

  1. Quando le dimensioni del contenitore non cambiano proporzionalmente, i percorsi tendono a ridimensionarsi con conseguente modifica delle dimensioni del trattino e dello spazio tra di essi (prova a passare il mouse sulla prima casella dello snippet). Questo può essere controllato aggiungendo vector-effect='non-scaling-stroke'(come nella seconda casella) ma il supporto del browser per questa proprietà è nullo in IE.


Metodo 2: utilizzo delle sfumature

Possiamo utilizzare più linear-gradientimmagini di sfondo e posizionarle in modo appropriato per creare un effetto bordo tratteggiato. Questo può essere fatto anche con a, repeating-linear-gradientma non ci sono molti miglioramenti a causa dell'uso di un gradiente ripetuto poiché abbiamo bisogno che ogni gradiente si ripeta in una sola direzione.

Professionisti:

  1. Scalabile e adattabile anche se le dimensioni del contenitore sono dinamiche.
  2. Non fa uso di pseudo-elementi extra, il che significa che possono essere tenuti da parte per qualsiasi altro potenziale utilizzo.

Contro:

  1. Il supporto del browser per i gradienti lineari è relativamente inferiore e questo è un no-go se si desidera supportare IE 9-. Anche le librerie come CSS3 PIE non supportano la creazione di modelli di gradiente in IE8-.
  2. Non può essere utilizzato quando border-radiusè coinvolto perché gli sfondi non si curvano in base a border-radius. Invece vengono tagliati.

Metodo 3: Box Shadows

Possiamo creare una piccola barra (a forma di trattino) usando pseudo-elementi e quindi crearne più box-shadowversioni per creare un bordo come nello snippet sottostante.

Se il trattino è di forma quadrata, sarebbe sufficiente un singolo pseudo-elemento, ma se è un rettangolo, avremmo bisogno di uno pseudo-elemento per i bordi superiore + inferiore e un altro per i bordi sinistro + destro. Questo perché l'altezza e la larghezza del trattino sul bordo superiore saranno diverse da quelle a sinistra.

Professionisti:

  1. Le dimensioni del trattino sono controllabili modificando le dimensioni dello pseudo-elemento. La spaziatura è controllabile modificando lo spazio tra ogni ombra.
  2. È possibile ottenere un effetto davvero unico aggiungendo un colore diverso per ciascuna ombra della scatola.

Contro:

  1. Dato che dobbiamo impostare manualmente le dimensioni del trattino e la spaziatura, questo approccio non è valido quando le dimensioni del riquadro principale sono dinamiche.
  2. IE8 e versioni precedenti non supportano il box shadow . Tuttavia, questo può essere superato utilizzando librerie come CSS3 PIE.
  3. Possono essere usati con border-radiusma posizionarli sarebbe molto complicato se dovessi trovare punti su un cerchio (e forse anche transform).


Se intendi utilizzare la soluzione svg, ti consiglio di aggiungerla pointer-events:nonea svg in modo da poter interagire con il contenuto.
Sodj

Meravigliosa risposta.
Deviance

22

Breve: No, non lo è. Dovrai invece lavorare con le immagini.


5
questa risposta è obsoleta a partire dal 2018
godblessstrawberry

2
@WilliamHampshire Vorrei andare con questa tecnica youtu.be/vs34f9FiHps?t=779 ma controlla la risposta accettata, potresti preferire altre soluzioni
godblessstrawberry

1
@godblessstrawberry Thanks !! Ma sta usando SVG, quindi non usi ancora solo CSS ...
Kyle Krzeski

1
@WilliamHampshire c'è una soluzione box-shadow nel thread Volevo dire risposta di Harry
godblessstrawberry

@godblessstrawberry Hai provato la soluzione? La soluzione ha disegnato la linea tratteggiata segmento per segmento. È solo un POC e inutile in pratica!
Yu Jianrong

6

C'è un fantastico strumento creato da @kovart chiamato generatore di bordi tratteggiati .

Usa un svg come immagine di sfondo per consentire l'impostazione dell'array di trattini del tratto desiderato ed è piuttosto conveniente.

Dovresti quindi usarlo semplicemente come proprietà di sfondo sul tuo elemento al posto del bordo:

div {
  background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' stroke='black' stroke-width='4' stroke-dasharray='6%2c 14' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e");
  padding: 20px;
  display: inline-block;
}

Questa è una soluzione semplice, facile e veloce
jamesioppolo

Ha funzionato bene!
Kevin Raffay,

3

La lunghezza del tratto dipende dalla larghezza del tratto. È possibile aumentare la lunghezza aumentando la larghezza e nascondere parte del bordo per elemento interno.

.thin {
    background: #F4FFF3;
    border: 2px dashed #3FA535;  
    position: relative;
}

.thin:after {
    content: '';
    position: absolute;
    left: -1px;
    top: -1px;
    right: -1px;
    bottom: -1px;
    border: 1px solid #F4FFF3;
}

https://jsfiddle.net/ok6srt2z/


Ma in questo modo non sarai in grado di fare clic sul contenuto dell'elemento originale perché lo pseudoelemento "dopo" lo coprirà. Quindi il modo migliore è usare SVG.
ili4

È possibile aggiungere pointer-events: noneper evitare il problema di sovrapposizione.
benJ

0

Di recente ho avuto lo stesso problema.

Sono riuscito a risolverlo con due div assolutamente posizionati portando il bordo (uno per l'orizzontale e uno per il verticale), e poi trasformandoli. La scatola esterna deve solo essere posizionata relativamente.

<div class="relative">
    <div class="absolute absolute--fill overflow-hidden">
        <div class="absolute absolute--fill b--dashed b--red"
            style="
                border-width: 4px 0px 4px 0px;
                transform: scaleX(2);
        "></div>
        <div class="absolute absolute--fill b--dashed b--red"
            style="
                border-width: 0px 4px 0px 4px;
                transform: scaleY(2);
        "></div>
    </div>

    <div> {{Box content goes here}} </div>
</div>

Nota: ho usato i tachioni in questo esempio, ma immagino che le classi si spieghino da sole.


-1

Questo creerà un bordo arancione e grigio usando class = "myclass" sul div.

.myclass {
    outline:dashed darkorange  12px;
    border:solid slategray  14px;
    outline-offset:-14px;
}

Con "fornire un maggiore controllo dell'aspetto dei bordi tratteggiati", l'OP (Poster originale) significa che vuole controllare la lunghezza di ogni trattino, come indicato all'inizio della domanda. Ci scusiamo per l'eventuale confusione.
Skylar
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.