csswg – CSS-Tricks https://css-tricks.com Tips, Tricks, and Techniques on using Cascading Style Sheets. Thu, 01 Aug 2024 14:41:04 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.1 https://i0.wp.com/css-tricks.com/wp-content/uploads/2021/07/star.png?fit=32%2C32&ssl=1 csswg – CSS-Tricks https://css-tricks.com 32 32 45537868 CSS Functions and Mixins Module Notes https://css-tricks.com/css-functions-and-mixins-module-notes/ https://css-tricks.com/css-functions-and-mixins-module-notes/#respond Wed, 31 Jul 2024 20:25:35 +0000 https://css-tricks.com/?p=378995 Most days, I’m writing vanilla CSS. Thanks to CSS variables and nesting, I have fewer reasons to reach for Sass or any other preprocessor. The times I reach for Sass tend to be when I need a @mixin to loop …


CSS Functions and Mixins Module Notes originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Most days, I’m writing vanilla CSS. Thanks to CSS variables and nesting, I have fewer reasons to reach for Sass or any other preprocessor. The times I reach for Sass tend to be when I need a @mixin to loop through a list of items or help keep common styles DRY.

That could change for me in the not-so-distant future since a new CSS Functions and Mixins Module draft was published in late June after the CSSWG resolved to adopt the proposal back in February.

Notice the module’s name: Functions and Mixins. There’s a distinction between the two.

This is all new and incredibly unbaked at the moment with plenty of TODO notes in the draft and points to consider in future drafts. The draft spec doesn’t even have a definition for mixins yet. It’ll likely be some time before we get something real to work and experiment with, but I like trying to wrap my mind around these sorts of things while they’re still in early days, knowing things are bound to change.

In addition to the early draft spec, Miriam Suzanne published a thorough explainer that helps plug some of the information gaps. Miriam’s an editor on the spec, so I find anything she writes about this to be useful context.

There’s a lot to read! Here are my key takeaways…

Custom functions are advanced custom properties

We’re not talking about the single-purpose, built-in functions we’ve come to love in recent years — e.g., calc(), min(), max(), etc. Instead, we’re talking about custom functions defined with an @function at-rule that contains logic for returning an expected value.

That makes custom functions a lot like a custom property. A custom property is merely a placeholder for some expected value that we usually define up front:

:root {
  --primary-color: hsl(25 100% 50%);
}

Custom functions look pretty similar, only they’re defined with @function and take parameters. This is the syntax currently in the draft spec:

@function <function-name> [( <parameter-list> )]? {
  <function-rules>

  result: <result>;
}

The result is what the ultimate value of the custom function evaluates to. It’s a little confusing to me at the moment, but how I’m processing this is that a custom function returns a custom property. Here’s an example straight from the spec draft (slightly modified) that calculates the area of a circle:

@function --circle-area(--r) {
  --r2: var(--r) * var(--r);

  result: calc(pi * var(--r2));
}

Calling the function is sort of like declaring a custom property, only without var() and with arguments for the defined parameters:

.element {
  inline-size: --circle-area(--r, 1.5rem); /* = ~7.065rem */
}

Seems like we could achieve the same thing as a custom property with current CSS features:

:root {
  --r: 1rem;
  --r2: var(--r) * var(--r);
  --circle-area: calc(pi * var(--r2));
}

.element {
  inline-size: var(--circle-area, 1.5rem);
}

That said, the reasons we’d reach for a custom function over a custom property are that (1) they can return one of multiple values in a single stroke, and (2) they support conditional rules, such as @supports and @media to determine which value to return. Check out Miriam’s example of a custom function that returns one of multiple values based on the inline size of the viewport.

/* Function name */
@function --sizes(
  /* Array of possible values */
  --s type(length),
  --m type(length),
  --l type(length),
  /* The returned value with a default */
) returns type(length) {
  --min: 16px;

  /* Conditional rules */
  @media (inline-size < 20em) {
    result: max(var(--min), var(--s, 1em));
  }
  @media (20em < inline-size < 50em) {
    result: max(var(--min), var(--m, 1em + 0.5vw));
  }
  @media (50em < inline-size) {
    result: max(var(--min), var(--l, 1.2em + 1vw));
  }
}

Miriam goes on to explain how a comma-separated list of parameters like this requires additional CSSWG work because it could be mistaken as a compound selector.

Mixins help maintain DRY, reusable style blocks

