In CSS können wir auf currentColor zugreifen, was enorm nützlich ist. Leider haben wir keinen Zugriff auf etwas wie currentBackgroundColor, und die color-mod() Funktion ist noch weit entfernt.
Davon abgesehen bin ich sicher, dass ich nicht allein bin, wenn ich sage, dass ich einige Links basierend auf dem Kontext gestalten und Farben invertieren möchte, wenn der Link gehovert oder fokussiert wird. Mit benutzerdefinierten CSS-Eigenschaften und einigen einfachen Hilfsklassen können wir dank der kaskadierenden Natur unserer Stile ein ziemlich leistungsfähiges Ergebnis erzielen.
Siehe den Pen
Kontextbezogene Farbgebung von Links mit Hilfsklassen und benutzerdefinierten Eigenschaften von Christopher Kirk-Nielsen (@chriskirknielsen)
auf CodePen.
Um dies zu erreichen, müssen wir unsere Text- und Hintergrundfarben mit Hilfsklassen (die unsere benutzerdefinierten Eigenschaften enthalten) angeben. Wir werden diese dann verwenden, um die Farbe unserer Unterstreichung zu definieren, die sich zu einem vollen Hintergrund ausdehnt, wenn gehovert wird.
Beginnen wir mit unserem Markup
<section class="u-bg--green">
<p class="u-color--dark">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, <a href="#">sed do eiusmod tempor incididunt</a> ut labore et dolore magna aliqua. Aliquam sem fringilla ut morbi tincidunt. Maecenas accumsan lacus vel facilisis. Posuere sollicitudin aliquam ultrices sagittis orci a scelerisque purus semper.
</p>
</section>
Dies ergibt uns einen Block, der einen Absatz mit einem Link enthält. Richten wir unsere Hilfsklassen ein. Ich werde vier Farben definieren, die ich auf Color Hunt gefunden habe. Wir erstellen eine Klasse für die color-Eigenschaft und eine Klasse für die background-color-Eigenschaft, die jeweils eine Variable zur Zuweisung des Farbwertes haben (--c und --bg, bzw.). Wenn wir also unsere grüne Farbe definieren würden, hätten wir Folgendes
.u-color--green {
--c: #08ffc8;
color: #08ffc8;
}
.u-bg--green {
--bg: #08ffc8;
background-color: #08ffc8;
}
Wenn Sie ein Sass-Benutzer sind, können Sie diesen Prozess mit einer Map automatisieren und die Werte durchlaufen, um die Farb- und Hintergrundklassen automatisch zu erstellen. Beachten Sie, dass dies nicht erforderlich ist, sondern lediglich eine Möglichkeit, viele farbbezogene Hilfsklassen automatisch zu erstellen. Dies kann sehr nützlich sein, aber behalten Sie Ihren Verbrauch im Auge, damit Sie nicht beispielsweise sieben Hintergrundklassen erstellen, die auf Ihrer Website nie verwendet werden. Davon abgesehen, hier ist der Sass-Code, um unsere Klassen zu generieren
$colors: ( // Define a named list of our colors
'green': #08ffc8,
'light': #fff7f7,
'grey': #dadada,
'dark': #204969
);
@each $n, $c in $colors { // $n is the key, $c is the value
.u-color--#{$n} {
--c: #{$c};
color: #{$c};
}
.u-bg--#{$n} {
--bg: #{$c};
background-color: #{$c};
}
}
Was passiert, wenn wir vergessen, eine Hilfsklasse in unserem Markup anzuwenden? Die --c-Variable würde natürlich currentColor verwenden… und das --bg auch! Definieren wir ein Top-Level-Standard, um dies zu vermeiden
html {
--c: #000000;
--bg: #ffffff;
}
Cool! Jetzt müssen wir nur noch unseren Link gestalten. Wir werden alle Links in diesem Artikel mit unserem bewährten <a>-Element gestalten, aber Sie könnten genauso gut eine Klasse wie .fancy-link hinzufügen.
Zusätzlich, wie Sie vielleicht wissen, sollten Links in der Reihenfolge "LoVe-HAte" gestaltet werden: :link, :visited, :hover (und :focus!) und :active. Wir könnten :any-link verwenden, aber die Browserunterstützung ist nicht so gut wie bei benutzerdefinierten CSS-Eigenschaften. (Wenn es andersherum gewesen wäre, wäre es kein großes Problem gewesen.)
Wir können beginnen, die Stile für unsere Links zu deklarieren, indem wir eine akzeptable Erfahrung für ältere Browser bereitstellen und dann auf die Unterstützung von benutzerdefinierten Eigenschaften prüfen
/* Styles for older browsers */
a {
color: inherit;
text-decoration: underline;
}
a:hover,
a:focus,
a:active {
text-decoration: none;
outline: .0625em solid currentColor;
outline-offset: .0625em;
}
a:active {
outline-width: .125em;
}
@supports (--a: b) { /* Check for CSS variable support */
/* Default variable values */
html {
--c: #000000;
--bg: #ffffff;
}
a {
/*
* Basic link styles go here...
*/
}
}
Erstellen wir dann die grundlegenden Link-Stile. Wir werden benutzerdefinierte Eigenschaften verwenden, um unsere Stile so DRY (Don't Repeat Yourself) wie möglich zu gestalten.
Zuerst müssen wir unsere Variablen einrichten. Wir möchten eine --space-Variable definieren, die für verschiedene Eigenschaften verwendet wird, um etwas Platz um den Text zu schaffen. Die Farbe des Links wird ebenfalls in einer Variable mit --link-color definiert, mit einem Standardwert von currentColor. Die gefälschte Unterstreichung wird mit einem Hintergrundbild erzeugt, dessen Größe je nach Zustand mit --bg-size angepasst wird, standardmäßig auf den Wert von --space gesetzt. Schließlich, um dem Ganzen etwas Spaß zu verleihen, werden wir auch einen gefälschten Rand um den Link simulieren, wenn er :active ist, mit box-shadow, daher definieren wir seine Größe in --shadow-size, die in seinem inaktiven Zustand auf 0 gesetzt ist. Das ergibt uns
--space: .125em;
--link-color: currentColor;
--bg-size: var(--space);
--shadow-size: 0;
Wir müssen zuerst die Fallback-Stile anpassen. Wir setzen unsere color, um unsere benutzerdefinierte Eigenschaft zu verwenden, und entfernen die Standard-Unterstreichung
color: var(--link-color);
text-decoration: none;
Erstellen wir als Nächstes unsere gefälschte Unterstreichung. Das Bild wird ein linearer Verlauf mit zwei identischen Start- und Endpunkten sein: die Textfarbe --c. Wir stellen sicher, dass es nur horizontal wiederholt wird mit background-repeat: repeat-x; und platzieren es unten in unserem Element mit background-position: 0 100%;. Schließlich geben wir ihm seine Größe, die horizontal 100% und vertikal den Wert von --bg-size beträgt. Wir landen bei diesem
background-image: linear-gradient(var(--c, currentColor), var(--c, currentColor));
background-repeat: repeat-x;
background-position: 0 100%;
background-size: 100% var(--bg-size);
Für unseren :active-Zustand definieren wir auch den Box-Shadow, der nicht existent sein wird, aber mit unserer Variable zum Leben erweckt werden kann: box-shadow: 0 0 0 var(--shadow-size, 0) var(--c);
Das ist der Großteil der grundlegenden Stile. Jetzt müssen wir neue Werte für unsere Variablen zuweisen, je nach Link-Zustand.
Die :link und :visited sind das, was unsere Benutzer sehen, wenn der Link "leerlaufend" ist. Da wir alles bereits eingerichtet haben, ist dies ein kurzer Regelblock. Obwohl wir diesen Schritt technisch überspringen und die --c-Variable in der anfänglichen Zuweisung von --link-color deklarieren könnten, weise ich sie hier zu, um jeden Schritt unserer Stile glasklar zu machen
a:link,
a:visited {
--link-color: var(--c);
}
Der Link sieht jetzt ziemlich cool aus, aber wenn wir mit ihm interagieren, passiert nichts… Erstellen wir als Nächstes diese Stile. Zwei Dinge müssen passieren: Der Hintergrund muss die gesamte verfügbare Höhe einnehmen (d. h. 100%), und die Textfarbe muss die des Hintergrunds werden, da der Hintergrund die Textfarbe ist (verwirrend, richtig?). Das erste ist einfach genug: --bg-size: 100%;. Für die Textfarbe weisen wir die --bg-Variable zu, wie folgt: --link-color: var(--bg);. Zusammen mit unseren Pseudo-Klassen-Selektoren erhalten wir
a:hover,
a:focus,
a:active {
--bg-size: 100%;
--link-color: var(--bg);
}
Schauen Sie, wie diese Unterstreichung beim Hovern oder Fokussieren zu einem vollen Hintergrund wird! Als Bonus können wir einen gefälschten Rand hinzufügen, wenn der Link angeklickt wird, indem wir die --shadow-size erhöhen, wofür unsere --space-Variable wieder einmal nützlich sein wird
a:active {
--shadow-size: var(--space);
}
Wir sind jetzt so gut wie fertig! Es sieht jedoch etwas zu generisch aus, fügen wir also einen Übergang, etwas Polsterung und abgerundete Ecken hinzu, und stellen wir außerdem sicher, dass es gut aussieht, wenn der Link mehrere Zeilen umfasst!
Für die Übergänge müssen wir nur color, background-size und box-shadow animieren. Die Dauer liegt bei Ihnen, aber da Links im Allgemeinen etwa 20 Pixel hoch sind, können wir eine kurze Dauer einstellen. Um dies reibungsloser zu gestalten, verwenden wir schließlich die ease-in-out-Auslöschung. Das summiert sich zu
transition-property: color, background-size, box-shadow;
transition-duration: 150ms;
transition-timing-function: ease-in-out;
will-change: color, background-size, box-shadow; /* lets the browser know which properties are about to be manipulated. */
Als Nächstes weisen wir unsere --space-Variable padding und border-radius zu, aber machen Sie sich keine Sorgen um ersteres – da wir es nicht als inline-block definiert haben, wird das Padding den vertikalen Rhythmus unseres Textblocks nicht stören. Das bedeutet, Sie können die Höhe Ihres Hintergrunds anpassen, ohne sich über Zeilenabstände Gedanken machen zu müssen! (stellen Sie einfach sicher, dass Sie Ihre Werte testen)
padding: var(--space);
border-radius: var(--space);
Schließlich, um sicherzustellen, dass die Stile auf mehreren Zeilen korrekt angewendet werden, müssen wir nur box-decoration-break: clone; (und Präfixe, falls gewünscht) hinzufügen, und das war's.
Wenn Sie fertig sind, sollten wir diese Stile haben
/* Styles for older browsers */
a {
color: inherit;
text-decoration: underline;
}
a:hover,
a:focus,
a:active {
text-decoration: none;
outline: .0625em solid currentColor;
outline-offset: .0625em;
}
a:active {
outline-width: .125em;
}
/* Basic link styles for modern browsers */
@supports (--a: b) {
/* Default variable values */
html {
--c: #000000;
--bg: #ffffff;
}
a {
/* Variables */
--space: .125em;
--link-color: currentColor;
--bg-size: var(--space);
--shadow-size: 0;
/* Layout */
padding: var(--space); /* Inline elements won't affect vertical rhythm, so we don't need to specify each direction */
/* Text styles */
color: var(--link-color);/* Use the variable for our color */
text-decoration: none; /* Remove the default underline */
/* Box styles */
border-radius: var(--space); /* Make it a tiny bit fancier ✨ */
background-image: linear-gradient(var(--c, currentColor), var(--c, currentColor));
background-repeat: repeat-x;
background-position: 0 100%;
background-size: 100% var(--bg-size);
box-shadow: 0 0 0 var(--shadow-size, 0) var(--c, currentColor); /* Used in the :active state */
box-decoration-break: clone; /* Ensure the styles repeat on links spanning multiple lines */
/* Transition declarations */
transition-property: color, background-size, box-shadow;
transition-duration: 150ms;
transition-timing-function: ease-in-out;
will-change: color, background-size, box-shadow;
}
/* Idle states */
a:link,
a:visited {
--link-color: var(--c, currentColor); /* Use --c, or fallback to currentColor */
}
/* Interacted-with states */
a:hover,
a:focus,
a:active {
--bg-size: 100%;
--link-color: var(--bg);
}
/* Active state */
a:active {
--shadow-size: var(--space); /* Define the box-shadow size */
}
}
Sicher, es ist etwas komplizierter als nur eine Unterstreichung, aber in Verbindung mit Hilfsklassen, die Ihnen jederzeitigen Zugriff auf Text- und Hintergrundfarben ermöglichen, ist es eine ziemlich gute progressive Verbesserung.
Es liegt an Ihnen, dies mit drei Variablen für jede Farbe zu verbessern, entweder im RGB- oder HSL-Format, um die Deckkraft usw. anzupassen. Sie können auch einen text-shadow hinzufügen, um text-decoration-skip-ink zu simulieren!
Was passiert, wenn Sie die Farben nicht mit Hilfsklassen anwenden? Sehen Sie es sich selbst an! Alles, was Sie tun müssen, ist, einen sinnvollen Standard für Ihre Variablen zu definieren.
Ich verstehe es nicht…
Hallo!
Wenn Sie vergessen würden, einem Abschnitt Hilfsklassen hinzuzufügen, und dieser Abschnitt einen Link enthielte, würden beim Hovern/Fokussieren Probleme auftreten. Versuchen Sie, die Standard-CSS-Variablen in
htmlzu entfernen, um zu sehen, was ich meine; der letzte Abschnitt hat keine hinzugefügten Hilfsklassen.Sie könnten sicherstellen, dass die Links nur in einem Hilfsklassenkontext funktionieren, mit etwas wie
[class*="u-bg--"] [class*="u-color--"] a, aber das würde den Selektoren etwas Komplexität hinzufügen, was ich für dieses Tutorial vermeiden wollte.Bitte lassen Sie mich wissen, ob das alles geklärt hat; ich beantworte gerne alle Fragen, die Sie dazu haben!