CSS @property 和新样式 CSS @property and the new style

原始链接: https://ryanmulligan.dev/blog/css-property-new-style/

本文介绍了 CSS 中“@property”规则的用法,该功能允许开发人员在 CSS 中显式声明自定义属性的语法、初始值和继承。 作者解释了“@property”如何通过允许浏览器解释和动画自定义属性更改来提供不同状态之间的更平滑的转换。 他们使用 codepen 演示了这一点,展示了通过精心设计的“圆锥渐变”、“线性渐变”和“@keyframe”动画组合实现的旋转渐变和闪亮边框效果。 作者还讨论了设置“background-origin”以及调整自定义属性的“syntax”和“initial-value”等技术,以创建各种视觉效果。 此外,他们还探索了在悬停事件期间使渐变旋转更慢的方法,在按钮内创建微小的闪烁点,并对其外观进行微妙的增强。 最后,他们对“@property”在更大规模的应用程序和设计系统中的潜在用途表示兴奋。 文章结尾提供了有用资源的链接。 总结如下: 在本文中,作者演示了如何使用 CSS 中的“@property”规则在网页中创建动态且具有视觉吸引力的效果。 使用自定义属性和“圆锥渐变”、“线性渐变”和“动画”的巧妙组合,作者创建了旋转渐变和闪亮边框效果。 讨论的技术包括使用“background-origin”、调整语法和初始值、使悬停事件时渐变旋转得更慢、创建微小的闪烁点以及增强悬停事件的外观。 总体而言,作者将“@property”视为一种令人兴奋的工具,用于增强网页中的用户交互,特别是用于设计号召性用语和其他图形元素。 本文最后提供了进一步学习和探索的有用链接。

The article introduces the usage of '@property' rule in CSS, a feature that allows developers to explicitly declare syntax, initial value, and inheritance for custom properties in CSS. The author explains how '@property' provides smoother transitions between different states by allowing the browser to interpret and animate custom property changes. They demonstrate this using a codepen showcasing a rotating gradient and shining border effect achieved through carefully crafted combinations of 'conic-gradient', 'linear-gradient', and '@keyframe' animations. The author also discusses techniques such as setting `background-origin` and adjusting the 'syntax' and 'initial-value' of custom properties to create various visual effects. Additionally, they explore ways to make gradients spin slower during hover events, create tiny shimmering dots within buttons, and give subtle enhancements to their appearance. They conclude by expressing excitement towards the potential uses of '@property' in larger scale applications and design systems. The article ends with links to helpful resources. Here is the summary: In this article, the author demonstrates the use of the '@property' rule in CSS to create dynamic and visually appealing effects in web pages. Using custom properties and clever combinations of 'conic-gradient', 'linear-gradient', and 'animation', the author creates a rotating gradient and shining border effect. Techniques discussed include using `background-origin`, adjusting syntax and initial-values, making gradients spin slower on hover events, creating tiny shimmering dots, and enhancing the appearance of hover events. Overall, the author presents '@property' as an exciting tool for enhancing user interactions in web pages, particularly for designing call-to-actions and other graphical elements. The article concludes with useful links for further learning and exploration.


Posted on September 2, 2024

Takes about 9 minutes to read

The @property at-rule recently gained support across all modern browsers, unlocking the ability to explicitly define a syntax, initial value, and inheritance for CSS custom properties. It seems like forever ago that CSS Houdini and its CSS Properties and Values API were initially introduced. I experimented sparingly over time, reading articles that danced around the concepts, but I had barely scratched the surface of what @property could offer. The ensuing demo explores what's possible in the next generation of CSS.

Calls to action

Ever seen those sleek, attention-seeking, shiny call-to-action webpage elements? Waves of sites across the web, especially the ones marketing services and software urging for you to "Upgrade your account" or "Sign up today," have discovered the look and latched on. I'm not here to knock it and admittedly think it's kind of fresh. I thought I'd give that style a try myself. Check out the result in the CodePen below.

Open CodePen demo

There's a ton to unpack in this demo. Let's start with that shine looping around the button. Toggle open the demo's CSS panel to find a collection of @property rules related to those custom properties that need to animate. Here's the one defined for the --gradient-angle:

@property --gradient-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

The @property rule communicates to the browser that <angle> is the allowed syntax for this custom property and its initial value is 0deg. This enables the browser to smoothly transition from 0deg to 360deg and output a rotating gradient.

@keyframes rotate-gradient {
  to { --gradient-angle: 360deg; }
}

.rotate-gradient {
  background: conic-gradient(from var(--gradient-angle), transparent, black);
  animation: rotate-gradient 10s linear infinite;
}

I put together a simple gradient spin demo to focus on the handful of lines necessary to render this concept.

Open CodePen demo

