Editorial review: Document CSS if() function by chrisdavidmills · Pull Request #39516 · mdn/content · GitHub | Latest TMZ Celebrity News & Gossip | Watch TMZ Live
Skip to content

Editorial review: Document CSS if() function #39516

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 66 commits into from
Jul 3, 2025
Merged

Conversation

chrisdavidmills
Copy link
Contributor

@chrisdavidmills chrisdavidmills commented May 14, 2025

Description

Chrome supports the CSS if() function from version 137. See https://chromestatus.com/feature/6313805904347136.

This PR documents the new function. Specifically, it:

  • Adds an if() reference page (nearly done, just needs examples)
  • Adds if() to the CSS values and units module page
  • Adds if() to the CSS value functions ref page.

Motivation

Additional details

Related issues and pull requests

@chrisdavidmills chrisdavidmills requested a review from a team as a code owner May 14, 2025 13:32
@chrisdavidmills chrisdavidmills requested review from estelle and removed request for a team May 14, 2025 13:32
@github-actions github-actions bot added the Content:CSS Cascading Style Sheets docs label May 14, 2025
@chrisdavidmills chrisdavidmills marked this pull request as draft May 14, 2025 13:33
@chrisdavidmills chrisdavidmills removed the request for review from estelle May 14, 2025 13:33
@github-actions github-actions bot added the size/m [PR only] 51-500 LoC changed label May 14, 2025
@chrisdavidmills chrisdavidmills requested review from a team and estelle and removed request for a team and estelle May 14, 2025 13:33
Copy link
Contributor

github-actions bot commented May 14, 2025

Preview URLs

Flaws (4)

Note! 1 document with no flaws that don't need to be listed. 🎉

URL: /en-US/docs/Web/CSS/CSS_Values_and_Units
Title: CSS values and units
Flaw count: 1

  • macros:
    • Macro produces link /en-US/docs/Web/CSS/url which is a redirect

URL: /en-US/docs/Web/CSS/if
Title: if()
Flaw count: 3

  • broken_links:
    • /en-US/docs/Web/CSS/CSS_values_and_units is ill cased
  • macros:
    • Macro produces link /en-US/docs/Web/CSS/linear-gradient which is a redirect
  • unknown:
    • Parse error: Unexpected input

(comment last updated: 2025-07-01 18:29:47)

@github-actions github-actions bot added size/l [PR only] 501-1000 LoC changed and removed size/m [PR only] 51-500 LoC changed labels May 15, 2025
@chrisdavidmills chrisdavidmills marked this pull request as ready for review May 15, 2025 14:31
@chrisdavidmills chrisdavidmills changed the title Document CSS if() function Technical review: Document CSS if() function May 15, 2025
@chrisdavidmills chrisdavidmills requested a review from andruud May 21, 2025 15:27
@andruud
Copy link

andruud commented Jun 16, 2025

Looks good. I don't have permission to click "Approve" here, though.

@chrisdavidmills chrisdavidmills requested a review from estelle June 24, 2025 15:27
chrisdavidmills and others added 3 commits June 24, 2025 16:32
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Copy link
Member

@estelle estelle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