Mixins feel more familiar to me than custom functions. Years of writing Sass mixins will do that to you, and indeed, is perhaps the primary reason I still reach for Sass every now and then.

Mixins sorta look like the new custom functions. Instead of @function we’re working with @mixin which is exactly how it works in Sass.

/* Custom function */
@function <function-name> [( <parameter-list> )]? {
  <function-rules>
  result: <result>;
}

/* CSS/Sass mixin */
@mixin <mixin-name> [( <parameter-list> )]? {
  <mixin-rules>
}

So, custom functions and mixins are fairly similar but they’re certainly different:

  • Functions are defined with @function; mixins are defined with @mixin but are both named with a dashed ident (e.g. --name).
  • Functions result in a value; mixins result in style rules.

This makes mixins ideal for abstracting styles that you might use as utility classes, say a class for hidden text that is read by screenreaders:

.sr-text {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

In true utility fashion, we can sprinkle this class on elements in the HTML to hide the text.

<a class="sr-text">Skip to main content</a>

Super handy! But as any Tailwind-hater will tell you, this can lead to ugly markup that’s difficult to interpret if we rely on many utility classes. Screereader text isn’t in too much danger of that, but a quick example from the Tailwind docs should illustrate that point:

<div class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg">

It’s a matter of preference, really. But back to mixins! The deal is that we can use utility classes almost as little CSS snippets to build out other style rules and maintain a clearer separation between markup and styles. If we take the same .sr-text styles from before and mixin-erize them (yep, I’m coining this):

@mixin --sr-text {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

Instead of jumping into HTML to apply the styles, we can embed them in other CSS style rules with a new @apply at-rule:

header a:first-child {
  @apply --sr-text;

  /* Results in: */
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

Perhaps a better example is something every project seems to need: centering something!

@mixin --center-me {
  display: grid;
  place-items: center;
}

This can now be part of a bigger ruleset:

header {
  @apply --center-me;
  /*
    display: grid;
    place-items: center;
  */

  background-color: --c-blue-50;
  color: --c-white;
  /* etc. */
}

That’s different from Sass which uses @include to call the mixin instead of @apply. We can even return larger blocks of styles, such as styles for an element’s ::before and ::after pseudos:

@mixin --center-me {
  display: grid;
  place-items: center;
  position: relative;

  &::after {
    background-color: hsl(25 100% 50% / .25);
    content: "";
    height: 100%;
    position: absolute;
    width: 100%;
  }
}

And, of course, we saw that mixins accept argument parameters just like custom functions. You might use arguments if you want to loosen up the styles for variations, such as defining consistent gradients with different colors:

@mixin --gradient-linear(--color-1, --color-2, --angle) {
  /* etc. */
}

We’re able to specify the syntax for each parameter as a form of type checking:

@mixin --gradient-linear(
  --color-1 type(color),
  --color-2 type(color),
  --angle type(angle),
) {
  /* etc. */
}

We can abstract those variables further and set default values on them:

@mixin --gradient-linear(
  --color-1 type(color),
  --color-2 type(color),
  --angle type(angle),
) {
  --from: var(--color-1, orangered);
  --to: var(--from-color, goldenrod);
  --angle: var(--at-angle, to bottom right);

  /* etc. */
}

…then we write the mixin’s style rules with the parameters as variable placeholders.

@mixin --gradient-linear(
  --color-1 type(color),
  --color-2 type(color),
  --angle type(angle),
) {
  --from: var(--color-1, orangered);
  --to: var(--from-color, goldenrod);
  --angle: var(--at-angle, to bottom right);

  background: linear-gradient(var(--angle), var(--from), var(--to));
}

Sprinkle conditional logic in there if you’d like:

@mixin --gradient-linear(
  --color-1 type(color),
  --color-2 type(color),
  --angle type(angle),
) {
  --from: var(--color-1, orangered);
  --to: var(--from-color, goldenrod);
  --angle: var(--at-angle, to bottom right);

  background: linear-gradient(var(--angle), var(--from), var(--to));

  @media (prefers-contrast: more) {
    background: color-mix(var(--from), black);
    color: white;
  }
}

This is all set to @apply the mixin in any rulesets we want:

header {
  @apply --gradient-linear;
  /* etc. */
}

.some-class {
  @apply --gradient-linear;
  /* etc. */
}

…and combine them with other mixins:

header {
  @apply --gradient-linear;
  @apply --center-me;
  /* etc. */
}

This is all very high level. Miriam gets into the nuances of things like:

  • Applying mixins at the root level (i.e., not in a selector)
  • Working with Container Queries with the limitation of having to set global custom properties on another element than the one that is queried.
  • The possibility of conditionally setting mixin parameters with something like @when/@else in the mixin. (Which makes me wonder about the newly-proposed if() function and whether it would be used in place of @when.)
  • Why we might draw a line at supporting loops the same way Sass does. (CSS is a declarative language and loops are imperative flows.)
  • Scoping mixins (@layer? scope? Something else?)

Miriam has an excellent outline of the open questions and discussions happening around mixins.

That’s, um, it… at least for now.

Gah, this is a lot for my blonde brain! Anytime I’m neck-deep in CSS specification drafts, I have to remind myself that the dust is still settling. The spec authors and editors are wrestling with a lot of the same questions we have — and more! — so it’s not like a cursory read of the drafts is going to make experts out of anyone. And that’s before we get to the fact that things can, and likely will, change by the time it all becomes a recommended feature for browsers to implement.

This will be an interesting space to watch, which is something you can do with the following resources:


CSS Functions and Mixins Module Notes originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/css-functions-and-mixins-module-notes/feed/ 0 378995
CSS Stuff I’m Excited After the Last CSSWG Meeting https://css-tricks.com/css-stuff-im-excited-after-the-last-csswg-meeting/ https://css-tricks.com/css-stuff-im-excited-after-the-last-csswg-meeting/#comments Fri, 19 Jul 2024 17:16:57 +0000 https://css-tricks.com/?p=379180 From June 11–13, the CSS Working Group (CSSWG) held its second face-to-face meeting of the year in Coruña, Spain, with a long agenda of new features and improvements coming to language. If 2023 brought us incredible advances like …


CSS Stuff I’m Excited After the Last CSSWG Meeting originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
From , the CSS Working Group (CSSWG) held its second face-to-face meeting of the year in Coruña, Spain, with a long agenda of new features and improvements coming to language. If 2023 brought us incredible advances like out-of-the-box nesting, container and style queries, or the has: selector, then 2024 is going to be even more packed with even more ground-breaking additions. Whether a new feature like inline conditionals is just starting or long-term projects are wrapping up, 2024 is already filled with exciting developments — and we’re still in July!

I wanted to share what I think are some of the most interesting and significant features coming to CSS that were examined in the meeting. However, I don’t want you to take the following as an exact recap of the discussions. Instead, I want to bring up the broader topics coming to CSS that had a spotlight at the last meeting. In reality, the features examined have been cooking up for even years and the discussions are geared towards specific cases and new enhancements, rather than defining a whole specification; a work that would be impossible in one meeting.

You can see the exact issues discussed on the CSSWG meeting agenda.

Feature 1: What if we get if()?

Since CSS custom properties gained reliable support around 2016, there have been many attempts to apply certain styles depending on a custom property value without, of course, appealing to JavaScript. One of the earliest workarounds for conditional styles was posted by Roman Komarov back in 2016 in “Conditions for CSS Variables”. From there, many other hacks have been documented for making conditional declarations in CSS (including this extremely clever one by Ana Tudor here on CSS-Tricks). In fact, you can find a full list that discusses and compares those workarounds by CSSWG member Lea Verou in her recent article, “Inline conditionals in CSS, now?”.

What’s for sure is that the community has craved a conditional way to apply styles using custom properties. Nowadays, we have a specification for Style Queries that’s capable of the task, but they come with limitations not related to browser support. The biggest of those limitations? We can’t directly style the container that’s queried, so we need some sort of wrapper element around that wrapper in HTML.

<div class="news-container" style="--variant: info">
  <p>Here is some good <strong>news</strong></p>
</div>

…in addition to writing the style query:

.news-container {
  container-name: news-container;
}

@container news-container style(--variant: info) {
  p {
    color: blue;
    border: 1px solid blue;
  }
}

What if() might look like

On the CSSWG side, there have been discussions about adding an if() function as far back as 2018. It was of this year — yes, six years later — that the CSSWG resolved to begin working on if() for CSS. As good as it may look, don’t expect to see if() in a browser in at least two years! (That’s Lea’s unofficial estimate.) We’ll likely need to wait even longer for enough browser support to begin using it reliably in production. The spec draft is only barely getting started and many things have to pass a test first. For context, the CSS variables working draft began in 2012 and only received wide browser support in 2016.

Syntax-wise, if() is probably going to borrow the ternary operator from JavaScript and other programming languages, structured like this:

if(a ? b : c)

…where a is the custom property we are checking and b are c are the possible conditional return values. To check for styles, an inline style(--my-property: value) would be used.

.forecast {
  background-color: if(style(--weather: clouds) ? var(--clouds-color): var(--default-color));
}

Even if ? isn’t used in CSS and : has a different meaning everywhere else, I think this syntax is the one most people are familiar with, not to mention it also allows seamless conditional chaining.

.forecast {
  background-color: if(
    style(--weather: clouds) ? var(--clouds-color): 
    style(--weather: sunny) ? var(--sunny-color);
    style( --weather: rain) ? var(--rain-color): var(--default-color)
  );
}

Future if() improvements

Although these probably won’t make it in the initial release, it’s interesting to see how if() might change between now and sometime further in the future:

  • Support for other inline conditionals. We are supposed to check for custom properties using the style() query, but we may as well check for media features with an inline media() query or if a user agent supports a specific property with an inline support().
.my-element {
  width: if(media(width > 1200px) ? var(--size-l): var(--size-m));
}
  • Using conditional inside other CSS functions. In future drafts, we may use ternaries inside other functions without having to wrap them around if(), e.g. just as we can make calculations without calc() if we are inside a clamp() or round() function.

Feature 2: Cross-document view transitions

Last year, the View Transition API gave us the power to create seamless transitions when navigating between web pages and states. No components or frameworks, no animation libraries — just vanilla HTML and CSS with a light sprinkle of JavaScript. The first implementation of View Transitions was baked into browsers a while back, but it was based on an experimental function defined by Chrome and was limited to transitions between two states (single-page view transitions) without support for transitioning between different pages (i.e., multi-page view transitions), which is what most of us developers are clamoring for. The possibilities for mimicking the behavior of native apps are exciting!

That’s why the CSS View Transitions Module Level 2 is so amazing and why it’s my favorite of all the CSS additions we’re covering in this article. Yes, the feature brings out-of-the-box seamless transitions between pages, but the real deal is it removes the need for a framework to achieve it. Instead of using a library — say React + some routing library — we can backtrack into plain CSS and JavaScript.

Of course, there are levels of complexity where the View Transition API may fall short, but it’s great for countless cases where we just want page transitions without the performance cost of dropping in a framework.

Opting into view transitions

View transitions are triggered when we navigate between two pages from the same-origin. In this context, navigation might be clicking a link, submitting a form, or going back and forth with browser buttons. By contrast, something like using a search bar between same-origin pages won’t trigger a page transition.

Both pages — the one we’re navigating away from and the one we’re navigating to — need to opt into the transition using the @view-transition at-rule and setting the navigation property to auto

@view-transition {
  navigation: auto;
}

When both pages opt into a transition, the browser takes a “snapshot” of both pages and smoothly fades the “before” page into the “after” page.

Transitioning between “snapshots”

In that video, you can see how the old page fades into the new page, and it works thanks to an entire tree of new pseudo-elements that persist through the transition and use CSS animations to produce the effect. The browser will group snapshots of elements with a unique view-transition-name property that sets a unique identifier on the transition that we can reference, and which is captured in the ::view-transition pseudo-element holding all of the transitions on the page.

You can think of ::view-transition as the :root element for all page transitions, grouping all of the parts of a view transition on the same default animation.

::view-transition
├─ ::view-transition-group(name)
│  └─ ::view-transition-image-pair(name)
│     ├─ ::view-transition-old(name)
│     └─ ::view-transition-new(name)
├─ ::view-transition-group(name)
│  └─ ::view-transition-image-pair(name)
│     ├─ ::view-transition-old(name)
│     └─ ::view-transition-new(name)
└─ /* and so one... */

Notice that each transition lives in a ::view-transition-group that holds a ::view-transition-image-pair that, in turn, consists of the “old” and “new” page snapshots. We can have as many groups in there as we want, and they all contain an image pair with both snapshots.

Quick example: let’s use the ::view-transition “root” as a parameter to select all of the transitions on the page and create a sliding animation between the old and new snapshots.

@keyframes slide-from-right {
  from {
    transform: translateX(100vw);
  }
}

@keyframes slide-to-left {
  to {
    transform: translateX(-100vw);
  }
}

::view-transition-old(root) {
  animation: 300ms ease-in both slide-to-left;
}

::view-transition-new(root) {
  animation: 300ms ease-out both slide-from-right;
}

If we navigate between pages, the entire old page slides out to the left while the entire new page slides in from the right. But we may want to prevent some elements on the page from participating in the transition, where they persist between pages while everything else moves from the “old” snapshot to the “new” one.

That’s where the view-transition-name property is key because we can take snapshots of certain elements and put them in their own ::view-transition-group apart from everything else so that it is treated individually.

nav {
  view-transition-name: navigation;

  /* 
    ::view-transition
    ├─ ::view-transition-group(navigation)
    │  └─ ::view-transition-image-pair(navigation)
    │     ├─ ::view-transition-old(navigation)
    │     └─ ::view-transition-new(navigation)
    └─ other groups...
  */
}

You can find a live demo of it on GitHub. Just note that browser support is limited to Chromium browsers (i.e., Chrome, Edge, Opera) at the time I’m writing this.

There are many things we can look forward to with cross-document view transitions. For example, If we have several elements with a different view-transition-name, we could give them a shared view-transition-class to style their animations in one place — or even customize the view transitions further with JavaScript to check from which URL the page is transitioning and animate accordingly.

Feature 3: Anchor Positioning

Positioning an element relative to another element in CSS seems like one of those no-brainer, straightforward things, but in reality requires mingling with inset properties (top, bottom, left, right) based on a series of magic numbers to get things just right. For example, getting a little tooltip that pops in at the left of an element when hovered might look something like this in HTML:

<p class="text">
  Hover for a surprise
  <span class="tooltip">Surprise! I'm a tooltip</span>
</p>

…and in CSS with current approaches:

.text {
  position: relative;
}


.tooltip {
  position: absolute;
  display: none;

  /* vertical center */
  top: 50%;
  transform: translateY(-50%);

  /* move to the left */
  right: 100%;
  margin-right: 15px; */
}

.text:hover .tooltip {
  display: block;
}

Having to change the element’s positioning and inset values isn’t the end of the world, but it sure feels like there should be an easier way. Besides, the tooltip in that last example is extremely fragile; if the screen is too small or our element is too far to the left, then the tooltip will hide or overflow beyond the edge of the screen.

CSS Anchor Positioning is yet another new feature that was discussed in the CSSWG meetings and it promises to make this sort of thing much, much easier.

Creating an anchor

The basic idea is that we establish two elements:

  • one that acts as an anchor, and
  • one that is a “target” anchored to that element.

This way, we have a more declarative way to associate one element and position it relative to the anchored element.

To begin we need to create our anchor element using a new anchor-name property.

Changing our markup a little:

<p>
  <span class="anchor">Hover for a surprise</span>
  <span class="tooltip">Surprise! I'm a tooltip</span>
</p>

We give it a unique dashed-indent as its value (just like a custom property):

.anchor {
  anchor-name: --tooltip;
}

Then we relate the .tooltip to the .anchor using the position-anchor property with either fixed or absolute positioning.

.toolip {
  position: fixed;
  position-anchor: --tooltip;
}

The .tooltip is currently positioned on top of the .anchor, but we ought to move it somewhere else to prevent that. The easiest way to move the .tooltip is using a new inset-area property. Let’s imagine that the .anchor is placed in the middle of a 3×3 grid and we can position the tooltip inside the grid by assigning it a row and column.

Three by three grid with yellow element in the center tile labeled 'anchor'.

The inset-area property takes two values for the .tooltip‘s in a specific row and column on the grid. It counts with physical values, like left, right, top and bottom, as well logical values depending on the user’s writing mode, like start and end, in addition to a center shared value. It also accepts values referencing x- and y-coordinates, like x-start and y-end. All these value types are ways of representing a space on the 3×3 grid.

For example, if we want the .tooltip to be positioned relative to the top-right edge of the anchor, we can set the inset-area property like this:

.toolip {
  /* physical values */
  inset-area: top right;

  /* logical values */
  inset-area: start end;

  /* mix-n-match values! */
  inset-area: top end;
}

Lastly, if we want our tooltip to span across two regions of the grid, we can use a span- prefix. For example, span-top will place the .tooltip in the grid’s top and center regions. If instead we want to span across an entire direction, we can use the span-all value.

Three by three grid with a yellow element in the center labeled 'anchor' surrounded by three tooltip examples demonstrating how tooltips are placed on the grid, including code examples for each example.

One of the problems with our anchor-less example is that the tooltip can overflow outside the screen. We can solve this using another new property, this time called position-try-options, in combination with a new inset-area() function.

(Yes, there is inset-area the property and inset-area() the function. That’s one we’ll have to commit to memory!)

The position-try-options property accepts a comma-separated list of fallback positions for the .tooltip when it overflows outside the screen. We can provide a list of inset-area() functions, each holding the same values that the inset-area property would. Now, each time the tooltip goes out off-screen, the next declared position is “tried”, and if that position causes an overflow, the next declared position is tried, and so on.

.toolip {
  inset-area: top left;
  position-try-options: inset-area(top), inset-area(top right);
}

This is a pretty wild concept that will take some time to grok. CSSWG member Miriam Suzanne sat down to discuss and tinker with anchor positioning with James Stuckey Weber in a video that’s well worth watching.

Geoff Graham took notes on the video if you’re looking for a TL;DW.

There are still many aspects to anchor positioning we aren’t covering here for brevity, notably the new anchor() function and @try-position at-rule. The anchor() function returns the computed position of the edge of an anchor, which provides more control over a tooltip’s inset properties. The @try-position at-rule is for defining custom positions to set on the position-try-options property.

My hunch is that using inset-area will be plenty robust for the vast majority of use cases.

The CSSWG is a collective effort

Earlier I said that this article wouldn’t be an exact retelling of the discussions that took place at the CSSWG meetings, but rather a broad representation of new specs coming to CSS that, due to their novelty, were bound to come up in those meetings. There are even some features that we simply hadn’t the time to review in this roundup that are still subject to debate (cough, masonry).

One thing is for sure: specs aren’t made in some vacuum over one or two meetings; it takes the joined effort of tens of amazing authors, developers, and user agents to bring to life what we use every day in our CSS work — not to mention the things we will use in the future.

I also had the opportunity to talk with some amazing developers from the CSSWG, and I found it interesting what their biggest takeaways were from the meetings. You might expect if() is at the top of their lists since that’s what is buzzing in socials. But CSSWG member Emilio Cobos told me, for example, that the letter-spacing property is essentially flawed and there isn’t a simple solution for fixing it that’s copasetic with how letter-spacing is currently defined by CSS and used in browsers. That includes the fact that converting normal properties into shorthand properties can be dangerous to a codebase.

Every tiny detail we might think of as trivial is carefully analyzed for the sake of the web and for the love of it. And, like I mentioned earlier, this stuff is not happening in a closed vacuum. If you’re at all interested in the future of CSS — whether that simply keeping up with it or getting actively involved — then consider any of the following resources.


CSS Stuff I’m Excited After the Last CSSWG Meeting originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/css-stuff-im-excited-after-the-last-csswg-meeting/feed/ 4 https://www.youtube.com/embed/76hIB2L_vs4 CSS Anchor Positioning in Practice - Winging It Live nonadult 379180
“Maybe The Most Exciting Development In CSS You’ve Never Heard Of” https://css-tricks.com/houdini-maybe-exciting-development-css-youve-never-heard/ Fri, 25 Mar 2016 13:51:27 +0000 http://css-tricks.com/?p=239753 Philip Walton has the scoop on Houdini, a new W3C task force that’s planning to give developers low level browser APIs:

The bottom line is, imagine how much nicer your development life would be if you could use any


“Maybe The Most Exciting Development In CSS You’ve Never Heard Of” originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Philip Walton has the scoop on Houdini, a new W3C task force that’s planning to give developers low level browser APIs:

The bottom line is, imagine how much nicer your development life would be if you could use any CSS property and know for sure it was going to work, exactly the same, in every browser. And think about all of the new features you read of in blog posts or hear about at conferences and meetups — things like CSS grids, CSS snap points and sticky positioning. Imagine if you could use all of them today and in a way that was as performant as native CSS features. And all you’d need to do is grab the code from GitHub.

This is the dream of Houdini. This is the future that the task force is trying to make possible.

To Shared LinkPermalink on CSS-Tricks


“Maybe The Most Exciting Development In CSS You’ve Never Heard Of” originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
239753