Skip to content
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

:placeholder-shown is replaced with -moz-placeholder, although this is outdated #1533

Open
kliehm opened this issue Mar 20, 2025 · 17 comments
Open

Comments

@kliehm
Copy link

kliehm commented Mar 20, 2025

Due to a change in autoprefixer in the last two weeks I assume, suddenly :placeholder-shown is replaced with :-moz-placeholder. According to caniuse, this should only be necessary in Firefox < 50, not in current versions.

Although as far as I understand, :-moz-placeholder should be a synonym to ::placeholder, i.e. to style the placeholder, whereas :placeholder-shown is an indicator if the placeholder is visible or not. So if the focus is within the input and the placeholder text disappears, :placeholder-shown is false. That's something different than styling the placeholder.

Our .browserslistrc looks like this, so Firefox < 50 should not be relevant:

> 1% in DE
last 2 versions
not dead

For the time being, I disabled replacement of :placeholder-shown with /* autoprefixer: ignore next */.

@ai
Copy link
Member

ai commented Mar 20, 2025

Can you show simple example of input CSS, output and expected output?

@ai
Copy link
Member

ai commented Mar 20, 2025

cc @Marukome0743

@ai
Copy link
Member

ai commented Mar 20, 2025

Although as far as I understand, :-moz-placeholder should be a synonym to ::placeholder, i.e. to style the placeholder, whereas :placeholder-shown is an indicator if the placeholder is visible or not

https://caniuse.com/?search=placeholder-shown says that :-moz-placeholder equals to :placeholder-shown.

Also, another argument is that :placeholder-shown and :-moz-placeholder both uses single : (which means it is a state, not [virtual] element).

But we may be wrong. Please show your proofs or arguments.

@kliehm
Copy link
Author

kliehm commented Mar 20, 2025

https://caniuse.com/?search=placeholder-shown says that :-moz-placeholder equals to :placeholder-shown.

Yes, but that's only true for Firefox prior v50. Modern Firefoxes support :placeholder-shown.

Here is a minimal example: show the label only if the placeholder is visible:

HTML:
<input placeholder="&nbsp;" /><label>Text</label>

CSS:
label { display: none };
input:not(:placeholder-shown) + label { display: block }

In retrospective, I could have achieved the same effect with :empty, but this is how we've done it. It worked until recently. With the replacement it doesn't work as expected anymore in current versions of Firefox:

input:not(:-moz-placeholder) + label { display: block }

I appreciate your great work, that's only a little annoyance. :)

@ai
Copy link
Member

ai commented Mar 20, 2025

Oh, so you have a problem only with not()? It is important note.

Can you show current output and expected output (with prefixes)?

@kliehm
Copy link
Author

kliehm commented Mar 20, 2025

Can you show simple example of input CSS, output and expected output?

Here it still works: the search field at the top has a label "what are you looking for" that disappears, when the input receives focus. Also the reset button (the x) only appears when there is text in the input.

https://verwaltung.bund.de/portal/EN

The negative case only appears on dev stages so far.

@ai
Copy link
Member

ai commented Mar 20, 2025

  1. I need to show a small isolated example, not the whole website. Sorry, debugging the huge part of code is hard (and it could be an issue in another part than Autoprefixer, maybe you rely on broken behavior).
  2. I need current output and output that it is expected (so the 1 link doesn’t work).

@kliehm
Copy link
Author

kliehm commented Mar 20, 2025

Okay, I made a fiddle: https://codepen.io/kliehm/pen/ZYExNdd

With a current Firefox you can see that :placeholder-shown is not equivalent to :-moz-placeholder.

So in current versions of Firefox autoprefixer shouldn't replace it. I didn't succeed to include different versions of autoprefixer in the fiddle, so I made it static. My apologies that I'm not able to pin it down further, if it's a problem with autoprefixer or browserslist. I don't think it's a change in Firefox, since in version 10.4.21 of autoprefixer it gets replaced with :-moz-placeholder, whereas in version 10.4.20 it didn't.

@ai
Copy link
Member

ai commented Mar 20, 2025

  1. This fiddle is also useful, thanks for it.
  2. But fiddle is not actual/expected CSS output. Please, it is really important for me to follow the instruction because it saves my time for maintaince open source project.
  3. Talking about this fiddle. What is expected and real behaviour. Please show the screenshot.

I see that Firefox and Chroma output is exactly the same.

Image

@kliehm
Copy link
Author

kliehm commented Mar 20, 2025

Okay, sorry for the inconvenience. This is my output on Firefox v136.0.2 (Windows). It's interesting that your browser is interpreting the second part exactly opposite from the expected behavior of :-moz-placeholder. I can reproduce your screenshot with Chrome 134.0.6998.89.

The expected behavior is the top two examples with :placeholder-shown, same as your result.

The bottom two examples with :-moz-placeholder show that it's not the same result as :placeholder-shown. Although you get different results, you can see that it's not equivalent.

Image

@kliehm
Copy link
Author

kliehm commented Mar 21, 2025

@Marukome0743 I could pin it down: it worked with autoprefixer 10.4.20, was broken with autoprefixer 10.4.21. It is this commit.

