material-components / material-web

Material Design Web Components
https://material-web.dev
Apache License 2.0
9.31k stars 890 forks source link

Setting individual shape to outlined text field fails if unit is not set #5443

Open shadow-identity opened 8 months ago

shadow-identity commented 8 months ago

What is affected?

Component

Description

I need to set a shape of the md-outlined-text-field to have rounded top angles but not rounded bottom ones when active. But it does not work if unit is not specified in css custom property which controls the shape.

Reproduction

I need to set a shape of the md-outlined-text-field to have rounded top angles and not rounded bottom. So I set the default shape and override the bottom corners:

    md-outlined-text-field {
        --md-outlined-text-field-container-shape: 1.7rem;
    }
    md-outlined-text-field:focus {
        --md-outlined-text-field-container-shape-end-start: 0;
        --md-outlined-text-field-container-shape-end-end: 0;
    }

But it results in broken shape of the component: not only the top left corner has the radius of 0, but also the left padding / margin completely disappeared:

image

Workaround

I found that if I set units explicitly (0px or 0rem) it works.

    md-outlined-text-field:focus {
        --md-outlined-text-field-container-shape-end-start: 0rem;
        --md-outlined-text-field-container-shape-end-end: 0px;
    }
image

Is this a regression?

No or unsure. This never worked, or I haven't tried before.

Affected versions

Failing on 1.2.0

Browser/OS/Node environment

Firefox 123.0b4 (64-bit) mas OS 14.3 (23D56) node v18.14.0

asyncLiz commented 8 months ago

Hm, I believe we use the value in CSS calc()s, where a unit is required. This may just need to be documented as a caveat that units are required.

shadow-identity commented 8 months ago

AFAIK calc() does not require a unit. We even used it to convert --md- opacity variables (which are unit-less numbers between 0 and 1) into percentage values to use later in color-mix(), because color-mix accepts only percents. We was doing it like this:

--md-filled-icon-button-container-color: color-mix(
                    in srgb,
                    var(--md-sys-color-secondary-container),
                    transparent calc(var(--md-sys-state-hover-state-layer-opacity) * 100%)
                );

where --md-sys-state-hover-state-layer-opacity: 0.07999999821186066; is defined somewhere in material definitions.

md5login commented 8 months ago

AFAIK calc() does not require a unit. We even used it to convert --md- opacity variables (which are unit-less numbers between 0 and 1) into percentage values to use later in color-mix(), because color-mix accepts only percents. We was doing it like this:

--md-filled-icon-button-container-color: color-mix(
                    in srgb,
                    var(--md-sys-color-secondary-container),
                    transparent calc(var(--md-sys-state-hover-state-layer-opacity) * 100%)
                );

where --md-sys-state-hover-state-layer-opacity: 0.07999999821186066; is defined somewhere in material definitions.

calc() doesn't require a unit per spec. Units are required by border-radius, which the calc result goes to. Hence, if units are not provided, the calculated result will be unitless, which is incompatible with the border-radius property.

shadow-identity commented 8 months ago

Defining css custom properties with @property may provide hints to the editor, like

@property --md-filled-icon-button-container-color {
    syntax: "<length>";
    ...
}

But I'm not sure if it will work with external library.