search
HomeWeb Front-endCSS TutorialContextual Utility Classes for Color with Custom Properties

Contextual Utility Classes for Color with Custom Properties

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!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Next Level CSS Styling for CursorsNext Level CSS Styling for CursorsApr 23, 2025 am 11:04 AM

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.

Worlds Collide: Keyframe Collision Detection Using Style QueriesWorlds Collide: Keyframe Collision Detection Using Style QueriesApr 23, 2025 am 10:42 AM

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

Using CSS backdrop-filter for UI EffectsUsing CSS backdrop-filter for UI EffectsApr 23, 2025 am 10:20 AM

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.

SMIL on?SMIL on?Apr 23, 2025 am 09:57 AM

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

'Pretty' is in the eye of the beholder'Pretty' is in the eye of the beholderApr 23, 2025 am 09:40 AM

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.

CSS-Tricks Chronicles XLIIICSS-Tricks Chronicles XLIIIApr 23, 2025 am 09:35 AM

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.

Tailwind's @apply Feature is Better Than it SoundsTailwind's @apply Feature is Better Than it SoundsApr 23, 2025 am 09:23 AM

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

Feeling Like I Have No Release: A Journey Towards Sane DeploymentsFeeling Like I Have No Release: A Journey Towards Sane DeploymentsApr 23, 2025 am 09:19 AM

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.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

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

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

MinGW - Minimalist GNU for Windows

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

Zend Studio 13.0.1

Powerful PHP integrated development environment

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools