an

ICMR inks industry collaborations for first in-human trials

Collaborations on four molecules, a fillip for research in the country




an

Chandrayaan-3 landed on possibly oldest craters of Moon: Scientists

A crater is formed when an asteroid crashes into the surface of a larger body like a planet or a Moon.




an

AI pioneers John Hopfield and Geoffrey Hinton awarded Nobel Prize in Physics

Hinton, often referred to as the “Godfather of artificial intelligence,” alongside Hopfield, an American scientist working at Princeton, have utilised principles from physics to create algorithms and neural networks that underpin today’s AI technologies




an

ShakthiSAT mission to train 12,000 girls from 108 nations; aims satellite launch under Chandrayaan-4

Aerospace startup Space Kidz India to select one student from each of the 108 participating countries who will travel to India for hands-on training in building payloads, spacecraft prototypes




an

What are solid-fuel missiles, and why is North Korea developing them?

Solid-fuel missiles, easier to store and faster to launch than liquid-fuel counterparts, represent a strategic leap for Pyongyang’s defence capabilities 




an

Day Trading Guide for October 30, 2024: Intraday supports, resistances for Nifty50 stocks

Here are the intraday supports and resistances for widely traded stocks such as Reliance Industries, ITC, ONGC, Infosys, HDFC Bank, TCS, and SBI



  • Day trading guide

an

Nifty Prediction Today – October 30, 2024: Can be range bound. Stay out of the market

Nifty 50 October Futures contract can oscillate in a range of 24,300-24,600




an

Bank Nifty prediction today – Oct 30, 2024: Intraday trend uncertain at the moment

The key levels for Bank Nifty futures are 51,200 and 52,700




an

Day trading guide for October 31, 2024: Intraday supports, resistances for Nifty50 stocks

Here are the intraday supports and resistances for widely traded stocks such as Reliance Industries, ITC, ONGC, Infosys, HDFC Bank, TCS, and SBI



  • Day trading guide

an

Mid-life check on health insurance

How to revitalise existing health insurance policies




an

Dhanuka Agritech: What should investors do?

At the current price of ₹1,570.15, the stock trades 29 times FY24 earnings and about 24 times and 19 times its estimated FY25 and FY26 earnings




an

IndusInd, Bandhan, RBL, IDFC First, Kotak, Ujjivan et al. - Dissecting the MFI worry 

Many private banks have been hit by the turbulent MFI segment. Read on to know what has caused this distress and how investors should play this space safely




an

Bandu’s Blockbusters for Nov 3, 2024

Guess the stock that will give the best return by next Friday




an

Diary of an F&O trader - Part 2

Yet another story of how unrestricted F&O trading ruined a trader’s finances




an

Why buying a house early in career can hurt your financial well-being

Here are the reasons and why and how to save up for that ‘priced’ buy in later years




an

Swiggy IPO analysis: You can take a shot, but maybe not a big swig

The ₹11,327-crore IPO of Swiggy will value the company at a market cap of ₹87,000 crore and enterprise value (EV) of ₹78,000 crore




an

Stock to buy today: J.B. Chemicals and Pharmaceuticals (₹1,961.80): BUY

J.B. Chemicals and Pharmaceuticals share price can rise to ₹2,100




an

Safeguard your trip abroad with travel insurance

Choose the right policy based on your requirements; for an ideal deal, compare policies, premiums, features and benefits online and choose the one that fits your criteria the best




an

Nifty Prediction Today – November 04, 2024: Bearish. Go short now and on a rise

Nifty 50 November Futures contract can fall to 23,950 and 23,800




an

Bank Nifty prediction today – November 4, 2024: Bears gaining momentum

Bank Nifty futures might see a fall to 50,800




an

F&O Query: Should you hold call options on Reliance Industries and ICICI Bank?




an

Stock to buy today: Angel One (₹2,886.35): BUY

Angel One share price can rise to ₹3,400 after some more fall from here




an

Bank Nifty Prediction today – Nov 5, 2024: Might fall off a barrier, initiate short

Bank Nifty November futures areis likely to see a decline




an

Day trading guide for November 5, 2024: Intraday supports, resistances for Nifty50 stocks

Here are the intraday supports and resistances for widely traded stocks such as Reliance Industries, ITC, ONGC, Infosys, HDFC Bank, TCS, and SBI



  • Day trading guide

