material-design-light icon indicating copy to clipboard operation
material-design-light copied to clipboard

Text fields uses :has() CSS pseudo-class that many browsers don't support yet

Open robinlahtinen opened this issue 1 year ago • 5 comments

Describe the bug Text fields uses :has() CSS pseudo-class that many browsers don't support as of yet.

Useful links

  • https://caniuse.com/css-has

To Reproduce Steps to reproduce the behavior:

  1. Go to https://www.materialdesignlight.com/
  2. See or interact with text field components
  3. See error

Expected behavior All expected features under :has() pseudo-classes to work. Use Chrome Dev or newer browser for working implementation.

Plan N/A

robinlahtinen avatar Jul 04 '22 19:07 robinlahtinen

Thinking of replacing :has with general sibling combinator (~).

robinlahtinen avatar Jul 05 '22 17:07 robinlahtinen

Chromium based browsers now support :has(), but Firefox still hasn't enabled it for general use.

robinlahtinen avatar Nov 13 '22 18:11 robinlahtinen

Another workaround would be to just use classes on the parent tag and child or sibling tags if needed. But... it would provide a worse developer experience, that I would like to avoid.

robinlahtinen avatar Mar 07 '23 19:03 robinlahtinen

I am adding some comments/thoughts that might be useful to people looking at this issue:

  • It is tricky to get rid of the has() css selector in a way that is compatible with old browsers (without Js)
  • It is working correctly for regular states (enabled, hover, focussed)
  • For reference, here is the html that we're working with:
<div class='textfield-filled''>
  <label class="textfield-container">
    <span class='textfield-leading-icon material-symbols-outlined'>search</span>
    <input class='textfield-input' type="text" placeholder=' '>
    <span class='textfield-label'>Label</span>
    <span class='textfield-trailing-icon material-symbols-outlined'>cancel</span>
  </label>
  <a class='textfield-supporting-text'>Supporting text</a>
</div>
  • However, the question now is: how to support the disabled state (in a cross browser manner)?
    • Usually, I would put the disabled attribute on the input element
    • However, if I do that, it means that I've got to style the leading icon, trailing icon and such based upon the disabled attribute of the input. Which is fine if using the sibling selector. However, some elements are sibling(label, trailing icon) but some are not (leading icon, supporting text) and it may be even worse with the upcoming support for prefix and suffix text
  • Therefore I am leaning toward adding the disabled attribute on the root element, the main div whose class is 'textfield-filled''
  • Note that the current implementation of material design 2 requires adding a 'mdc-text-field--disabled' class on the root element as well as a disabled attribute on the input element:
<label class="mdc-text-field mdc-text-field--filled mdc-text-field--disabled">
  <span class="mdc-text-field__ripple"></span>
  <span class="mdc-floating-label" id="my-label-id">Disabled text field</span>
  <input class="mdc-text-field__input" type="text" aria-labelledby="my-label-id" disabled>
  <span class="mdc-line-ripple"></span>
</label>

ref: https://m2.material.io/components/text-fields/web#other-variations

stephanebastian avatar Mar 14 '23 08:03 stephanebastian

  • Therefore I am leaning toward adding the disabled attribute on the root element, the main div whose class is 'textfield-filled''

That compromise sounds ok. Doesn't seem to interfere with semantics or accessibility.

robinlahtinen avatar Mar 15 '23 21:03 robinlahtinen