Saturday, November 29, 2025

On Inheriting and Sharing Property Values


Generally I need to set the worth of a CSS property to that of a special property, even when I don’t know what that worth is, and even when it modifications later. Sadly although, that’s not potential (at the very least, there isn’t a CSS operate that particularly does that).

In my view, it’d be tremendous helpful to have one thing like this (for interpolation, possibly you’d throw calc-size() in there as effectively):

/* Completely hypothetical */
button {
  border-radius: compute(peak, self);
  border-radius: compute(peak, inherit);
  border-radius: compute(peak, #this);
}

In 2021, Lea Verou defined why, regardless of being proposed quite a few instances, implementing such a general-purpose CSS operate like this isn’t possible. Having mentioned that, I do stay hopeful, as a result of issues are at all times evolving and the CSSWG course of isn’t at all times linear.

Within the meantime, although there isn’t a CSS operate that allows us to get the worth of a special property, you would possibly have the ability to obtain your final result utilizing a special methodology, and people strategies are what we’re going to take a look at at this time.

The fool-proof CSS customized properties methodology

We are able to simply get the worth of a special CSS property utilizing customized properties, however we’d must know what the worth is in an effort to declare the customized property to start with. This isn’t very best, but it surely does allow us to realize some outcomes.

Let’s soar again to the instance from the intro the place we attempt to set the border-radius primarily based on the peak, solely this time we all know what the peak is and we retailer it as a CSS customized property for reusability, and so we’re capable of obtain our final result:

button {
  --button-height: 3rem;
  peak: var(--button-height);
  border-radius: calc(var(--button-height) * 0.3);
}

We are able to even place that --button-height customized property increased up within the CSS cascade to make it accessible to extra containment contexts.

:root {
  /* Declare right here to make use of wherever */
  --button-height: 3rem;

  header {
    --header-padding: 1rem;
    padding: var(--header-padding);
  
    /* Peak is unknown (however we are able to calculate it) */
    --header-height: calc(var(--button-height) + (var(--header-padding) * 2));
  
    /* Which implies we are able to calculate this, too */
    border-radius: calc(var(--header-height) * 0.3);
  
    button {
      /* In addition to these, in fact */
      peak: var(--button-height);
      border-radius: calc(var(--button-height) * 0.3);

      /* Oh, what the heck */
      padding-inline: calc(var(--button-height) * 0.5);
    }
  }
}

I suppose when my math instructor mentioned that I’d want algebra in the future. She wasn’t mendacity!

The unsupported inherit() CSS operate methodology

The inherit() CSS operate, which isn’t at the moment supported by any internet browser, will allow us to get the worth of a mother or father’s property. Suppose: the inherit key phrase, besides that we are able to get the worth of any mother or father property and even modify it utilizing worth features similar to calc(). The newest draft of the CSS Values and Models Module Stage 5 spec defines how this’d work for customized properties, which wouldn’t actually allow us to do something that we are able to’t already do (as demonstrated within the earlier instance), however the hope is that it’d work for all CSS properties additional down the road in order that we wouldn’t want to make use of customized properties (which is only a tad longer):

header {
  peak: 3rem;

  button {
    peak: 100%;

    /* Get peak of mother or father however use it right here */
    border-radius: calc(inherit(peak) * 0.3);
    padding-inline: calc(inherit(peak) * 0.5);
  }
}

There may be one distinction between this and the customized properties method, although. This methodology is dependent upon the mounted peak of the mother or father, whereas with the customized properties methodology both the mother or father or the kid can have the mounted peak.

Because of this inherit() wouldn’t interpolate values. For instance, an auto worth that computes to 3rem would nonetheless be inherited as auto, which could compute to one thing else when inherit()-ed., Generally that’d be high-quality, however different instances it’d be a difficulty. Personally, I’m hoping that interpolation turns into a chance sooner or later, making it way more helpful than the customized properties methodology.

Till then, there are another (largely property-specific) choices.

The aspect-ratio CSS property

Utilizing the aspect-ratio CSS property, we are able to set the peak relative to the width, and vice-versa. For instance:

div {
  width: 30rem;

  /* peak can be half of the width */
  aspect-ratio: 2 / 1;

  /* Similar factor */
  aspect-ratio: 3 / 1.5;

  /* Similar factor */
  aspect-ratio: 10 / 5;

  /* width and peak would be the identical */
  aspect-ratio: 1 / 1;
}

Technically we don’t “get” the width or the peak, however we do get to set one primarily based on the opposite, which is the necessary factor (and because it’s a ratio, you don’t must know the precise worth — or unit — of both).

The currentColor CSS key phrase

The currentColor CSS key phrase resolves to the computed worth of the shade property. Its information kind is , so we are able to use it instead of any on any property on the identical ingredient. For instance, if we set the shade to crimson (or one thing that resolves to crimson), or if the shade is computed as crimson by way of inheritance, we might then declare border-color: currentColor to make the border crimson too:

physique {
  /* We are able to set shade right here (and let or not it's inherited) */
  shade: crimson;

  button {
    /* Or set it right here */
    shade: crimson;

    /* After which use currentColor right here */
    border-color: currentColor;
    border: 0.0625rem strong currentColor;
    background: hsl(from currentColor h s 90);
  }
}

This allows us to reuse the colour with out having to arrange customized properties, and naturally if the worth of shade modifications, currentColor will robotically replace to match it.

Whereas this isn’t the identical factor as having the ability to get the colour of actually something, it’s nonetheless fairly helpful. Really, if one thing akin to compute(background-color) simply isn’t potential, I’d be proud of extra CSS key phrases like currentColor.

In actual fact, currentBackgroundColor/currentBackground has already been proposed. Utilizing currentBackgroundColor for instance, we might set the border shade to be barely darker than the background shade (border-color: hsl(from currentBackgroundColor h s calc(l - 30))), or combine the background shade with one other shade after which use that because the border shade (border-color: color-mix(currentBackgroundColor, black, 30)).

However why cease there? Why not currentWidth, currentHeight, and so forth?

The from-font CSS key phrase

The from-font CSS key phrase is unique to the text-decoration-thickness property, which can be utilized to set the thickness of underlines. In the event you’ve ever hated the truth that underlines are at all times 1px whatever the font-size and font-weight, then text-decoration-thickness can repair that.

The from-font key phrase doesn’t generate a price although — it’s optionally supplied by the font maker and embedded into the font file, so that you won’t like the worth that they supply, if they supply one in any respect. In the event that they don’t, auto can be used as a fallback, which internet browsers resolve to 1px. That is high-quality should you aren’t choosy, but it surely’s nonetheless unreliable (and clearly fairly area of interest).

We are able to, nevertheless, specify a proportion worth as a substitute, which can be sure that the thickness is relative to the font-size. So, if text-decoration-thickness: from-font simply isn’t reducing it, then we’ve got that as a backup (one thing between 8% and 12% ought to do it).

Don’t underestimate CSS models

You most likely already find out about vw and vh models (viewport width and viewport peak models). These symbolize a proportion of the viewport’s width and peak respectively, so 1vw for instance can be 1% of the viewport’s width. These models could be helpful by themselves or inside a calc() operate, and used inside any property that accepts a unit.

Nonetheless, there are many different, lesser-known models that may be helpful in an analogous method:

  • 1ex: equal to the computed x-height
  • 1cap: equal to the computed cap peak
  • 1ch: equal to the computed width of the 0 glyph
  • 1lh: equal to the computed line-height (so long as you’re not trimming or including to its content material field, for instance utilizing text-box or padding, respectively, lh models could possibly be used to find out the peak of a field that has a hard and fast variety of strains)
Supply: W3

And once more, you need to use them, their logical variants (e.g., vi and vb), and their root variants (e.g., rex and rcap) inside any property that accepts a unit.

As well as, should you’re utilizing container dimension queries, you’re additionally free to make use of the next container question models inside the containment contexts:

  • 1cqw: equal to 1% of the container’s computed width
  • 1cqh: equal to 1% of the container’s computed peak
  • 1cqi: equal to 1% of the container’s computed inline dimension
  • 1cqb: equal to 1% of the container’s computed block dimension
  • 1cqmin: equal to 1cqi or 1cqb, whichever is smallest
  • 1cqmax: equal to 1cqi or 1cqb, whichever is largest

That inherit() instance from earlier, you realize, the one which isn’t at the moment supported by any internet browser? Right here’s the identical factor however with container dimension queries:

header {
  peak: 3rem;
  container: header / dimension;

  @container header (width) {
    button {
      peak: 100%;
      border-radius: calc(100cqh * 0.3);
      padding-inline: calc(100cqh * 0.5);
    }
  }
}

Or, since we’re speaking a couple of container and its direct little one, we are able to use the next shorter model that doesn’t create and question a named container (we don’t want to question the container anyway, since all we’re doing is stealing its models!):

header {
  peak: 3rem;
  container-type: dimension;

  button {
    peak: 100%;
    border-radius: calc(100cqh * 0.3);
    padding-inline: calc(100cqh * 0.5);
  }
}

Nonetheless, remember that inherit() would allow us to inherit something, whereas container dimension queries solely allow us to inherit sizes. Additionally, container dimension queries don’t work with inline containers (that’s why this model of the container is horizontally stretched), to allow them to’t clear up each drawback anyway.

In a nutshell

I’m simply going to throw compute() on the market once more, as a result of I believe it’d be a extremely nice approach to get the values of different CSS properties:

button {
  /* self could possibly be the default */
  border-radius: compute(peak, self);
  /* inherit might work like inherit() */
  border-radius: compute(peak, inherit);
  /* Good to have, however not as necessary */
  border-radius: compute(peak, #this);
}

But when it’s simply not potential, I actually like the concept of introducing extra currentColor-like key phrases. Except key phrases like from-font the place the font maker supplies the worth (or not, sigh), key phrases similar to currentWidth and currentHeight can be extremely helpful. They’d make CSS simpler to learn, and we wouldn’t must create as many customized properties.

Within the meantime although, customized properties, aspect-ratio, and sure CSS models will help us in the suitable circumstances, to not point out that we’ll be getting inherit() sooner or later. These are closely geared in the direction of getting widths and heights, which is okay as a result of that’s undoubtedly the most important drawback right here, however hopefully there are extra CSS options on the horizon that permit values for use in additional locations.

Related Articles

Latest Articles