an

F&O Query: Should you hold call options on Infosys and Voltas?




an

Day trading guide for November 6, 2024: Intraday supports, resistances for Nifty50 stocks

Here are the intraday supports and resistances for widely traded stocks such as Reliance Industries, ITC, ONGC, Infosys, HDFC Bank, TCS, and SBI



  • Day trading guide

an

Bank Nifty Prediction today – Nov 6, 2024: Intraday trend uncertain, stay out

Bank Nifty futures is trading between key levels at 52,000 and 52,800




an

Day trading guide for November 7, 2024: Intraday supports, resistances for Nifty50 stocks

Here are the intraday supports and resistances for widely traded stocks such as Reliance Industries, ITC, ONGC, Infosys, HDFC Bank, TCS, and SBI



  • Day trading guide

an

Stock to buy today: PNB Housing Finance (₹999.2)

The price action over the past couple of weeks indicates good buying interest




an

Bank Nifty Prediction today – Nov 7, 2024: Hovering around a support, short if this base is broken

Bank Nifty futures can fall to 51,300 if it slips below 52,000 




an

Day trading guide for November 8, 2024: Intraday supports, resistances for Nifty50 stocks

Here are the intraday supports and resistances for widely traded stocks such as Reliance Industries, ITC, ONGC, Infosys, HDFC Bank, TCS, and SBI



  • Day trading guide

an

Bank Nifty prediction today – Nov 8, 2024: Trading within a range

Bank Nifty futures is currently stuck between 52,000 and 52,500




an

Ayushman Bharat senior citizen health insurance: Benefits and enrolment details

The Ayushman Bharat scheme offers ₹5 lakh health coverage for seniors 70+, free and with easy Aadhaar-based enrollment




an

Insurance Query: Stay updated on changes in health insurance norms

IRDAI’s changes to health insurance landscape provide enhanced protection, security and a more user-friendly experience




an

When the taxman comes knocking

Here’s a lowdown on notices/ intimations from the I-T department and what they mean for taxpayers




an

Bandu’s Blockbusters for Nov 10, 2024

Guess the stock that will give the best return by next Friday




an

Tech Query: What is the outlook for TVS Holdings, Gujarat State Fertilizers & Chemicals (GSFC), Ideaforge Technology and Niyogin Fintech?

We zoom in on the prospects of TVS Holdings, as also the prospects of three other stocks — Gujarat State Fertilizers & Chemicals (GSFC), Ideaforge Technology and Niyogin Fintech




an

Niva Bupa Health Insurance IPO: Should you subscribe?

The company’s ability to reign in claims in the next three years is key monitorable




an

Trump, tariffs and tax cuts – Can they power the US stock markets ahead?

As Trump 2.0 gets set to take control, the US markets are a play of opposing factors




an

New vs Old: I-T regime choice can alter your net salary

Each regime has its own tax rates, deductions and benefits that can significantly impact take-home pay. This overview help you determine which option might be the best fit for your financial situation.




an

Nifty Prediction Today – November 11, 2024: Resistance ahead. Go short on a rise

Nifty 50 November Futures contract can fall to 23,900




an

Bank Nifty Prediction Today – November 11, 2024: Wait for dips to go long

Bank Nifty November Futures can rise to 52,500 if the bounce sustains




an

Copper: Can oscillate in a range

MCX Copper Futures contract can trade in a range of ₹820-₹865




an

Day trading guide for November 12, 2024: Intraday supports, resistances for Nifty50 stocks

Here are the intraday supports and resistances for widely traded stocks such as Reliance Industries, ITC, ONGC, Infosys, HDFC Bank, TCS, and SBI



  • Day trading guide

an

fit-content and fit-content()

Today we will look at fit-content and fit-content(), which are special values for width and grid definitions. It’s ... complicated — not as a concept, but in its practical application.

min- and max-content

Before looking at fit-content we have to briefly review two other special width values: min-content and max-content. You need those in order to understand fit-content.

Normally (i.e. with width: auto defined or implied) a box will take as much horizontal space as it can. You can change the horizontal space by giving width a specifc value, but you can also order the browser to determine it from the box’s contents. That’s what min-content and max-content do.

Try them below.

