question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

CSS Attribute Selector Not Working Correctly with Value, Different React/Preact Behavior

See original GitHub issue

preact 10.5.7

Reproduction

Minimal Reproduction Repo

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

  1. Clone this repo
  2. npm install
  3. 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:closed
  • Created 3 years ago
  • Comments:11 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
developitcommented, Dec 2, 2020

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:

import { options } from 'preact';

let old = options.vnode;
options.vnode = vnode => {
  let props = vnode.props;
  if (typeof vnode.type == 'string' && props && 'value' in props) {
    props.Value = props.value;
  }
  if (old) old(vnode);
};
1reaction
marvinhagemeistercommented, Dec 3, 2020

FYI: If the input has a placeholder one can detect it being empty in CSS via the :placeholder-shown selector.

input:placeholder-shown {
  border: 1px solid red;
}

If it has a required attribute then we can use the :invalid pseudo to detect if it’s empty:

input:invalid {
  border: 1px solid red;
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

CSS attribute selector not working when the ... - Stack Overflow
The updated attribute-value (as represented in the style attribute) seems to be a representation of the style property (derived, presumably, ...
Read more >
Attribute selectors - CSS: Cascading Style Sheets | MDN
The CSS attribute selector matches elements based on the presence or value of a given attribute.
Read more >
[attribute] | CSS-Tricks
Value contains: attribute value contains a term as the only value, a value in a list of values, or as part of another...
Read more >
How To Select HTML Elements Using ID, Class, and Attribute ...
To start working with id , class , and attribute selectors, you will first set up the HTML and CSS code that you...
Read more >
Attribute Selectors | Codrops
Regardless of whether the attribute is correctly applied or not, you can still select it via CSS. But it is really bad practice...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found