cssvue.jsvuejs3bootstrap-5primevue

PrimeVue InputNumber's width exceeds the width of its parent


I have a list of items in the cart that's presented in Bootstrap rows and cols. Each item has a PrimeVue InputNumber for changing the quantity of a specific product in the cart.

Here's a StackBlitz project with this issue.

This is how I use InputNumber:

<InputNumber v-model="item.qty"
             inputId="horizontal-buttons"
             showButtons
             buttonLayout="horizontal"
             :step="1"
             style="max-width: 100%; box-sizing: border-box;">
<template #incrementbuttonicon>
  <span class="material-symbols-sharp">
    add
  </span>
</template>
<template #decrementbuttonicon>
  <span class="material-symbols-sharp">
    remove
  </span>
</template>
</InputNumber>

Here's the component with the list I've mentioned above:

<script setup>
import InputNumber from 'primevue/inputnumber'
import { useCartStore } from '../stores/cartStore.js'
import { storeToRefs } from 'pinia'

const cartStore = useCartStore()
const { cart } = storeToRefs(cartStore)
const { deleteFromCart } = cartStore
</script>

<template>
  <div class="row mw-2000 mx-auto px-lg-5 px-0 my-0">
    <section class="col-9">
      <div class="container-fluid">
        <div class="row border-top border-bottom cart-item"
             v-for="item in cart">
          <img class="col-2" :src="item.product.images[0]" alt="Product">
          <div class="col-6 d-inline-block overflow-ellipsis">
            {{ item.product.title }}
          </div>
          <div class="col-1 d-inline-block overflow-ellipsis">
            ${{ parseFloat(item.product.price).toFixed(2) }}
          </div>
          <div class="col-2">
            <InputNumber v-model="item.qty"
                         inputId="horizontal-buttons"
                         showButtons
                         buttonLayout="horizontal"
                         :step="1" style="max-width: 100%; box-sizing: border-box;">
              <template #incrementbuttonicon>
                <span class="material-symbols-sharp">
                  add
                </span>
              </template>
              <template #decrementbuttonicon>
                <span class="material-symbols-sharp">
                  remove
                </span>
              </template>
            </InputNumber>
          </div>
          <div class="col-1 d-flex justify-content-end">
            <button type="button"
                    class="btn btn-danger delete-product-btn d-inline-flex
                    justify-content-center align-items-center"
                    @click="deleteFromCart(item.product.id)">
              <span class="material-symbols-sharp">
                close
              </span>
            </button>
          </div>
        </div>
      </div>
    </section>
    <section class="col-3"></section>
  </div>
</template>

As you see, I tried applying style="max-width: 100%; box-sizing: border-box;" to the InputNumber component, but it didn't work. I also tried replacing max-width: 100% with width: 100%, but it also didn't work. Right now, the input looks like this:

enter image description here

I tried to inspect the component, but couldn't find any reason why it behaves like this. I haven't seen the InputNumber being set a fixed width or something similar anywhere.

enter image description here

enter image description here

To be clear, I want the InputNumber to fit its parent's width.

Thank you in advance!


Solution

  • It looks like the issue is fixed by applying 1, 2:

    .p-inputnumber input {
      width: 100%;
    }
    

    but I'm not sure I understand the DOM mechanics behind it.

    My best guess is that the width is silently imposed by the user agent (the browser) which, according to the HTML standard, "should ensure that at least 20 characters are visible". This is confirmed by the input shrinking when given a size attribute value smaller than 20 (default value).

    I inspected all CSS applied to span.p-inputnumber, its inner input, its inner buttons and the input's inner shadow DOM and nothing else explains why they would exceed the parent width.

    Also, the behavior does not seem to be caused by conflicting CSS rules between primevue and bootstrap. (Not saying using them together is advisable, but I seriously doubt it is the underlying cause of the unwanted CSS behavior).


    1 - if you want this behavior only on some inputs, apply the fix selectively, using a dedicated class.

    2 - giving the input a CSS overflow value of auto, hidden, overlay or scroll seems to have the same effect as the proposed fix (only tested in Chrome).

    3 - If I were you, I'd open an issue on primevue's repo letting them know about the behavior, it's likely something they want to fix. Most developers would expect the input not to exceed the parent width out of the box, without having to apply any CSS.