heading to the airport, so will finish later.

}
```

In this case, we are setting a different {{cssxref("background-image")}} {{cssxref("linear-gradient()")}} value on {{htmlelement("div")}} elements depending on whether a `--scheme` [custom property](/en-US/docs/Web/CSS/--*) is set to `ice` or `fire`. If neither value is set, the `else` value comes into play, and the `background-image` property is set to `none`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In this case, we are setting a different {{cssxref("background-image")}} {{cssxref("linear-gradient()")}} value on {{htmlelement("div")}} elements depending on whether a `--scheme` [custom property](/en-US/docs/Web/CSS/--*) is set to `ice` or `fire`. If neither value is set, the `else` value comes into play, and the `background-image` property is set to `none`.
In this case, we are setting a different {{cssxref("linear-gradient()")}} values as the {{cssxref("background-image")}} on {{htmlelement("div")}} elements, depending on whether a `--scheme` [custom property](/en-US/docs/Web/CSS/--*) is set to `ice` or `fire`. If `--scheme` doesn't exist, or it exists and is set to any other value, the `else` value comes into play, and the `background-image` property is set to `none`.

First suggestion is just so the two links aren't next to each other without content between them (cognitive: clearer that they are separate links)
second suggestion is to kind of indicate that a non-existent custom prop won't invalidate the function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable. I used it with a couple of tweaks:

In this case, we are setting a different {{cssxref("linear-gradient()")}} as the {{cssxref("background-image")}} on {{htmlelement("div")}} elements, depending on whether a --scheme custom property is set to ice or fire. If --scheme doesn't exist, or it exists and is set to any other value, the else value comes into play, and the background-image property is set to none.

> [!WARNING]
> There must be no space between the `if` and the opening parenthesis (`(`). If there is, the whole declaration is invalid.

If a single `<if-condition>` or `<value>` is invalid, it does not invalidate the entire `if()` function; instead, the parser moves on to the next `<if-condition> : <value>` pair.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If a single `<if-condition>` or `<value>` is invalid, it does not invalidate the entire `if()` function; instead, the parser moves on to the next `<if-condition> : <value>` pair.
If a single `<if-condition>` or `<value>` is invalid, it does not invalidate the entire `if()` function; instead, the parser moves on to the next `<if-condition> : <value>` pair. If no `<if-condition>` nor `<value>` valid, the function returns a guaranteed-invalid.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly used, with a couple of tweaks:

If a single <if-condition> or <value> is invalid, it does not invalidate the entire if() function; instead, the parser moves on to the next <if-condition> : <value> pair. If no <if-condition> nor <value> is valid, the function returns {{glossary("guaranteed_invalid_value", "guaranteed-invalid")}}.


You can include multiple `else : <value>` pairs inside an `if()` function, in any position. However, in most cases, a single `else : <value>` pair at the end of the semi-colon-separated list is used to provide the default value that is always returned if none of the `<if-test>`s evaluate to true.

If you include an `else : <value>` pair before any `<if-test> : <value>` pairs, the later conditions are not evaluated because the `else` always evaluates to `true`. The following `if()` therefore always returns `none`, and the two `<if-test> : <value>` pairs are never evaluated:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If you include an `else : <value>` pair before any `<if-test> : <value>` pairs, the later conditions are not evaluated because the `else` always evaluates to `true`. The following `if()` therefore always returns `none`, and the two `<if-test> : <value>` pairs are never evaluated:
If you include an `else : <value>` pair before any `<if-test> : <value>` pairs, the later conditions are not evaluated because `else` evaluates to `true`. The following `if()` therefore always returns `none`, and the two `<if-test> : <value>` pairs are never evaluated:

If you don't go with this edit, we should still get rid of "the" unless you add "keyword"
should "later" be "latter"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just removed the "the". I think it sounds better and more definite with "always" included. "latter" is not quite right because I want to include all of the values after the else : <value> pair; I think "latter" implies just the ones at the end.

I thought about it a bit, and went with "the conditions that follow it":

If you include an else : <value> pair before any <if-test> : <value> pairs, the conditions that follow it are not evaluated because else always evaluates to true. The following if() therefore always returns none, and the two <if-test> : <value> pairs are never evaluated:

WDYT?

}
```

One circumstance in which you might want to put an `else : <value>` in a position other than the end of the values list is when a value is not behaving as expected, and you are trying to debug it. In the following example, we are trying to work out whether the first `<if-test> : <value>` pair is working properly. If it isn't, the `else : <value>` pair returns a value of `url("debug.png")` to display an image indicating that the first `<if-test> : <value>` pair needs fixing. The last two `<if-test> : <value>` pairs are again never evaluated.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
One circumstance in which you might want to put an `else : <value>` in a position other than the end of the values list is when a value is not behaving as expected, and you are trying to debug it. In the following example, we are trying to work out whether the first `<if-test> : <value>` pair is working properly. If it isn't, the `else : <value>` pair returns a value of `url("debug.png")` to display an image indicating that the first `<if-test> : <value>` pair needs fixing. The last two `<if-test> : <value>` pairs are again never evaluated.
Debugging a value is not behaving as expected is a case in which you might want to put an `else : <value>` in a position other than the end of the values list. In the following example, we are trying to work out whether the first `<if-test> : <value>` pair is working properly. If it isn't, the `else : <value>` pair returns a value of `url("debug.png")` to display an image indicating that the first `<if-test> : <value>` pair needs fixing. The last two `<if-test> : <value>` pairs are again never evaluated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I played with this a bit, and ended up with:

Debugging a value that is not behaving as expected is one case where you might want to put an else : <value> in a position other than the end of the value list. In the following example, we are trying to work out whether the first <if-test> : <value> pair is working properly. If it isn't, the else : <value> pair returns a value of url("debug.png") to display an image indicating that the first <if-test> : <value> pair needs fixing. The last two <if-test> : <value> pairs are again never evaluated.


### Nesting if() functions

Because an `if()` function can take the place of whole property values or individual components, it is possible to nest multiple `if()` functions, and nest `if()` functions inside other functions such as {{cssxref("calc()")}}.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Because an `if()` function can take the place of whole property values or individual components, it is possible to nest multiple `if()` functions, and nest `if()` functions inside other functions such as {{cssxref("calc()")}}.
Because an `if()` function can take the place of whole property values or individual components, it is possible to nest `if()` functions within other `if()` functions, and to nest `if()` functions inside other functions such as {{cssxref("calc()")}}.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was mostly good; I tightened it up a bit to:

Because an if() function can take the place of whole property values or individual components, it is possible to nest if() functions within other if() functions, and inside other functions such as {{cssxref("calc()")}}.

Copy link
Member

@estelle estelle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a couple of the edits are suggetions to get the reader excited. all suggestions are minor.


Our HTML contains an {{htmlelement("article")}} element with some content inside it — a top-level heading, a couple of {{htmlelement("p")}} elements, and an {{htmlelement("aside")}}. Below that we include a {{htmlelement("form")}} containing a {{htmlelement("select")}} drop-down that allows you to select a color scheme.

```html-nolint live-sample___color-scheme
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the nolint so ipsum isn't spell-checked?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was just because prettier made the code layout a bit weird.

chrisdavidmills and others added 15 commits July 1, 2025 18:36
Co-authored-by: Estelle Weyl <estelle@openwebdocs.org>
Co-authored-by: Estelle Weyl <estelle@openwebdocs.org>
Co-authored-by: Estelle Weyl <estelle@openwebdocs.org>
Co-authored-by: Estelle Weyl <estelle@openwebdocs.org>
Co-authored-by: Estelle Weyl <estelle@openwebdocs.org>
Co-authored-by: Estelle Weyl <estelle@openwebdocs.org>
Co-authored-by: Estelle Weyl <estelle@openwebdocs.org>
Co-authored-by: Estelle Weyl <estelle@openwebdocs.org>
Co-authored-by: Estelle Weyl <estelle@openwebdocs.org>
Co-authored-by: Estelle Weyl <estelle@openwebdocs.org>
Co-authored-by: Estelle Weyl <estelle@openwebdocs.org>
Co-authored-by: Estelle Weyl <estelle@openwebdocs.org>
Co-authored-by: Estelle Weyl <estelle@openwebdocs.org>
Co-authored-by: Estelle Weyl <estelle@openwebdocs.org>
@chrisdavidmills chrisdavidmills requested a review from estelle July 1, 2025 18:30
@estelle estelle merged commit d248d3f into mdn:main Jul 3, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Content:CSS Cascading Style Sheets docs size/l [PR only] 501-1000 LoC changed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants

TMZ Celebrity News – Breaking Stories, Videos & Gossip

Looking for the latest TMZ celebrity news? You've come to the right place. From shocking Hollywood scandals to exclusive videos, TMZ delivers it all in real time.

Whether it’s a red carpet slip-up, a viral paparazzi moment, or a legal drama involving your favorite stars, TMZ news is always first to break the story. Stay in the loop with daily updates, insider tips, and jaw-dropping photos.

🎥 Watch TMZ Live

TMZ Live brings you daily celebrity news and interviews straight from the TMZ newsroom. Don’t miss a beat—watch now and see what’s trending in Hollywood.