min-content and max-content
width: auto: as much as possible
width: max-content
width: min-content
width: max-content with a long text that runs the danger of disappearing right out of the browser window if it continues for much longer
  • min-content means: the minimal width the box needs to contain its contents. In practice this means that browsers see which bit of content is widest and set the width of the box to that value. The widest bit of content is the longest word in a text, or the widest image or video or other asset.
  • max-content means: the width the box needs to contain all of its contents. In the case of text this means that all text is placed on one line and the box becomes as wide as necessary to contain that entire line. In general this is not a desirable effect. The largest bit of content may also be an image or video other asset; in that case browsers use this width to determine the box’s width.

If you use hyphens: auto or something similar, the browser will break the words at the correct hyphenation points before determining the minimal width. (I turned off hyphenation in the examples.)

Quick Chromia/Android rabbit hole

All Chromium-based browsers on Android (tested in Chrome (v90), Samsung Internet (v87), and Edge (v77)) break off the 'width: max-content' text in the example above at the dash, and thus take the 'width: max-' as the max-content, provided the page does NOT have a meta viewport. No other browser does this — and that includes Chrome on Mac.

Also, Chromia on Android make the font-size a tad smaller when you resize the boxes below the maximum possible width. I will ignore both bugs because this article is about fit-content, and not about these rabbit holes.

These bugs do NOT occur in UC (based on Chromium 78). Seems UC is taking its own decisions here, and is impervious to these particular bugs.

fit-content

Now that we understand these values we also understand fit-content. It is essentially a shorthand for the following:

box {
	width: auto;
	min-width: min-content;
	max-width: max-content;
}

Thus the box sizes with its containing box, but to a minimum of min-content and to a maximum of max-content.

fit-content as width, min-width, and max-width
width: fit-content: trying to find my fit
min-width: fit-content
max-width: fit-content

I’m not sure if this effect is useful outside a grid or flexbox context, but it’s here if you need it.

fit-content as min- or max-width

You can also use fit-content as a min-width or max-width value; see the example above. The first means that the width of the box varies between min-content and auto, while the second means it varies between 0 and max-content.

I find this fairly useless and potentially confusing. What you really mean is min-width: min-content or max-width: max-content. If that’s what you mean, say so. Your CSS will be clearer if you do.

So I believe that it would be better not to use fit-content for min-width or max-width; but only for width.

-moz-

Unfortunately, while fit-content works in all other browsers, Firefox still needs a vendor prefix. So the final code becomes:

box {
	width: -moz-fit-content;
	width: fit-content;
}

(These prefixes get harder and harder to defend as time goes by. fit-content has perfectly fine cross-browser support, so I don’t see why Firefox doesn’t just go over to the regular variant.)

fit-content in flexbox and grid: nope

fit-content does not work in flexbox and grid. In the example below the centre box has width: fit-content; it does not work. If it worked the middle box would have a width of max-content; i.e. as small as it needs to be to contain its text.

Flexbox with fit-content
Test content
fit-content
Test content

The final example on this page has a test where you can see grid doesn’t understand this keyword, either.

Note that grid and flex items have min-width: min-content by default, as you can see in the example above.

fit-content()

Let’s go to the more complex part: fit-content(). Although it’s supposed to work for a normal width, it doesn’t.

fit-content and fit-content() as width
width: fit-content: trying to find my fit
width: fit-content(200px)

Grid

You can use fit-content(value) in grid templates, like:

1fr fit-content(200px) 1fr
Grid with fit-content(200px)
Test content
fit-content(200px)
Test content

It means

1fr min(max-content-size, max(min-content, 200px)) 1fr

The max() argument becomes min-content or 200 pixels, whichever is larger. This is then compared to the maximum content size, which is the actual width available due to the constraints of the grid, but with a maximum of max-content. So the real formula is more like this one, where available-size is the available width in the grid:

1fr min(min(max-content,available-size), max(min-content, 200px)) 1fr

Some syntactic notes:

  • We’re talking fit-content() the function here. fit-content the keyword does not work in grid definitions.
  • Here Firefox does not need -moz-. Go figure.
  • fit-content() needs an argument; an empty function does not work. Also, an argument in fr units is invalid.
  • MDN mentions a value fit-content(stretch). It does not work anywhere, and isn’t referred to anywhere else. I assume it comes from an older version of the spec.