The problem is that caniuse lists the replacement with :-moz-placeholder only for Mozilla < 50. For Mozilla > 50 it shouldn't be replaced, pretty please.

@Marukome0743
Copy link
Contributor

Marukome0743 commented Mar 25, 2025

The problem is that caniuse lists the replacement with :-moz-placeholder only for Mozilla < 50. For Mozilla > 50 it shouldn't be replaced, pretty please.

Explanation of bug

TL;DR: The support of Kaios 2.5

I finally found out the cause of this issue.
I will describe this step by step.

First, Autoprefixer don't add the :-moz-placeholder under last 1 version browsersl.ist.

Autoprefixer last 1 preview

Image

Second, Autoprefixer appends the :-moz-placeholder from last 2 version browsersl.ist.

Autoprefixer last 2 version preview

Image

Third, I checked the target browsers of the :placeholder-shown property from below code..

// Placeholder-shown selector
let prefixPlaceholderShown = require('caniuse-lite/data/features/css-placeholder-shown')
f(prefixPlaceholderShown, browsers => {
prefix([':placeholder-shown'], {
browsers,
feature: 'css-placeholder-shown',
selector: true
})
})

:placeholder-shown target browsers

[
  'firefox 4',  'firefox 5',  'firefox 6',
  'firefox 7',  'firefox 8',  'firefox 9',
  'firefox 10', 'firefox 11', 'firefox 12',
  'firefox 13', 'firefox 14', 'firefox 15',
  'firefox 16', 'firefox 17', 'firefox 18',
  'firefox 19', 'firefox 20', 'firefox 21',
  'firefox 22', 'firefox 23', 'firefox 24',
  'firefox 25', 'firefox 26', 'firefox 27',
  'firefox 28', 'firefox 29', 'firefox 30',
  'firefox 31', 'firefox 32', 'firefox 33',
  'firefox 34', 'firefox 35', 'firefox 36',
  'firefox 37', 'firefox 38', 'firefox 39',
  'firefox 40', 'firefox 41', 'firefox 42',
  'firefox 43', 'firefox 44', 'firefox 45',
  'firefox 46', 'firefox 47', 'firefox 48',
  'firefox 49', 'firefox 50', 'ie 10',
  'ie 11',      'kaios 2.5'
]

The last 2 version browsersl.ist doesn't include the old firefox browsers.
So why does Autoprefixer insert the :-moz-placeholder when you cover only last 2 version?

Because of kaios 2.5.

The last 2 version browsersl.ist covers kaios 2.5.

The last 2 version browsersl.ist

Image

In conclusion, Autoprefixer adds :-moz-placeholder with last 2 version browsersl.ist due to kaios 2.5.

Solutions

1. Do nothing

This is a desired result for the people who want to cover kaios 2.5.
Then continue to adding :-moz-placeholder.

2. Remove kaios from your own Browserslist.

You can change the target of the browsers using .browserslistrc, package.json and so on.
See Browserslist docs for available queries and default value.

3. Don't parse :placeholder-shown to :-moz-placeholder

At first my PR was the removal of :-moz-placeholder-shown property.
I didn't know the old firefox supports the non-standard :-moz-placeholder name rather than :placeholder-shown partially.
To avoid confusing, stop to parse :placeholder-shown to :-moz-placeholder.

Which solution is better?
Thank you for reading!

@kliehm
Copy link
Author

kliehm commented Mar 25, 2025

3. Don't parse :placeholder-shown to :-moz-placeholder

At first my PR was the removal of :-moz-placeholder-shown property. I didn't know the old firefox supports the non-standard :-moz-placeholder name rather than :placeholder-shown partially. To avoid confusing, stop to parse :placeholder-shown to :-moz-placeholder.

Which solution is better? Thank you for reading!

Thank you for your research. I'm afraid solution #2 doesn't work. According to our Browserslist configuration, KaiOS should be excluded:

> 1% in DE
last 2 versions
not dead

Other browsers and OS have a current market share in Germany of < 0.2% (KaiOS doesn't even appear in stats after 2018), so it shouldn't be included. If that configuration doesn't work, I'd prefer solution #3.

@Marukome0743
Copy link
Contributor

I wonder if you use or combiner instead of and one.


Image


Image


Then you should write this code.

> 1% in DE and last 2 versions
not dead

Please forgive me if it's wrong because I'm newbie on browserslist.

@kliehm
Copy link
Author

kliehm commented Mar 25, 2025

Then you should write this code.

> 1% in DE and last 2 versions
not dead

Good point, I'm not an expert either. I will try that.

@Marukome0743
Copy link
Contributor

Eventually, I got the corrent .browserslistrc.

> 1% in DE
last 2 versions
not dead
not kaios <= 2.5
Exclude kaios from Browserslist

Image

I also paste the result of your previous one to compare easily.

> 1% in DE
last 2 versions
not dead
Previous Browserslist

Image

This .browserslistrc doesn't parse :placeholder-shown to :-moz-placeholder anymore, right?
Could you try it?

@kliehm
Copy link
Author

kliehm commented Mar 26, 2025

Could you try it?

I tried your suggestion

> 1% in DE and last 2 versions
not dead

and it works. So for me that's fine. Thank you for the kind conversation and help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants