ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
51.02k stars 13.52k forks source link

bug(input, select): changing font size with label-placement="floating" causes incorrect label position #27194

Open EinfachHans opened 1 year ago

EinfachHans commented 1 year ago

Prerequisites

Ionic Framework Version

v7.x

Current Behavior

The floating label placement of an outlined <ion-select> seems buggy in my applications so i debugged in and mentioned that the current implementation is not very consistent and for example breaks if you set for example a different font size.

Atm the label is placed by (select example):

:host(.select-label-placement-floating) .label-text-wrapper {
    transform: translateY(100%) scale(1);
}

what only works if the label (the label-text-wrapper element) has1/3 of the height of the select itself as far as i understand. This stops working if you set a different font size on a input/select.

Expected Behavior

The implementation should force the label to be always centered in the middle. For example:

:host(.select-label-placement-floating) .label-text-wrapper {
    top: 50%;
    transform: translateY(-50%) scale(1);
}

and then of course reset the top property on other states

Steps to Reproduce

Change the font size on a md outlined floating label select or input element

Code Reproduction URL

No response

Ionic Info

Let me know if required

Additional Information

No response

ionitron-bot[bot] commented 1 year ago

Thanks for the issue! This issue has been labeled as needs reproduction. This label is added to issues that need a code reproduction.

Please reproduce this issue in an Ionic starter application and provide a way for us to access it (GitHub repo, StackBlitz, etc). Without a reliable code reproduction, it is unlikely we will be able to resolve the issue, leading to it being closed.

If you have already provided a code snippet and are seeing this message, it is likely that the code snippet was not enough for our team to reproduce the issue.

For a guide on how to create a good reproduction, see our Contributing Guide.

EinfachHans commented 1 year ago

I created a minimal repo with two selects, one has a smaller font size: https://github.com/EinfachHans/ionic-label-bug

EinfachHans commented 1 year ago

And here is a stackblitz, guess that's quicker to check out: https://github-1mgkjv-ctghgu.stackblitz.io

averyjohnston commented 1 year ago

Thank you, I'm able to replicate this. While the label floats into the correct position when the input/select is focused, it sits vertically off-center otherwise.

muuvmuuv commented 1 year ago

I have kind of a similar issue our label also "moves" because once the ion-input is clicked it changes its inner HTML structure...

Before

SCR-20230822-myxn

After

SCR-20230822-myyf

thetaPC commented 1 year ago

I'm also experiencing this when using ion-select inside an item and outside.

If the ion-select is inside a list, then the label is completely gone. If it's not inside a list, then the label is shifted down.

Code Snippet:

<ion-list>
  <ion-item>
    <ion-select label="Floating label" label-placement="floating">
      <ion-select-option value="apple">Apple</ion-select-option>
      <ion-select-option value="banana">Banana</ion-select-option>
      <ion-select-option value="orange">Orange</ion-select-option>
    </ion-select>
  </ion-item>
</ion-list>
<ion-select label="Floating label" label-placement="floating">
  <ion-select-option value="apple">Apple</ion-select-option>
  <ion-select-option value="banana">Banana</ion-select-option>
  <ion-select-option value="orange">Orange</ion-select-option>
</ion-select>

Here's a screenshot: Simulator Screenshot - iPhone 14 Pro - 2023-09-26 at 11 52 28

maudvd commented 1 year ago

The same thing happens when you change the min-height property of the ion-input

sebowilli commented 12 months ago

Any updates here or plans of integrating this in one of the next releases? I really like the feature of having a floating label on the input but it stops me from applying any customization on the font. Changing font-size and/or font-family are both messing up the layout. As an example for font-family, I was trying to change it to Open Sans instead of the default font.

mapsandapps commented 11 months ago

It does seem like both Input and Select could be improved by using the suggestions up-thread, plus adjusting the transitions. However, this does not seem to solve the problem @thetaPC found. We'll need to do additional work to understand that issue.

To fix the original issue, we can add this to Input & Select, as in my draft PR: #28446:

When the stacked & floating .label-text-wrapper has focus or a value:

@include transform(translateY(-50%), scale(1));
top: 50%;
transition: color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1), top 150ms cubic-bezier(0.4, 0, 0.2, 1);

When the stacked & floating .label-text-wrapper is not focused and does not have a value:

top: 0;
WillxRv commented 5 months ago

Is there any way to resolve this before the fix? Thanks

maudvd commented 5 months ago

I use this css globally to fix this temporarily

.input-label-placement-floating.sc-ion-input-md-h
  .label-text-wrapper.sc-ion-input-md {
  transform: translateY(70%) scale(1);
}
.has-focus.input-label-placement-floating.sc-ion-input-md-h
  .label-text-wrapper.sc-ion-input-md {
  transform: translateY(30%) scale(0.75);
  font-weight: normal;
}
.has-value.input-label-placement-floating.sc-ion-input-md-h
  .label-text-wrapper.sc-ion-input-md {
  transform: translateY(30%) scale(0.75);
  font-weight: normal;
}

You can adjust the values to adapt to your font-size and/or font-family.

WillxRv commented 5 months ago

I temporarily fixed this problem in ion-select and ion-input with the code below. Thanks maudvd to give a direction

.select-fill-outline.select-label-placement-stacked::part(label), .select-fill-outline.select-label-placement-floating::part(label) { top: 50%; transform: translateY(-50%) scale(1); transition: color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1), top 150ms cubic-bezier(0.4, 0, 0.2, 1); } .label-floating.select-fill-outline::part(label) { top: 0 !important; transform: translateY(-32%) scale(0.75) !important; }

.input-fill-outline.input-label-placement-stacked .label-text-wrapper, .input-fill-outline.input-label-placement-floating .label-text-wrapper { top: 50%; transform: translateY(-50%) scale(1) !important; transition: color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1), top 150ms cubic-bezier(0.4, 0, 0.2, 1); }

.label-floating.input-fill-outline .label-text-wrapper { top: 0; transform: translateY(-32%) scale(0.75) !important; }