I tested most of these things in the following example, where you can also try the bits of syntax that do not work — maybe they’ll start working later.

And that’s fit-content and fit-content() for you. It’s useful in some situations.

Below you can play around with fit-content() in a grid.

Grid with controls

Set grid-template-columns: to

Test content
fit-content() with some more text



  • CSS for JavaScripters

an

aspect-ratio and grid

I’m currently investigating the new aspect-ratio declaration and plan to write an article about it. However, I got stuck on aspect ratios in a grid context. Chrome/Safari and Firefox do something different here, and I understand neither approach. So I hope I can get some help.

aspect-ratio is currently supported by Chrome 90, by Firefox 88 with the correct flag enabled, and by Safari Technology Preview. I tested mostly in the first two — for complicated reasons I cannot install STP right now, but a kind Twitter follower sent me a few screenshots. It behaves as Chrome.

First, a general remark. aspect-ratio is intentionally a fairly weak declaration. It gives way if other constraints on boxes make the requested aspect ratio impossible. Take this example:

.my-box {
	width: 100px;
	height: 50px;
	aspect-ratio: 16/9;
}

The box has a fixed width and height, and they overrule the aspect-ratio. The box will thus have a 2/1 aspect ratio, as dictated by its width and height, and not a 16/9 one.

Flexbox

With that in mind, let’s first look at aspect-ratio in a flexbox environment. I think I understand what’s going on here, and the browsers all do the same, so this is a good reference point for the grid problems we’ll encounter later.

Flex items take their width from the flexbox environment. In my example they have a flex-basis: 30%, but they could also have a width or even no width/flex-basis definition at all. In all cases the flexbox algorithm decides on the width of each item.

Once the width has been determined, it’s time for the height. Let’s assume it’s not set. In flexbox, height: auto means not “as high as you need to be for your content” but “as high as the highest box in your row.”

That is, naturally flexbox would give the boxes an equal width (because that’s what my flex declarations say) and an equal height (because that always happens in flexbox). Apparently, this counts as a set height for the aspect-ratio algorithm.

As a result the 16/9 value is ignored because the 4/3 results in a larger height, and this value is therefore the one that determines the height of the entire row.

As you see, the third box in this example does have the correct aspect ratio. That’s because it has an explicit height: min-content: set your height to whatever your content needs, and, more importantly, ignore the row height of the flex box. This, apparently, gives the aspect ratio algorithm the opening it needs to set the height to the one requested by the aspect-ratio: 16/9.

I’m not sure if my reasoning is right. I am very certain that this works in all browsers, though, so you can use height: min-content in production straight away. (max-content also works. There’s no real difference between the two in height declarations.)

flex aspect-ratio and min-content

The problem: grid

Now we get to the problem: grid. To follow along, please look at the example below in Firefox 88 with the aspect-ratio flag on, and in either Chrome or Safari Technology Preview.

I expected grid to more or less behave the same as flexbox: the widths are set by the grid, the heights by the row height, and getting the proper aspect ratio would require height: min-content. That last clause is correct: the min-content trick works as it does in flexbox. It’s the behaviour of th 16/9 box without min-content that surprises me.

Here, again, the third box has height: min-content and takes the correct aspect ratio, which means not obeying the row height, in all browsers.

grid aspect-ratio and min-content

Firefox first. All boxes get their correct aspect ratio and they all have the same width, as the repeat: (3,1fr) grid template dictates. That means their height differs. More importantly, the grid container box now becomes only as high as is necessary to contain the items as they would have been without their aspect ratio.

I am 99% certain that the grid container behaviour is a bug. I am less certain whether the aspect-ratio being obeyed is also a bug.

In Chrome, the second and third box behave as expected: the last box becomes less high than the row height because of height: min-content, and the second box dictates the row height with its 4/3 aspect ratio.

But what’s up with the first box? It appears that it takes the row height as a given, but then sets the width to the value dictated by the 16/9 aspect ratio, ignoring the fact that this box now overflows its proper grid placement. Is this a bug? Or does height count for more than width in a grid context? I don’t know.

In the second example all grid items have min-height: 100px. In all browsers they they calculate their width from their aspect ratio. Thus they break the grid-defined widths. This is understandable, given that the explicit height declaration is “stronger” than the implied widths from the grid definition. (Or rather: I devoutly hope I’m right here and not talking nonsense.)

