The currentColor
property of CSS is very practical, but unfortunately, we do not have a similar currentBackgroundColor
property, and color-mod()
function is not widely supported yet.
Therefore, many developers want to style the links according to the context and reverse the color when hovering or focusing. With CSS custom properties and some simple utility classes, we can use the cascading features of styles to achieve powerful effects.
To do this, we need to use utility classes (including custom properties) to specify text and background colors, then use these classes to define the underlined colors and expand to the full background when hovering.
First, let’s look at the HTML structure:
<p> Lorem ipsum dolor sit amet, consectetur apiscing elit, <a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">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 sclerisque purus semper. </p>
This code contains a paragraph and a link. Next, we set up the utility class. I will define four colors on Color Hunt, creating the color attribute class and the background color attribute class, each containing a variable to assign values ( --c
and --bg
respectively). For example, the corresponding classes of green color are as follows:
.u-color--green { --c: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b08ffc8; color: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b08ffc8; } .u-bg--green { --bg: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b08ffc8; background-color: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b08ffc8; }
Sass users can use mappings and loops to automatically create color and background classes. This is not necessary, just one way to automatically create many color-related utility classes. This is very useful, but keep track of usage and avoid creating unused classes. Here is the Sass code that generates these classes:
$colors: ( // Define the color list 'green': https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b08ffc8, 'light': https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15bffff7f7, 'grey': https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15bdadada, 'dark': https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b204969 ); @each $n, $c in $colors { // $n is the key, $c is the value.u-color--https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b{$n} { --c: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b{$c}; color: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b{$c}; } .u-bg--https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b{$n} { --bg: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b{$c}; background-color: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b{$c}; } }
If you forget to apply the utility class in HTML, the --c
variable will use currentColor
, and so will --bg
! To avoid this, we define a top-level default:
html { --c: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b000000; --bg: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15bffffff; }
Now, just style the link. In this article we will style all<a></a>
elements, but it is also easy to add classes like .fancy-link
.
The style of the link should follow the "LoVe-HAte" order: :link
, :visited
, :hover
(and :focus
!) and :active
. We can use :any-link
, but the browser support is not as good as CSS custom properties.
We can first declare the link style, provide an acceptable experience for older browsers, and then check custom attribute support:
/* Styles of old 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 CSS variables to support*/ /* Default variable value*/ html { --c: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b000000; --bg: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15bffffff; } a { /* Basic link style*/ } }
Next create the basic link style. We will use custom properties to make the style as DRY as possible.
First, we need to set the variables. We want to define a --space
variable for various properties and add some space around the text. The link color will also be defined in --link-color
variable, defaulting to currentColor
. The fake underscore will be generated using the background image, and its size will be adjusted according to the state using the --bg-size
variable, which defaults to --space
value. Finally, for added fun, we will also simulate a border when the link is in :active
, so we will define its size in --shadow-size
, set to 0 in inactive state. This gives us:
--space: .125em; --link-color: currentColor; --bg-size: var(--space); --shadow-size: 0;
First, we need to adjust the fallback style. We will set the color to use custom properties and remove the default underscore:
color: var(--link-color); text-decoration: none;
Next create a fake underscore. The image will be a linear gradient with two identical start and end points: text color --c
. We make sure it only repeats background-repeat: repeat-x;
, and places it at the bottom of the element background-position: 0 100%;
. Finally, we give it the size, horizontally 100% and vertically --bg-size
value. Finally got:
background-image: linear-gradient(var(--c, currentColor), var(--c, currentColor)); background-repeat: repeat-x; background-position: 0 100%; background-size: 100% var(--bg-size);
For :active
state, we also define box-shadow
, which will not exist, but with our variable, it will be able to take effect: box-shadow: 0 0 0 var(--shadow-size, 0) var(--c);
This is most of the basic style. Now we need to assign a new value to the variable based on the link state.
:link
and :visited
are what users see when the link is in "idle". Since we've set everything up, this is a short rule set. Although we can declare the --c
variable in the initial assignment of --link-color
, I'm assigning here to make every step of our style clear:
a:link, a: visited { --link-color: var(--c); }
The link looks cool now, but if we interact with it, nothing will happen... Next create these styles. Two things need to happen: the background must occupy all available heights (i.e. 100%) and the text color must be changed to the color of the background because the background is the text color (confusing, right?). The first one is simple: --bg-size: 100%;
. For text color, we assign the --bg
variable as follows: --link-color: var(--bg);
. Together with our pseudo-class selector, we end up with:
a:hover, a:focus, a:active { --bg-size: 100%; --link-color: var(--bg); }
Look, the underline becomes the complete background when hovering or focusing! As a bonus, we can add mock borders when clicking on the link by adding --shadow-size
, and our --space
variable will come in handy again:
a:active { --shadow-size: var(--space); }
We are almost done now! However, it looks a bit too generic, so let's add a transition, some padding and rounded corners and make sure it looks great too if the link spans multiple rows!
For the transition, we only need the animation color, background size, and box-shadow
. The duration is up to you, but given that the link is usually about 20 pixels high, we can set a shorter duration. Finally, to make it look smoother, let's use ease-in-out
to ease. This is summarized as:
transition-property: color, background-size, box-shadow; transition-duration: 150ms; transition-timing-function: ease-in-out; will-change: color, background-size, box-shadow; /* Let the browser know which properties are about to be operated. */
Next, we assign the --space
variable to padding
and border-radius
, but don't worry about the former - since we don't define it as an inline block, padding
won't mess up the vertical rhythm of the text block. (Just make sure to test your value)
padding: var(--space); border-radius: var(--space);
Finally, to make sure the style is applied correctly on multiple lines, we just need to add box-decoration-break: clone;
(and prefixes, if you prefer), and that's it.
Once done, we should have these styles:
/* Styles of old 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 value*/ html { --c: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b000000; --bg: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15bffffff; } a { /* Variable*/ --space: .125em; --link-color: currentColor; --bg-size: var(--space); --shadow-size: 0; /* Layout*/ padding: var(--space); /* Inline elements do not affect the vertical rhythm, so we don't need to specify each direction*/ /* Text style*/ color: var(--link-color); /* Set color with variables*/ text-decoration: none; /* Delete the default underscore*/ /* Box style*/ border-radius: var(--space); /* Make it more beautiful✨ */ 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); /* Use in:active state*/ box-decoration-break: clone; /* Make sure the style is repeated on links spanning multiple lines*/ /* Transition Statement*/ transition-property: color, background-size, box-shadow; transition-duration: 150ms; transition-timing-function: ease-in-out; will-change: color, background-size, box-shadow; } /* Idle state*/ a:link, a: visited { --link-color: var(--c, currentColor); /* Use --c, or fall back to currentColor */ } /* Interaction status*/ a:hover, a:focus, a:active { --bg-size: 100%; --link-color: var(--bg); } /* Activity*/ a:active { --shadow-size: var(--space); /* Define box-shadow size*/ } }
Of course it's a little more complicated than just using underscores, but in conjunction with utility classes that allow you to always access text and background colors, it's a pretty nice progressive enhancement.
You can enhance this with three variables, each color uses rgb or hsl format to adjust opacity, etc. You can also add text shadows to simulate text-decoration-skip-ink
!
The above is the detailed content of Contextual Utility Classes for Color with Custom Properties. For more information, please follow other related articles on the PHP Chinese website!

Custom cursors with CSS are great, but we can take things to the next level with JavaScript. Using JavaScript, we can transition between cursor states, place dynamic text within the cursor, apply complex animations, and apply filters.

Interactive CSS animations with elements ricocheting off each other seem more plausible in 2025. While it’s unnecessary to implement Pong in CSS, the increasing flexibility and power of CSS reinforce Lee's suspicion that one day it will be a

Tips and tricks on utilizing the CSS backdrop-filter property to style user interfaces. You’ll learn how to layer backdrop filters among multiple elements, and integrate them with other CSS graphical effects to create elaborate designs.

Well, it turns out that SVG's built-in animation features were never deprecated as planned. Sure, CSS and JavaScript are more than capable of carrying the load, but it's good to know that SMIL is not dead in the water as previously

Yay, let's jump for text-wrap: pretty landing in Safari Technology Preview! But beware that it's different from how it works in Chromium browsers.

This CSS-Tricks update highlights significant progress in the Almanac, recent podcast appearances, a new CSS counters guide, and the addition of several new authors contributing valuable content.

Most of the time, people showcase Tailwind's @apply feature with one of Tailwind's single-property utilities (which changes a single CSS declaration). When showcased this way, @apply doesn't sound promising at all. So obvio

Deploying like an idiot comes down to a mismatch between the tools you use to deploy and the reward in complexity reduced versus complexity added.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

Atom editor mac version download
The most popular open source editor

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

Zend Studio 13.0.1
Powerful PHP integrated development environment

WebStorm Mac version
Useful JavaScript development tools
