Home Web Front-end CSS Tutorial Contextual Utility Classes for Color with Custom Properties

Contextual Utility Classes for Color with Custom Properties

Apr 18, 2025 am 09:36 AM

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>
Copy after login

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;
}
Copy after login

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};
  }
}
Copy after login

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;
}
Copy after login

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*/
  }
}
Copy after login

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;
Copy after login

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;
Copy after login

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);
Copy after login

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);
}
Copy after login

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);
}
Copy after login

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);
}
Copy after login

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. */
Copy after login

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);
Copy after login

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*/
  }
}
Copy after login

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 of this Website
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

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

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Vue 3 Vue 3 Apr 02, 2025 pm 06:32 PM

It&#039;s out! Congrats to the Vue team for getting it done, I know it was a massive effort and a long time coming. All new docs, as well.

Building an Ethereum app using Redwood.js and Fauna Building an Ethereum app using Redwood.js and Fauna Mar 28, 2025 am 09:18 AM

With the recent climb of Bitcoin’s price over 20k $USD, and to it recently breaking 30k, I thought it’s worth taking a deep dive back into creating Ethereum

Can you get valid CSS property values from the browser? Can you get valid CSS property values from the browser? Apr 02, 2025 pm 06:17 PM

I had someone write in with this very legit question. Lea just blogged about how you can get valid CSS properties themselves from the browser. That&#039;s like this.

Stacked Cards with Sticky Positioning and a Dash of Sass Stacked Cards with Sticky Positioning and a Dash of Sass Apr 03, 2025 am 10:30 AM

The other day, I spotted this particularly lovely bit from Corey Ginnivan’s website where a collection of cards stack on top of one another as you scroll.

A bit on ci/cd A bit on ci/cd Apr 02, 2025 pm 06:21 PM

I&#039;d say "website" fits better than "mobile app" but I like this framing from Max Lynch:

Comparing Browsers for Responsive Design Comparing Browsers for Responsive Design Apr 02, 2025 pm 06:25 PM

There are a number of these desktop apps where the goal is showing your site at different dimensions all at the same time. So you can, for example, be writing

Using Markdown and Localization in the WordPress Block Editor Using Markdown and Localization in the WordPress Block Editor Apr 02, 2025 am 04:27 AM

If we need to show documentation to the user directly in the WordPress editor, what is the best way to do it?

Why are the purple slashed areas in the Flex layout mistakenly considered 'overflow space'? Why are the purple slashed areas in the Flex layout mistakenly considered 'overflow space'? Apr 05, 2025 pm 05:51 PM

Questions about purple slash areas in Flex layouts When using Flex layouts, you may encounter some confusing phenomena, such as in the developer tools (d...

See all articles