CSS Variables has reached a point where it can be used in production environments, and I have been exploring its powerful features. I've tried a variety of ways to use it and hope you'll be excited about them as well as I do. They are very practical and powerful!
I found that the use of CSS variables can often be summarized into several categories . Of course, you can use CSS variables as you like, but thinking about them from these different categories may help you understand their different ways of using them.
- Variables: Basic usage, such as setting brand colors and using them where needed.
- Default value: For example, set a default border-radius, which can be overwritten afterwards.
- Cascading values: Based on specific usage clues, such as user preferences.
- Scope rule set: Deliberate style variations of individual elements such as links and buttons.
- Mixin: Rule set designed to apply its values ??to new contexts.
- Inline properties: The value passed in from the inline style of HTML.
The example we will see is a simplified and concentrated pattern from Cutestrap, the CSS framework I created and maintained.
A brief description of browser support
I often hear two common questions when it comes to custom properties. The first one is about browser support. Which browsers support them? What fallback schemes do we need to use in browsers that do not support them?
The global market share that supports the content described in this article is 85%. Still, it's worth cross-reference to caniuse to determine how much progressive enhancement means and where to use it in your project based on your user base.
The second question is always about how to use custom properties. So let's get a deeper look at its usage!
Pattern 1: Variable
First, we will set a custom attribute variable for the brand color and use it on the SVG element. We will also use a fallback scheme to overwrite users of older browsers.
html { --brand-color: hsl(230, 80%, 60%); } .logo { fill: pink; /* backup plan*/ fill: var(--brand-color); }
Here, we declare a variable named --brand-color in the html rule set. The variable is defined on the always-existing element, so it will be cascading to each element that uses it. In short, we can use this variable in the .logo rule set.
We declared a pink fallback value for the older browser. In the second fill declaration, we pass --brand-color into the var() function, which returns the value we set for that custom property.
The pattern is roughly like this: define the variable (--variable-name) and then use it on the element (var(--variable-name)).
Mode 2: Default
The var() function we used in the first example can also provide default values ??in case the custom properties it attempts to access are not set.
For example, suppose we provide rounded borders for the button. We can create a variable—we call it --roundness—but we won't define it as before. Instead, we will assign a default value when using variables.
.button { /* --roundness: 2px; */ border-radius: var(--roundness, 10px); }
One use case for using default values ??without custom properties defined is that your project is still in design, but your functionality expires today . If the design changes, this makes it much easier to update the values ??later.
So you can give the button a nice default value that satisfies your deadline, and when --roundness is finally set to a global custom property, your button will get that update for free without returning to it.
You can edit and uncomment the above code on CodePen to see how the button looks after setting --roundness!
Mode 3: Cascading values
Now that we have the basics, let’s start building the future we deserve. I really miss AIM and MySpace expressing their personality by allowing users to use custom text and background colors on their profile.
Let's bring it back and create a school message board where every student can set their own font, background color and text color for the messages they post.
User-based topics
We are basically having students create custom themes. We will set the topic configuration in the data-attribute rule set so that any child elements that use these topics (in this case the .message element) can access these custom attributes.
.message { background-color: var(--student-background, http://ipnx.cn/link/93ac0c50dd620dc7b88e5fe05c70e15bfff); color: var(--student-color, http://ipnx.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b000); font-family: var(--student-font, "Times New Roman", serif); margin-bottom: 10px; padding: 10px; } [data-student-theme="rachel"] { --student-background: rgb(43, 25, 61); --student-color: rgb(252, 249, 249); --student-font: Arial, sans-serif; } [data-student-theme="jen"] { --student-background: http://ipnx.cn/link/93ac0c50dd620dc7b88e5fe05c70e15bd55349; --student-color: http://ipnx.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b000; --student-font: Avenir, Helvetica, sans-serif; } [data-student-theme="tyler"] { --student-background: blue; --student-color: yellow; --student-font: "Comic Sans MS", "Comic Sans", cursive; }
Here is the marker:
<div data-student-theme="chris"> <p>Chris: I've spoken at events and given workshops all over the world at conferences.</p> </div> <div data-student-theme="rachel"> <p>Rachel: I prefer email over other forms of communication.</p> </div> <div data-student-theme="jen"> <p>Jen: This is why I immediately set up my new team with Slack for real-time chat.</p> </div> <div data-student-theme="tyler"> <p>Tyler: I miss AIM and MySpace, but this message board is OK.</p> </div>
We set up all student topics for our student topic ruleset using the [data-student-theme] selector. If you set custom properties for the background, color, and font for this student, these custom properties will be applied to our .message rule set because .message is a child element of a div containing data-attribute, which in turn contains the custom attribute value to use. Otherwise, the default values ??we provide will be used.
Readability Theme Coverage
While it’s fun and cool to control custom styles for users, the styles that users choose are not always accessible and need to be considered for contrast, color vision flaws, or anyone who likes not bleeding from their eyes while reading. Remember the GeoCities era?
Let's add a class that provides a clearer look and feel and set it on the parent element to overwrite any student topics when the class exists.
.readable-theme [data-student-theme] { --student-background: hsl(50, 50%, 90%); --student-color: hsl(200, 50%, 10%); --student-font: Verdana, Geneva, sans-serif; }
...
We utilize cascades to cover student topics by setting higher specificity so that backgrounds, colors, and fonts are within range and will be applied to each .message rule set.
Pattern 4: Scope Rule Set
Speaking of scopes, we can scope custom properties and use them to simplify what was originally boilerplate CSS. For example, we can define variables for different link states.
a { --link: hsl(230, 60%, 50%); --link-visited: hsl(290, 60%, 50%); --link-hover: hsl(230, 80%, 60%); --link-active: hsl(350, 60%, 50%); } a:link { color: var(--link); } a: visited { color: var(--link-visited); } a:hover { color: var(--link-hover); } a:active { color: var(--link-active); }
<a href="http://ipnx.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">Link Example</a>
Now we're already<a></a>
Custom properties are written globally on the elements and used them on our link state, we don't need to write them again. The scope of these properties is limited to us<a></a>
The ruleset of the elements, so they are only set on the anchor tag and its child elements. This allows us not to pollute the global namespace.
Example: Grayscale link
Going forward, we can control the links we just created by changing the custom properties of different use cases. For example, let's create a gray link.
.grayscale { --link: LightSlateGrey; --link-visited: Silver; --link-hover: DimGray; --link-active: LightSteelBlue; }
<a href="http://ipnx.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">Link Example</a>
We declare a .grayscale rule set with colors for different link states. Since the selector for this rule set is more specific than the default, these variable values ??will be used and then applied to the pseudo-class rule set of the linked state, rather than in<a></a>
Content defined on the element.
Example: Custom links
If setting four custom properties feels too much work, what if we only set one hue value? This may make management much easier.
.custom-link { --hue: 30; --link: hsl(var(--hue), 60%, 50%); --link-visited: hsl(calc(var(--hue) 60), 60%, 50%); --link-hover: hsl(var(--hue), 80%, 60%); --link-active: hsl(calc(var(--hue) 120), 60%, 50%); } .danger { --hue: 350; }
<a href="http://ipnx.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">Link Example</a> Link Example
By introducing a variable of hue value and applying it to the HSL color value in other variables, we can update all four link states with just one value.
Computing is very powerful in combination with custom properties because they can make your style more expressive without having to put in more effort. Check out this technique by Josh Bader, who uses a similar approach to enforce accessible color contrast of buttons.
Mode 5: Mixin
Regarding custom properties, Mixin is a function declared as a custom property value. The parameters of Mixin are other custom properties that, when these properties change, recalculate the Mixin, which in turn updates the style.
The custom link example we just saw is actually a Mixin. We can set the value of --hue and then all four link states will be recalculated accordingly.
Example: Baseline grid foundation
Let's learn more about Mixin by creating a baseline mesh that helps with vertical rhythms. In this way, our content achieves a pleasant rhythm by using consistent spacing.
.baseline, .baseline * { --rhythm: 2rem; --line-height: var(--sub-rhythm, var(--rhythm)); --line-height-ratio: 1.4; --font-size: calc(var(--line-height) / var(--line-height-ratio)); } .baseline { font-size: var(--font-size); line-height: var(--line-height); }
We apply the ruleset of the baseline mesh to the .baseline class and any descendants.
- --rhythm: This is the cornerstone of our baseline. Updating it will affect all other properties.
- --line-height: Set to --rhythm by default, because --sub-rhythm is not set here.
- --sub-rhythm: This allows us to override --line-height -- followed by --font-size -- while maintaining the overall baseline grid.
- --line-height-ratio: This helps enforce appropriate spacing between text lines.
- --font-size: This is calculated by dividing --line-height by --line-height-ratio.
We also set font-size and line-height in the .baseline rule set to use --font-size and --line-height from the baseline grid. In short, whenever the rhythm changes, line height and font size change accordingly, while maintaining a readable experience.
OK, let's use the baseline.
Let's create a small webpage. We will use our --rhythm custom property to set the spacing between all elements.
.baseline h2, .baseline p, .baseline ul { padding: 0 var(--rhythm); margin: 0 0 var(--rhythm); } .baseline p { --line-height-ratio: 1.2; } .baseline h2 { --sub-rhythm: calc(3 * var(--rhythm)); --line-height-ratio: 1; } .baseline p, .baseline h2 { font-size: var(--font-size); line-height: var(--line-height); } .baseline ul { margin-left: var(--rhythm); }
<h2> A Tiny Webpage</h2> <p>This is the tiniest webpage. It has three noteworthy features:</p>
- Tiny
- Exemplar
- Identifies as Hufflepuff
We basically use two Mixins here: --line-height and --font-size. We need to set the attributes font-size and line-height to their custom attribute counterparts to set the title and paragraph. Mixin has been recalculated in these rule sets, but they need to be set before the updated styles are applied to them.
It is important to note that when applying Mixin using wildcard selectors, you may not want to use custom attribute values ??in the rule set itself. It makes these styles more specific than any other inheritance brought by the cascade, making it difficult to overwrite them without using !important.
Pattern 6: Inline properties
We can also declare custom properties inline. Let's build a lightweight grid system to demonstrate.
.grid { --columns: auto-fit; display: grid; gap: 10px; grid-template-columns: repeat(var(--columns), minmax(0, 1fr)); }
<div> <img src="/static/imghw/default1.png" data-src="https://img.php.cn/" class="lazy" alt="Bill Murray"><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/174468445958706.jpg" class="lazy" alt="Nic Cage"><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/174468446478697.jpg" class="lazy" alt="Nic Cage gray"><img src="/static/imghw/default1.png" data-src="https://img.php.cn/" class="lazy" alt="Bill Murray gray"><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/174468446644293.jpg" class="lazy" alt="Nic Cage crazy"><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/174468446996811.jpg" class="lazy" alt="Nic Cage gif"> </div>
By default, the grid has columns of equal size that will be automatically arranged into single rows.
To control the number of columns, we can set the --columns custom property inline on the grid element.
<div style="--columns: 3;"> ... </div>
We just looked at six different custom attribute use cases – at least the ones I use for the most. Even if you already know and have been using custom properties, you want to see these usages to give you a better idea of ??when and where to use them effectively.
Have you used different types of patterns using custom properties? Please share them in the comments and link some demos – I would love to see them!
If you are not familiar with custom properties and are looking for promotion, try using the example we covered here, but add media queries. You will see how adaptable these properties are and how many interesting opportunities are when you have the power to change values ??at any time.
In addition, there are a large number of other excellent resources on CSS-Tricks that can improve your custom attribute skills in the Custom Attribute Guide.
The above is the detailed content of Patterns for Practical CSS Custom Properties Use. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

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

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

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

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

There are three ways to create a CSS loading rotator: 1. Use the basic rotator of borders to achieve simple animation through HTML and CSS; 2. Use a custom rotator of multiple points to achieve the jump effect through different delay times; 3. Add a rotator in the button and switch classes through JavaScript to display the loading status. Each approach emphasizes the importance of design details such as color, size, accessibility and performance optimization to enhance the user experience.

To deal with CSS browser compatibility and prefix issues, you need to understand the differences in browser support and use vendor prefixes reasonably. 1. Understand common problems such as Flexbox and Grid support, position:sticky invalid, and animation performance is different; 2. Check CanIuse confirmation feature support status; 3. Correctly use -webkit-, -moz-, -ms-, -o- and other manufacturer prefixes; 4. It is recommended to use Autoprefixer to automatically add prefixes; 5. Install PostCSS and configure browserslist to specify the target browser; 6. Automatically handle compatibility during construction; 7. Modernizr detection features can be used for old projects; 8. No need to pursue consistency of all browsers,

Use the clip-path attribute of CSS to crop elements into custom shapes, such as triangles, circular notches, polygons, etc., without relying on pictures or SVGs. Its advantages include: 1. Supports a variety of basic shapes such as circle, ellipse, polygon, etc.; 2. Responsive adjustment and adaptable to mobile terminals; 3. Easy to animation, and can be combined with hover or JavaScript to achieve dynamic effects; 4. It does not affect the layout flow, and only crops the display area. Common usages are such as circular clip-path:circle (50pxatcenter) and triangle clip-path:polygon (50%0%, 100 0%, 0 0%). Notice

Themaindifferencesbetweendisplay:inline,block,andinline-blockinHTML/CSSarelayoutbehavior,spaceusage,andstylingcontrol.1.Inlineelementsflowwithtext,don’tstartonnewlines,ignorewidth/height,andonlyapplyhorizontalpadding/margins—idealforinlinetextstyling

Setting the style of links you have visited can improve the user experience, especially in content-intensive websites to help users navigate better. 1. Use CSS's: visited pseudo-class to define the style of the visited link, such as color changes; 2. Note that the browser only allows modification of some attributes due to privacy restrictions; 3. The color selection should be coordinated with the overall style to avoid abruptness; 4. The mobile terminal may not display this effect, and it is recommended to combine it with other visual prompts such as icon auxiliary logos.

TheCSSPaintingAPIenablesdynamicimagegenerationinCSSusingJavaScript.1.DeveloperscreateaPaintWorkletclasswithapaint()method.2.TheyregisteritviaregisterPaint().3.ThecustompaintfunctionisthenusedinCSSpropertieslikebackground-image.Thisallowsfordynamicvis

To create responsive images using CSS, it can be mainly achieved through the following methods: 1. Use max-width:100% and height:auto to allow the image to adapt to the container width while maintaining the proportion; 2. Use HTML's srcset and sizes attributes to intelligently load the image sources adapted to different screens; 3. Use object-fit and object-position to control image cropping and focus display. Together, these methods ensure that the images are presented clearly and beautifully on different devices.

Different browsers have differences in CSS parsing, resulting in inconsistent display effects, mainly including the default style difference, box model calculation method, Flexbox and Grid layout support level, and inconsistent behavior of certain CSS attributes. 1. The default style processing is inconsistent. The solution is to use CSSReset or Normalize.css to unify the initial style; 2. The box model calculation method of the old version of IE is different. It is recommended to use box-sizing:border-box in a unified manner; 3. Flexbox and Grid perform differently in edge cases or in old versions. More tests and use Autoprefixer; 4. Some CSS attribute behaviors are inconsistent. CanIuse must be consulted and downgraded.
