Tenho um problema com uma entrada explodindo fora dos limites pretendidos. O problema se parece com o seguinte:
A parte relevante do HTML bruto se parece com o seguinte (primeiro junto com o CSS completo):
<td class="relative whitespace-nowrap pl-3 first:pl-4 sm:first:pl-6 pr-3 last:pr-4 sm:last:pr-6 text-main-900 dark:text-main-50 text-left border-b border-main-200 dark:border-main-800 py-2.5">
<div class="max-w-20">
<div class="flex flex-row">
<div data-slot="control" class="flex flex-row grow shadow mr-1">
<div class="min-w-8 flex flex-row justify-center items-center border-l border-t border-b text-xs text-main-text bg-main-static-bg border-main-border/20 dark:text-main-text-dark dark:bg-main-static-bg-dark dark:border-main-border-dark/10 rounded-l-lg">
<span data-slot="control" class="group inline-flex focus:outline-none" id="headlessui-checkbox-:r9v:" role="checkbox" aria-checked="false" tabindex="0" data-headlessui-state="">
<span class="relative isolate flex size-[1.125rem] items-center justify-center rounded-[0.3125rem] sm:size-4 before:absolute before:inset-0 before:-z-10 before:rounded-[calc(0.3125rem-1px)] before:bg-white before:shadow before:group-data-[checked]:bg-[--checkbox-checked-bg] dark:before:hidden dark:bg-white/5 dark:group-data-[checked]:bg-[--checkbox-checked-bg] border border-zinc-950/15 group-data-[checked]:border-transparent group-data-[checked]:group-data-[hover]:border-transparent group-data-[hover]:border-zinc-950/30 group-data-[checked]:bg-[--checkbox-checked-border] dark:border-white/15 dark:group-data-[checked]:border-white/5 dark:group-data-[checked]:group-data-[hover]:border-white/5 dark:group-data-[hover]:border-white/30 after:absolute after:inset-0 after:rounded-[calc(0.3125rem-1px)] after:shadow-[inset_0_1px_theme(colors.white/15%)] dark:after:-inset-px dark:after:hidden dark:after:rounded-[0.3125rem] dark:group-data-[checked]:after:block group-data-[focus]:outline group-data-[focus]:outline-2 group-data-[focus]:outline-offset-2 group-data-[focus]:outline-blue-500 group-data-[disabled]:opacity-50 group-data-[disabled]:border-zinc-950/25 group-data-[disabled]:bg-zinc-950/5 group-data-[disabled]:[--checkbox-check:theme(colors.zinc.950/50%)] group-data-[disabled]:before:bg-transparent dark:group-data-[disabled]:border-white/20 dark:group-data-[disabled]:bg-white/[2.5%] dark:group-data-[disabled]:[--checkbox-check:theme(colors.white/50%)] dark:group-data-[disabled]:group-data-[checked]:after:hidden forced-colors:[--checkbox-check:HighlightText] forced-colors:[--checkbox-checked-bg:Highlight] forced-colors:group-data-[disabled]:[--checkbox-check:Highlight] dark:forced-colors:[--checkbox-check:HighlightText] dark:forced-colors:[--checkbox-checked-bg:Highlight] dark:forced-colors:group-data-[disabled]:[--checkbox-check:Highlight] [--checkbox-check:theme(colors.white)] [--checkbox-checked-bg:theme(colors.zinc.900)] [--checkbox-checked-border:theme(colors.zinc.950/90%)] dark:[--checkbox-checked-bg:theme(colors.zinc.600)]">
<svg class="size-4 stroke-[--checkbox-check] opacity-0 group-data-[checked]:opacity-100 sm:h-3.5 sm:w-3.5" viewBox="0 0 14 14" fill="none">
(...)
</svg>
</span>
</span>
</div>
<input class="relative block grow appearance-none px-[calc(theme(spacing[3.5])-1px)] py-[calc(theme(spacing[2.5])-1px)] sm:px-[calc(theme(spacing[3])-1px)] sm:py-[calc(theme(spacing[1.5])-1px)] text-base/6 text-main-text placeholder:text-main-text/50 dark:placeholder:text-main-text-dark/30 sm:text-sm/6 dark:text-main-text-dark border border-main-border/20 data-[hover]:border-main-border-hover/30 dark:border-main-border-dark/10 dark:data-[hover]:border-main-border-dark-hover/20 bg-white dark:bg-white/5 focus:outline-none focus:border-b-2 focus:border-b-primary-500 focus:hover:border-b-primary-500 focus:pb-[calc(theme(spacing[2.5])-2px)] sm:focus:pb-[calc(theme(spacing[1.5])-2px)] data-[invalid]:border-danger-500 data-[invalid]:data-[hover]:border-danger-500 data-[invalid]:dark:border-danger-500 data-[invalid]:data-[hover]:dark:border-danger-500 data-[invalid]:focus:border-b-primary-500 data-[invalid]:data-[hover]:focus:border-b-primary-500 data-[disabled]:opacity-50 data-[disabled]:border-main-border/20 dark:data-[hover]:data-[disabled]:border-white/15 dark:data-[disabled]:border-main-border-dark/15 dark:data-[disabled]:bg-main-50/[2.5%] dark:[color-scheme:dark] rounded-l-none rounded-r-lg" id="headlessui-input-:ra1:" data-headlessui-state="" value="">
</div>
<button class="relative isolate inline-flex items-center justify-center gap-x-2 rounded-lg border text-base/6 font-semibold px-[calc(theme(spacing[3.5])-1px)] py-[calc(theme(spacing[2.5])-1px)] sm:px-[calc(theme(spacing.3)-1px)] sm:py-[calc(theme(spacing[1.5])-1px)] sm:text-sm/6 focus:outline-none data-[focus]:outline data-[focus]:outline-2 data-[focus]:outline-offset-2 data-[focus]:outline-primary-500 data-[disabled]:opacity-50 [&>[data-slot=icon]]:-mx-0.5 [&>[data-slot=icon]]:my-0.5 [&>[data-slot=icon]]:size-5 [&>[data-slot=icon]]:shrink-0 [&>[data-slot=icon]]:text-[--btn-icon] [&>[data-slot=icon]]:sm:my-1 [&>[data-slot=icon]]:sm:size-4 forced-colors:[--btn-icon:ButtonText] forced-colors:data-[hover]:[--btn-icon:ButtonText] border-transparent text-main-900 data-[hover]:data-[active]:bg-main-700/[10%] data-[hover]:bg-main-700/[2.5%] dark:text-main-50 dark:data-[hover]:dark:data-[active]:bg-main-300/40 dark:data-[hover]:bg-main-300/10 data-[hover]:data-[active]:[--btn-icon:theme(colors.main.400)] data-[hover]:[--btn-icon:theme(colors.main.700)] dark:data-[active]:[--btn-icon:theme(colors.main.400)] dark:data-[hover]:[--btn-icon:theme(colors.main.400)] [--btn-icon:theme(colors.main.500)] cursor-default" type="button" data-headlessui-state="">
<span class="-translate-x-1/2 -translate-y-1/2 absolute left-1/2 top-1/2 size-[max(100%,2.75rem)] [@media(pointer:fine)]:hidden" aria-hidden="true">
</span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" data-slot="icon">
(...)
</svg>
</button>
</div>
</div>
</td>
Estou usando o CSS do Tailwind, então esse é praticamente todo o CSS. Não há estilos adicionais usados além dos acima.
Abaixo o mesmo código reduzido apenas às classes que influenciam os tamanhos:
<td class="relative whitespace-nowrap pl-3 first:pl-4 sm:first:pl-6 pr-3 last:pr-4 sm:last:pr-6 py-2.5">
<div class="max-w-20"> <!-- Split from the below for testing purposes -->
<div class="flex flex-row"> <!-- Contents of the cell: input and button -->
<div class="flex flex-row grow mr-1"> <!-- Host div for the input -->
<div class="min-w-8 flex flex-row justify-center items-center"> <!-- Area with checkbox -->
<span class="group inline-flex"> <!-- Checkbox -->
<span class="relative isolate flex size-[1.125rem] items-center justify-center sm:size-4">
<svg class="size-4 sm:h-3.5 sm:w-3.5" viewBox="0 0 14 14" fill="none">
(...)
</svg>
</span>
</span>
</div>
<!-- Input part of the high-level input -->
<input class="relative block grow appearance-none px-[calc(theme(spacing[3.5])-1px)] py-[calc(theme(spacing[2.5])-1px)] sm:px-[calc(theme(spacing[3])-1px)] sm:py-[calc(theme(spacing[1.5])-1px)] focus:pb-[calc(theme(spacing[2.5])-2px)] sm:focus:pb-[calc(theme(spacing[1.5])-2px)]">
</div>
<!-- The last button in the cell -->
<button class="relative isolate inline-flex items-center justify-center gap-x-2 px-[calc(theme(spacing[3.5])-1px)] py-[calc(theme(spacing[2.5])-1px)] sm:px-[calc(theme(spacing.3)-1px)] sm:py-[calc(theme(spacing[1.5])-1px)] [&>[data-slot=icon]]:-mx-0.5 [&>[data-slot=icon]]:my-0.5 [&>[data-slot=icon]]:size-5 [&>[data-slot=icon]]:sm:my-1 [&>[data-slot=icon]]:sm:size-4">
<span class="-translate-x-1/2 -translate-y-1/2 absolute left-1/2 top-1/2 size-[max(100%,2.75rem)] [@media(pointer:fine)]:hidden" aria-hidden="true">
</span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" data-slot="icon">
(...)
</svg>
</button>
</div>
</div>
</td>
E um exemplo reproduzível: nada é mostrado devido à falta de classes de cores, mas você pode inspecionar o layout e ver a entrada transbordando.
<html>
<head>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<table>
<tbody>
<tr>
<td class="relative whitespace-nowrap pl-3 first:pl-4 sm:first:pl-6 pr-3 last:pr-4 sm:last:pr-6 py-2.5">
<div class="max-w-20">
<div class="flex flex-row">
<div class="flex flex-row mr-1">
<div class="min-w-8 flex flex-row justify-center items-center">
<span class="group inline-flex">
<span class="relative isolate flex size-[1.125rem] items-center justify-center sm:size-4">
<svg class="size-4 sm:h-3.5 sm:w-3.5" viewBox="0 0 14 14" fill="none">
(...)
</svg>
</span>
</span>
</div>
<input class="relative block grow appearance-none px-[calc(theme(spacing[3.5])-1px)] py-[calc(theme(spacing[2.5])-1px)] sm:px-[calc(theme(spacing[3])-1px)] sm:py-[calc(theme(spacing[1.5])-1px)] focus:pb-[calc(theme(spacing[2.5])-2px)] sm:focus:pb-[calc(theme(spacing[1.5])-2px)]">
</div>
<button class="relative isolate inline-flex items-center justify-center gap-x-2 px-[calc(theme(spacing[3.5])-1px)] py-[calc(theme(spacing[2.5])-1px)] sm:px-[calc(theme(spacing.3)-1px)] sm:py-[calc(theme(spacing[1.5])-1px)] [&>[data-slot=icon]]:-mx-0.5 [&>[data-slot=icon]]:my-0.5 [&>[data-slot=icon]]:size-5 [&>[data-slot=icon]]:sm:my-1 [&>[data-slot=icon]]:sm:size-4">
<span class="-translate-x-1/2 -translate-y-1/2 absolute left-1/2 top-1/2 size-[max(100%,2.75rem)] [@media(pointer:fine)]:hidden" aria-hidden="true">
</span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" data-slot="icon">
(...)
</svg>
</button>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
O w-20
é adicionado para fins de depuração - era para encolher à força o elemento de entrada, mas não o fez. O Chrome mostra informações para o div "w-20":
De qualquer forma, a largura da entrada parece não estar vinculada ao CSS - ela precisa ser derivada dos contêineres pais:
Indo para fora, largura do pai da entrada (div do host de entrada):
Largura da div de conteúdo da célula:
Também foi mostrado, a propósito, que seu conteúdo excede seu tamanho:
Meu requisito para a entrada é que ela seja reduzida ao tamanho do div host, para que eu possa controlar a largura de todo o componente de entrada (junto com a caixa de prefixo e a caixa de posfixo, que não são usadas neste caso).
Minhas perguntas: Por que input não encolhe, mas em vez disso transborda seu contêiner? O que realmente influencia a largura do input?
A largura mínima de um item flexbox é definida como
min-content
. Portanto, o<input>
não encolherá abaixo de seu tamanho intrínseco.Aqui está um exemplo simplificado:
Alterar o
<input>
'smin-width
para0
permite que ele encolha para caber:Atualizando seu exemplo:
min-w-0
à<div class="flex flex-row mr-1">
min-w-0
à<input ...>