grid aspect-ratio and min-height: 100px;

Thus maybe Firefox on the one hand and Chrome/Safari on the other are not as far apart as one would think from the first grid example. Still, something is buggy in that example. I just can’t figure out what it is.

Stumped. Please help.



  • CSS for JavaScripters

an

Custom properties and @property

You’re reading a failed article. I hoped to write about @property and how it is useful for extending CSS inheritance considerably in many different circumstances. Alas, I failed. @property turns out to be very useful for font sizes, but does not even approach the general applicability I hoped for.

Grandparent-inheriting

It all started when I commented on what I thought was an interesting but theoretical idea by Lea Verou: what if elements could inherit the font size of not their parent, but their grandparent? Something like this:

div.grandparent {
	/* font-size could be anything */
}

div.parent {
	font-size: 0.4em;
}

div.child {
	font-size: [inherit from grandparent in some sort of way];
	font-size: [yes, you could do 2.5em to restore the grandparent's font size];
	font-size: [but that's not inheriting, it's just reversing a calculation];
	font-size: [and it will not work if the parent's font size is also unknown];
}

Lea told me this wasn’t a vague idea, but something that can be done right now. I was quite surprised — and I assume many of my readers are as well — and asked for more information. So she wrote Inherit ancestor font-size, for fun and profit, where she explained how the new Houdini @property can be used to do this.

This was seriously cool. Also, I picked up a few interesting bits about how CSS custom properties and Houdini @property work. I decided to explain these tricky bits in simple terms — mostly because I know that by writing an explanation I myself will understand them better — and to suggest other possibilities for using Lea’s idea.

Alas, that last objective is where I failed. Lea’s idea can only be used for font sizes. That’s an important use case, but I had hoped for more. The reasons why it doesn’t work elsewhere are instructive, though.

Tokens and values

Let’s consider CSS custom properties. What if we store the grandparent’s font size in a custom property and use that in the child?

div.grandparent {
	/* font-size could be anything */
	--myFontSize: 1em;
}

div.parent {
	font-size: 0.4em;
}

div.child {
	font-size: var(--myFontSize);
	/* hey, that's the grandparent's font size, isn't it? */
}

This does not work. The child will have the same font size as the parent, and ignore the grandparent. In order to understand why we need to understand how custom properties work. What does this line of CSS do?

--myFontSize: 1em;

It sets a custom property that we can use later. Well duh.

Sure. But what value does this custom property have?

... errr ... 1em?

Nope. The answer is: none. That’s why the code example doesn’t work.

When they are defined, custom properties do not have a value or a type. All that you ordered the browsers to do is to store a token in the variable --myFontSize.

This took me a while to wrap my head around, so let’s go a bit deeper. What is a token? Let’s briefly switch to JavaScript to explain.

let myVar = 10;

What’s the value of myVar in this line? I do not mean: what value is stored in the variable myVar, but: what value does the character sequence myVar have in that line of code? And what type?

Well, none. Duh. It’s not a variable or value, it’s just a token that the JavaScript engine interprets as “allow me to access and change a specific variable” whenever you type it.

CSS custom properties also hold such tokens. They do not have any intrinsic meaning. Instead, they acquire meaning when they are interpreted by the CSS engine in a certain context, just as the myVar token is in the JavaScript example.

So the CSS custom property contains the token 1em without any value, without any type, without any meaning — as yet.

You can use pretty any bunch of characters in a custom property definition. Browsers make no assumptions about their validity or usefulness because they don’t yet know what you want to do with the token. So this, too, is a perfectly fine CSS custom property:

--myEgoTrip: ppk;

Browsers shrug, create the custom property, and store the indicated token. The fact that ppk is invalid in all CSS contexts is irrelevant: we haven’t tried to use it yet.

It’s when you actually use the custom property that values and types are assigned. So let’s use it:

background-color: var(--myEgoTrip);

Now the CSS parser takes the tokens we defined earlier and replaces the custom property with them:

background-color: ppk;

And only NOW the tokens are read and intrepreted. In this case that results in an error: ppk is not a valid value for background-color. So the CSS declaration as a whole is invalid and nothing happens — well, technically it gets the unset value, but the net result is the same. The custom property itself is still perfectly valid, though.

The same happens in our original code example:

div.grandparent {
	/* font-size could be anything */
	--myFontSize: 1em; /* just a token; no value, no meaning */
}

div.parent {
	font-size: 0.4em;
}

div.child {
	font-size: var(--myFontSize);
	/* becomes */
	font-size: 1em; 
	/* hey, this is valid CSS! */
	/* Right, you obviously want the font size to be the same as the parent's */
	/* Sure thing, here you go */
}

In div.child he tokens are read and interpreted by the CSS parser. This results in a declaration font-size: 1em;. This is perfectly valid CSS, and the browsers duly note that the font size of this element should be 1em.

font-size: 1em is relative. To what? Well, to the parent’s font size, of course. Duh. That’s how CSS font-size works.

So now the font size of the child becomes the same as its parent’s, and browsers will proudly display the child element’s text in the same font size as the parent element’s while ignoring the grandparent.

This is not what we wanted to achieve, though. We want the grandparent’s font size. Custom properties — by themselves — don’t do what we want. We have to find another solution.

@property

Lea’s article explains that other solution. We have to use the Houdini @property rule.

@property --myFontSize {
	syntax: "<length>";
	initial-value: 0;
	inherits: true;
}

div {
	border: 1px solid;
	padding: 1em;
}

div.grandparent {
	/* font-size could be anything */
	--myFontSize: 1em;
}

div.parent {
	font-size: 0.4em;
}

div.child {
	font-size: var(--myFontSize);
}

Now it works. Wut? Yep — though only in Chrome so far.

This is the grandparent
This is the parent
This is the child

What black magic is this?

Adding the @property rule changes the custom property --myFontSize from a bunch of tokens without meaning to an actual value. Moreover, this value is calculated in the context it is defined in — the grandfather — so that the 1em value now means 100% of the font size of the grandfather. When we use it in the child it still has this value, and therefore the child gets the same font size as the grandfather, which is exactly what we want to achieve.

(The variable uses a value from the context it’s defined in, and not the context it’s executed in. If, like me, you have a grounding in basic JavaScript you may hear “closures!” in the back of your mind. While they are not the same, and you shouldn’t take this apparent equivalency too far, this notion still helped me understand. Maybe it’ll help you as well.)

Unfortunately I do not quite understand what I’m doing here, though I can assure you the code snippet works in Chrome — and will likely work in the other browsers once they support @property.

Misson completed — just don’t ask me how.

Syntax

You have to get the definition right. You need all three lines in the @property rule. See also the specification and the MDN page.

@property --myFontSize {
	syntax: "<length>";
	initial-value: 0;
	inherits: true;
}

The syntax property tells browsers what kind of property it is and makes parsing it easier. Here is the list of possible values for syntax, and in 99% of the cases one of these values is what you need.

You could also create your own syntax, e.g.

syntax: "ppk | <length>"

Now the ppk keyword and any sort of length is allowed as a value.

Note that percentages are not lengths — one of the many things I found out during the writing of this article. Still, they are so common that a special value for “length that may be a percentage or may be calculated using percentages” was created:

syntax: "<length-percentage>"

Finally, one special case you need to know about is this one:

syntax: "*"

MDN calls this a universal selector, but it isn’t, really. Instead, it means “I don’t know what syntax we’re going to use” and it tells browsers not to attempt to interpret the custom property. In our case that would be counterproductive: we definitely want the 1em to be interpreted. So our example doesn’t work with syntax: "*".

initial-value and inherits

An initial-value property is required for any syntax value that is not a *. Here that’s simple: just give it an initial value of 0 — or 16px, or any absolute value. The value doesn’t really matter since we’re going to overrule it anyway. Still, a relative value such as 1em is not allowed: browsers don’t know what the 1em would be relative to and reject it as an initial value.

Finally, inherits: true specifies that the custom property value can be inherited. We definitely want the computed 1em value to be inherited by the child — that’s the entire point of this experiment. So we carefully set this flag to true.

Other use cases

So far this article merely rehashed parts of Lea’s. Since I’m not in the habit of rehashing other people’s articles my original plan was to add at least one other use case. Alas, I failed, though Lea was kind enough to explain why each of my ideas fails.

Percentage of what?

Could we grandfather-inherit percentual margins and paddings? They are relative to the width of the parent of the element you define them on, and I was wondering if it might be useful to send the grandparent’s margin on to the child just like the font size. Something like this:

@property --myMargin {
	syntax: "<length-percentage>";
	initial-value: 0;
	inherits: true;
}

div.grandparent {
	--myMargin: 25%;
	margin-left: var(--myMargin);
}

div.parent {
	font-size: 0.4em;
}

div.child {
	margin-left: var(--myMargin);
	/* should now be 25% of the width of the grandfather's parent */
	/* but isn't */
}

Alas, this does not work. Browsers cannot resolve the 25% in the context of the grandparent, as they did with the 1em, because they don’t know what to do.

The most important trick for using percentages in CSS is to always ask yourself: “percentage of WHAT?”

That’s exactly what browsers do when they encounter this @property definition. 25% of what? The parent’s font size? Or the parent’s width? (This is the correct answer, but browsers have no way of knowing that.) Or maybe the width of the element itself, for use in background-position?

Since browsers cannot figure out what the percentage is relative to they do nothing: the custom property gets the initial value of 0 and the grandfather-inheritance fails.

Colours

Another idea I had was using this trick for the grandfather’s text colour. What if we store currentColor, which always has the value of the element’s text colour, and send it on to the grandchild? Something like this:

@property --myColor {
	syntax: "<color>";
	initial-value: black;
	inherits: true;
}

div.grandparent {
	/* color unknown */
	--myColor: currentColor;
}

div.parent {
	color: red;
}

div.child {
	color: var(--myColor);
	/* should now have the same color as the grandfather */
	/* but doesn't */
}

Alas, this does not work either. When the @property blocks are evaluated, and 1em is calculated, currentColor specifically is not touched because it is used as an initial (default) value for some inherited SVG and CSS properties such as fill. Unfortunately I do not fully understand what’s going on, but Tab says this behaviour is necessary, so it is.

Pity, but such is life. Especially when you’re working with new CSS functionalities.

Conclusion

So I tried to find more possbilities for using Lea’s trick, but failed. Relative units are fairly sparse, especially when you leave percentages out of the equation. em and related units such as rem are the only ones, as far as I can see.

So we’re left with a very useful trick for font sizes. You should use it when you need it (bearing in mind that right now it’s only supported in Chromium-based browsers), but extending it to other declarations is not possible at the moment.

Many thanks to Lea Verou and Tab Atkins for reviewing and correcting an earlier draft of this article.



  • CSS for JavaScripters

an

New business wanted

Last week Krijn and I decided to cancel performance.now() 2021. Although it was the right decision it leaves me in financially fairly dire straits. So I’m looking for new jobs and/or donations.

Even though the Corona trends in NL look good, and we could probably have brought 350 people together in November, we cannot be certain: there might be a new flare-up. More serious is the fact that it’s very hard to figure out how to apply the Corona checks Dutch government requires, especially for non-EU citizens. We couldn’t figure out how UK and US people should be tested, and for us that was the straw that broke the camel’s back. Cancelling the conference relieved us of a lot of stress.

Still, it also relieved me of a lot of money. This is the fourth conference in a row we cannot run, and I have burned through all my reserves. That’s why I thought I’d ask for help.

So ...

Has QuirksMode.org ever saved you a lot of time on a project? Did it advance your career? If so, now would be a great time to make a donation to show your appreciation.

I am trying my hand at CSS coaching. Though I had only few clients so far I found that I like it and would like to do it more. As an added bonus, because I’m still writing my CSS for JavaScripters book I currently have most of the CSS layout modules in my head and can explain them straight away — even stacking contexts.

Or if there’s any job you know of that requires a technical documentation writer with a solid knowledge of web technologies and the browser market, drop me a line. I’m interested.

Anyway, thanks for listening.




an

Nirdiganta: A first-of-its-kind incubation centre for theatre 

Actor Prakash Raj’s innovative incubator for theatre and arts offers a comprehensive production process, stipends for actors/techs, lodging, kitchen and tech support. It also plans to promote fine arts and film in the future.




an

Prakash Raj on creating ‘Nirdiganta’, an incubation centre for theatre, and getting back on stage 

Actor Prakash Raj says fans will soon get to see him perform live on stage