CSS Attribute Selector Not Working Correctly with Value, Different React/Preact Behavior
See original GitHub issuepreact 10.5.7
Reproduction
To reproduce, clone the minimal repo, install dependencies, then run npm run watch
to start a local development server.
You can switch the build from Preact to React by commenting out two lines in rollup.config.js
to compare and constrast behaviors between the two.
alias({
entries: [
{ find: 'react', replacement: 'preact/compat' }, // comment out this line to see the React version
{ find: 'react-dom', replacement: 'preact/compat' }, // and this one
],
}),
I made a small video to compare the two in action.
I’m trying to use a simple CSS attribute selector on an input value, but I’m getting different behaviors in React and Preact.
In the example, the label should only have a red background when the input element is focused or when the input value is not an empty string. In React, this works as expected, but in Preact, the label always has a red background.
const Input = styled.input`
&:focus + label,
&:not([value='']):not(:focus) + label {
background-color: red;
}
`;
function App() {
const [inputVal, setInputVal] = react.useState('');
return (
<div>
<Input value={inputVal} onChange={(e) => setInputVal(e.target.value)} />
<label>
Background should only be red when focused or when value is not an empty
string.
</label>
</div>
);
}
render(<App />, document.getElementById('root'));
I’m used Styled Components in my example, but the issue still occurs when using plain CSS.
When I select the input
element in devtools, the value shows as an empty string for both React and Preact. I’m not quite sure what the underlying issue is. I don’t think it’s related to the differences in how onChange
and onInput
work in React/Preact due to some small testing I’ve done. I know attributes and props get serialized differently in Preact. Could this be the issue?
Steps to reproduce
- Clone this repo
npm install
nom run watch
Expected Behavior
Expected behavior is that React and Preact work identically and that background color of the text in the demo is red only when the input is focused or when the value of the input is not an empty string.
Actual Behavior
Highlighted text in the demo is red all the time.
If there’s something essential I’m missing, feel free to let me know. And if this is some underlying or unfixable issue, would you have pointers in how to make a library that uses code like what’s provided work correctly?
Issue Analytics
- State:
- Created 3 years ago
- Comments:11 (6 by maintainers)
Top GitHub Comments
I don’t think we should implement attribute reflection in Preact, or even in compat. It’s a huge security nightmare that we really shouldn’t be perpetuating. It was a mistake to implement in React, and is actively being considered for removal.
If you want to enable it using a hack:
FYI: If the input has a placeholder one can detect it being empty in CSS via the
:placeholder-shown
selector.If it has a
required
attribute then we can use the:invalid
pseudo to detect if it’s empty: