Steuern Sie die gestrichelte Randstrichlänge und den Abstand zwischen den Strichen

124

Ist es möglich, die Länge und den Abstand zwischen gestrichelten Randstrichen in CSS zu steuern?

Das folgende Beispiel wird zwischen den Browsern unterschiedlich angezeigt:

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

Große Unterschiede: IE 11 / Firefox / Chrome

IE 11 GrenzeFirefox GrenzeChromrand

Gibt es Methoden, mit denen das Erscheinungsbild gestrichelter Ränder besser gesteuert werden kann?

AntonAL
quelle

Antworten:

157

Der native Eigenschaftswert mit gestrichelten Rändern bietet keine Kontrolle über die Bindestriche selbst ... also bringen Sie die border-imageEigenschaft auf!

Brauen Sie Ihre eigene Grenze mit border-image

Kompatibilität : Es bietet hervorragende Browserunterstützung (IE 11 und alle modernen Browser). Ein normaler Rahmen kann als Fallback für ältere Browser festgelegt werden.

Lassen Sie uns diese erstellen

Diese Rahmen zeigen genau den gleichen Cross-Browser an!

Zielbeispiel Zielbeispiel mit größeren Lücken

Schritt 1 - Erstellen Sie ein geeignetes Bild

Dieses Beispiel ist 15 Pixel breit und 15 Pixel hoch und die Lücken sind derzeit 5 Pixel breit. Es ist ein PNG mit Transparenz.

So sieht es in Photoshop aus, wenn es vergrößert wird:

Beispiel Rand Bild Hintergrund gesprengt

So sieht es aus, wenn man skaliert:

Beispiel Rahmenbild Hintergrund Tatsächliche Größe

Kontrolle von Spalt und Hublänge

Um breitere / kürzere Lücken oder Striche zu erzeugen, vergrößern / verkürzen Sie die Lücken oder Striche im Bild.

Hier ist ein Bild mit größeren 10px Lücken:

Größere Lücken richtig skaliert = Größere Lücken im Maßstab

Schritt 2 - Erstellen des CSS - Dieses Beispiel erfordert 4 grundlegende Schritte

  1. Definieren Sie die border-image-Quelle :

    border-image-source:url("http://i.stack.imgur.com/wLdVc.png");  
  2. Optional - Definieren Sie die Rahmenbildbreite :

    border-image-width: 1;

    Der Standardwert ist 1. Er kann auch mit einem Pixelwert, einem Prozentwert oder einem anderen Vielfachen (1x, 2x, 3x usw.) festgelegt werden. Dies überschreibt jeden border-widthSatz.

  3. Definieren Sie das Border-Image-Slice :

    In diesem Beispiel beträgt die Dicke der oberen, rechten, unteren und linken Bildränder 2 Pixel, und es gibt keine Lücke außerhalb der Ränder. Daher beträgt unser Schnittwert 2:

    border-image-slice: 2; 

    Die Scheiben sehen so aus, 2 Pixel von oben, rechts, unten und links:

    Slices Beispiel

  4. Definieren Sie die Rahmenbildwiederholung :

    In diesem Beispiel möchten wir, dass sich das Muster gleichmäßig um unser div wiederholt. Also wählen wir:

    border-image-repeat: round;

Kurzschrift schreiben

Die obigen Eigenschaften können einzeln oder in Kurzform mithilfe des Rahmenbilds festgelegt werden :

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

Vollständiges Beispiel

Beachten Sie den border: dashed 4px #000Fallback. Nicht unterstützende Browser erhalten diesen Rahmen.

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

misterManSam
quelle
Beachten Sie, dass Sie angeben müssen border-style: solid(oder etwas Ähnliches), wenn Sie den Fallback weglassen.
Robbendebiene
Diese Lösung funktioniert nicht mit dem Attribut "Rahmenfarbe"
Rahmenfarbe
100

Zusätzlich zur border-imageEigenschaft gibt es einige andere Möglichkeiten, einen gestrichelten Rand mit Kontrolle über die Länge des Strichs und den Abstand zwischen ihnen zu erstellen. Sie werden nachfolgend beschrieben:

Methode 1: Verwenden von SVG

Wir können den gestrichelten Rand erstellen, indem wir ein pathoder ein polygonElement verwenden und die stroke-dasharrayEigenschaft festlegen. Die Eigenschaft verwendet zwei Parameter, wobei einer die Größe des Strichs definiert und der andere den Abstand zwischen ihnen bestimmt.

Vorteile:

  1. SVGs sind von Natur aus skalierbare Grafiken und können an alle Containerabmessungen angepasst werden.
  2. Kann sehr gut funktionieren, auch wenn es sich um einen handelt border-radius. Wir hätten nur die ersetzen müssenpathcircle in dieser Antwort ein Like (oder das pathin einen Kreis umwandeln) .
  3. Die Browserunterstützung für SVG ist ziemlich gut und Fallback kann mit VML für IE8- bereitgestellt werden.

Nachteile:

  1. Wenn sich die Abmessungen des Containers nicht proportional ändern, werden die Pfade tendenziell skaliert, was zu einer Änderung der Größe des Strichs und des Abstands zwischen ihnen führt (versuchen Sie, den Mauszeiger über das erste Feld im Snippet zu halten). Dies kann durch Hinzufügen gesteuert werden vector-effect='non-scaling-stroke'(wie im zweiten Feld), aber die Browserunterstützung für diese Eigenschaft ist im IE gleich Null.


Methode 2: Verwenden von Verläufen

Wir können mehrere linear-gradientHintergrundbilder verwenden und sie entsprechend positionieren, um einen gestrichelten Randeffekt zu erzielen. Dies kann auch mit a erfolgen repeating-linear-gradient, es gibt jedoch keine große Verbesserung, da ein sich wiederholender Gradient verwendet wird, da jeder Gradient nur in eine Richtung wiederholt werden muss.

Vorteile:

  1. Skalierbar und kann angepasst werden, auch wenn die Abmessungen des Containers dynamisch sind.
  2. Verwendet keine zusätzlichen Pseudoelemente, was bedeutet, dass sie für jede andere mögliche Verwendung beiseite gelegt werden können.

Nachteile:

  1. Browserunterstützung für lineare Verläufe ist vergleichsweise geringer und dies ist ein No-Go, wenn Sie IE 9- unterstützen möchten. Selbst Bibliotheken wie CSS3 PIE unterstützen die Erstellung von Verlaufsmustern in IE8- nicht.
  2. Kann nicht verwendet werden, wenn border-radiuses beteiligt ist, da die Hintergründe nicht basierend auf gekrümmt sind border-radius. Sie werden stattdessen abgeschnitten.

Methode 3: Box Shadows

Wir können einen kleinen Balken (in Form des Strichs) mit Pseudoelementen erstellen und dann mehrere erstellen box-shadow Versionen davon erstellen, um einen Rahmen wie im folgenden Snippet zu erstellen.

Wenn der Strich eine quadratische Form hat, würde ein einzelnes Pseudoelement ausreichen, aber wenn es ein Rechteck ist, würden wir ein Pseudoelement für die oberen + unteren Ränder und ein anderes für die linken + rechten Ränder benötigen. Dies liegt daran, dass sich Höhe und Breite des Strichs am oberen Rand von denen auf der linken Seite unterscheiden.

Vorteile:

  1. Die Abmessungen des Strichs können durch Ändern der Abmessungen des Pseudoelements gesteuert werden. Der Abstand kann durch Ändern des Abstands zwischen den einzelnen Schatten gesteuert werden.
  2. Ein sehr einzigartiger Effekt kann erzielt werden, indem für jeden Kastenschatten eine andere Farbe hinzugefügt wird.

Nachteile:

  1. Da wir die Abmessungen des Strichs und den Abstand manuell einstellen müssen, ist dieser Ansatz nicht gut, wenn die Abmessungen des übergeordneten Felds dynamisch sind.
  2. IE8 und niedriger unterstützen keinen Box Shadow . Dies kann jedoch durch die Verwendung von Bibliotheken wie CSS3 PIE überwunden werden.
  3. Kann verwendet werden, border-radiusaber das Positionieren wäre sehr schwierig, wenn Punkte auf einem Kreis (und möglicherweise sogar transform) gefunden werden müssten .

Harry
quelle
Wenn Sie die SVG-Lösung verwenden pointer-events:nonemöchten, empfehle ich, sie zu SVG hinzuzufügen, um mit dem Inhalt interagieren zu können.
Sodj
Wunderbare Antwort.
Abweichung
22

Kurz: Nein, das ist es nicht. Sie müssen stattdessen mit Bildern arbeiten.

Ham Vocke
quelle
5
Diese Antwort ist ab 2018 veraltet
godblessstrawberry
2
@ WilliamHampshire Ich würde mit dieser Technik gehen youtu.be/vs34f9FiHps?t=779 aber überprüfen Sie akzeptierte Antwort, Sie könnten andere Lösungen besser
mögen
1
@godblessstrawberry Danke !! Aber das ist SVG, also immer noch nicht nur CSS ...
William Hampshire
1
@ WilliamHampshire gibt es Box-Shadow-Lösung in dem Thread, den ich Antwort von Harry meinte
godblessstrawberry
@godblessstrawberry Hast du die Lösung ausprobiert? Die Lösung zeichnete die gestrichelte Linie Segment für Segment. Es ist nur ein POC und in der Praxis nutzlos!
Yu Jianrong
6

Es gibt ein cooles Tool von @kovart namens Dashed Border Generator .

Es verwendet ein SVG als Hintergrundbild, um das gewünschte Strichstrich-Array einzustellen, und ist sehr praktisch.

Sie würden es dann einfach als Hintergrundeigenschaft für Ihr Element anstelle des Rahmens verwenden:

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;
}
Balthazar
quelle
Dies ist eine einfache, einfache und schnelle Lösung
Jamesioppolo
Das hat gut funktioniert!
Kevin Raffay
3

Die Hublänge hängt von der Hubbreite ab. Sie können die Länge erhöhen, indem Sie die Breite erhöhen und einen Teil des Rahmens durch das innere Element ausblenden.

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

ili4
quelle
Auf diese Weise können Sie jedoch nicht auf den Inhalt des ursprünglichen Elements klicken, da das Pseudoelement "nach" es abdeckt. Der beste Weg ist also, SVG zu verwenden.
ili4
Sie können hinzufügen pointer-events: none, um das Overlay-Problem zu vermeiden.
8.
0

Ich hatte erst kürzlich das gleiche Problem.

Ich habe es geschafft, es mit zwei absolut positionierten Divs zu lösen, die den Rand tragen (einer für horizontal und einer für vertikal) und sie dann zu transformieren. Die äußere Box muss nur relativ positioniert sein.

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

Hinweis: In diesem Beispiel habe ich Tachyonen verwendet, aber ich denke, die Klassen sind selbsterklärend.

Razzz
quelle
-1

Dadurch wird ein orange-grauer Rand mit der Klasse = "myclass" auf dem div erstellt.

.myclass {
    outline:dashed darkorange  12px;
    border:solid slategray  14px;
    outline-offset:-14px;
}
BJC
quelle
Mit "Bessere Kontrolle über das Erscheinungsbild der gestrichelten Ränder" bedeutet das OP (Original Poster), dass er die Länge jedes Strichs steuern möchte, wie am Anfang der Frage angegeben. Entschuldigen Sie die Verwirrung.
Skylar