We can achieve the shiny animated border effect by evolving this code a bit. We'll introduce a linear-gradient as the first value of the element's background property and set a background-origin to each value.

  • The origin of the linear-gradient is set to padding-box. This prevents the gradient from spilling into the border area.
  • The conic-gradient origin is set to border-box. This gradient overflows into the space created by the border width.
  • To reveal the rotating conic-gradient, a single-pixel transparent border is added.
.border-gradient {
  background: 
    linear-gradient(black, black) padding-box,
    conic-gradient(from var(--gradient-angle), transparent 25%, white, transparent 50%) border-box;
  border: 1px solid transparent;
}

In the CSS panel of the simple gradient spin demo, uncomment the .border-gradient ruleset to reveal the shiny animated border. Looking pretty slick! For more examples, I've included a bunch of animated gradient border articles in the resources section at the end of the post.

Silky smooth hover transitions

A few special ingredients help facilitate a buttery smooth gradient transition when the element is hovered. Let's dig into its background values:

.shiny-cta {
  background: 
    linear-gradient(var(--shiny-cta-bg), var(--shiny-cta-bg)) padding-box,
    conic-gradient(
        from calc(var(--gradient-angle) - var(--gradient-angle-offset)),
        transparent,
        var(--shiny-cta-highlight) var(--gradient-percent),
        var(--gradient-shine) calc(var(--gradient-percent) * 2),
        var(--shiny-cta-highlight) calc(var(--gradient-percent) * 3),
        transparent calc(var(--gradient-percent) * 4)
      )
      border-box;
}

Each custom property that needs to animate has a syntax declared in its @property definition so that the browser can interpolate between corresponding value changes and transition them seamlessly. The size of the shiny area is determined by the --gradient-percent value. On hover, a higher percentage lengthens the shine. The --gradient-angle-offset value is used to readjust the gradient angle so that the shine doesn't rubber band back and forth on hover.

Demonstrating the transition behavior without the angle offset value

I had to fine-tune the percent and offset values until the shine length and transition felt optically aligned. Finally, the --gradient-shine brightness gets toned down to blend more seamlessly with the adjacent highlight colors.

Slow it on down

This CSS tip to slow down a rotation on hover truly blew my mind. In the tip's example code, the same rotate animation is declared twice. The second one is reversed and paused, its duration divided in half. When the element is hovered, animation-play-state: running overrides the paused value and slows the rotation to half speed. The mind-blowing part, at least to me, is that the animation speeds back up at the current position when the element is no longer hovered. No snapping back to a start position, no extra wrapper elements necessary. That is one heck of a tip.

The call-to-action animations rely on this method to slow them down when the button is hovered. This technique keeps all the rotations and movements in sync as they change speed.

Tiny shiny dots

Looking even closer, we'll discover pinhole-sized dots shimmering inside the button as the shiny border passes near them. To render this dot pattern, a radial-gradient background is created.

.shiny-cta::before {
  --position: 2px;
  --space: calc(var(--position) * 2);
  background: radial-gradient(
      circle at var(--position) var(--position),
      white calc(var(--position) / 4),
      transparent 0
    )
    padding-box;
  background-size: var(--space) var(--space);
  background-repeat: space;
}

Remember that --gradient-angle custom property? It has returned! But this time, it's being used in a conic-gradient mask that reveals parts of the dot pattern as it rotates. The gradient angle is offset by 45 degrees to align it perfectly with the shiny border rotation.

.shiny-cta::before {
  mask-image: conic-gradient(
    from calc(var(--gradient-angle) + 45deg),
    black,
    transparent 10% 90%,
    black
  );
}

For one last touch of magic, a gradient containing the highlight color is added to the ::after pseudo element, spinning in unison with the shine area. These highlights flowing through the button add a pleasant, welcoming ambience that was previously missing.

Enhancing the hover colors

The hover styles looked decent. But they didn't seem totally finished. I felt the desire to enhance. Create more depth. Make it pop, as they say.

The button's ::before and ::after pseudo elements were already in use so I wrapped the button text in a span element. A blurred box-shadow containing the highlight color is applied to one of its pseudo elements which is then expanded to fill the button dimensions. On hover, the pseudo element slowly scales up and down, evoking a vibe similar to relaxed breathing. Paired with the spinning highlight color inside the button, the effect finally resonated with me. This intricately designed call-to-action button felt complete.

In with the new style

Many of the above techniques would have been nearly impossible only a short time ago. Explicitly defining custom properties unlocks a great big world of opportunity. I'm especially eager to see how @property will be utilized in large-scale applications and design systems. Providing Type Definitions for CSS with @property by Stephanie Eckles as well as Adam Argyle's Type safe CSS design systems with @property are just a couple glimpses into a really promising future for publishing our CSS.

Helpful resources

Back to all blog posts

相关文章
联系我们 contact @ memedata.com