Reputation: 2929
I'm working on a chatbot (as a newbie) and work on UI (using Tailwindcss
).
For a reason I understand (different behaviors), I do not know how to handle it.
Any clue? Thanks.
On desktop textarea
is 1 row (perfect!)
But on mobile (iOS), it looks like this ("two" lines):
My code is:
<body>
<footer
class="fixed bottom-0 left-1/2 w-full max-w-4xl -translate-x-1/2 transform bg-white shadow-[0_0_40px_40px_rgba(255,255,255,1)]"
>
<div
class="mx-6 mb-6 flex h-fit flex-none items-center justify-between gap-x-2 rounded-lg border border-gray-200 bg-white py-3 pr-2 pl-4 shadow-sm"
>
<textarea
class="min-h-[24px] max-h-[240px] field-sizing-content flex-1 resize-none border-none text-base outline-0 placeholder:text-gray-400"
id="prompt__input"
type="text"
name="message"
placeholder="Comment puis-je vous aider ?"
></textarea>
<button
class="h-8 cursor-pointer px-3 text-xl font-black hover:rounded-lg hover:bg-gray-100 disabled:cursor-progress disabled:border-stone-200 disabled:text-stone-400"
id="prompt__submit"
type="button"
>
<svg
class="fill-gray-600"
aria-hidden="true"
focusable="false"
viewBox="0 0 16 16"
width="22"
height="22"
>
<path
d="M.989 8 .064 2.68a1.342 1.342 0 0 1 1.85-1.462l13.402 5.744a1.13 1.13 0 0 1 0 2.076L1.913 14.782a1.343 1.343 0 0 1-1.85-1.463L.99 8Zm.603-5.288L2.38 7.25h4.87a.75.75 0 0 1 0 1.5H2.38l-.788 4.538L13.929 8Z"
></path>
</svg>
</button>
</div>
</footer>
</body>
Upvotes: 1
Views: 29
Reputation: 9580
field-sizing
field-sizing
- MDN DocsIt is not available on either Firefox or Safari, so you need to look for an alternative solution.
field-sizing
utilities are not available in v3Note: The field-sizing
utilities was introduced in TailwindCSS v4. If you still want to use it with v3, you'll need to create your own custom class. (See more: PR #14469)
.field-sizing-content {
field-sizing: content;
}
.field-sizing-fixed {
field-sizing: fixed;
}
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addUtilities }) {
addUtilities({
'.field-sizing-content' {
'field-sizing': 'content';
},
'.field-sizing-fixed': {
'field-sizing': 'fixed',
},
})
})
]
}
Actually, I just inserted the original field-sizing solution and my new solution so that the results can be compared.
For the alternative solution, I set up a function on the textarea's input event that automatically adjusts the textarea's height
to its scrollHeight
, ensuring that the text will always be fully visible, with the max-h-[240px]
acting as the constraint.
To ensure it works properly, the rows="1"
setting is required to start with a single row by default, and an auto
height setting is needed so that the scrollHeight
actually starts decreasing when the content is deleted.
document.addEventListener("DOMContentLoaded", function () {
const textarea = document.getElementById("prompt__input__alternative");
// Update height to scrollHeight
function updateHeight() {
textarea.style.height = `auto`; /* for can reset height */
textarea.style.height = `${textarea.scrollHeight}px`;
}
textarea.addEventListener("input", updateHeight);
updateHeight();
});
<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<footer
class="fixed bottom-0 left-1/2 w-full max-w-4xl -translate-x-1/2 transform bg-white shadow-[0_0_40px_40px_rgba(255,255,255,1)]"
>
<p>Original with field-sizing-content</p>
<div
class="mx-6 mb-6 flex h-fit flex-none items-center justify-between gap-x-2 rounded-lg border border-gray-200 bg-white py-3 pr-2 pl-4 shadow-sm"
>
<textarea
class="min-h-[24px] max-h-[240px] field-sizing-content flex-1 resize-none border-none text-base outline-0 placeholder:text-gray-400"
id="prompt__input"
type="text"
name="message"
placeholder="Comment puis-je vous aider ?"
></textarea>
<button
class="h-8 cursor-pointer px-3 text-xl font-black hover:rounded-lg hover:bg-gray-100 disabled:cursor-progress disabled:border-stone-200 disabled:text-stone-400"
id="prompt__submit"
type="button"
>
<svg
class="fill-gray-600"
aria-hidden="true"
focusable="false"
viewBox="0 0 16 16"
width="22"
height="22"
>
<path
d="M.989 8 .064 2.68a1.342 1.342 0 0 1 1.85-1.462l13.402 5.744a1.13 1.13 0 0 1 0 2.076L1.913 14.782a1.343 1.343 0 0 1-1.85-1.463L.99 8Zm.603-5.288L2.38 7.25h4.87a.75.75 0 0 1 0 1.5H2.38l-.788 4.538L13.929 8Z"
></path>
</svg>
</button>
</div>
<p>Alternative with JavaScript</p>
<div
class="mx-6 mb-6 flex h-fit flex-none items-center justify-between gap-x-2 rounded-lg border border-gray-200 bg-white py-3 pr-2 pl-4 shadow-sm"
>
<textarea
class="w-full min-h-[24px] max-h-[240px] h-auto resize-none border-none text-base outline-0 placeholder:text-gray-400"
id="prompt__input__alternative"
type="text"
name="message"
placeholder="Comment puis-je vous aider ?"
rows="1"
></textarea>
<button
class="h-8 cursor-pointer px-3 text-xl font-black hover:rounded-lg hover:bg-gray-100 disabled:cursor-progress disabled:border-stone-200 disabled:text-stone-400"
id="prompt__submit"
type="button"
>
<svg
class="fill-gray-600"
aria-hidden="true"
focusable="false"
viewBox="0 0 16 16"
width="22"
height="22"
>
<path
d="M.989 8 .064 2.68a1.342 1.342 0 0 1 1.85-1.462l13.402 5.744a1.13 1.13 0 0 1 0 2.076L1.913 14.782a1.343 1.343 0 0 1-1.85-1.463L.99 8Zm.603-5.288L2.38 7.25h4.87a.75.75 0 0 1 0 1.5H2.38l-.788 4.538L13.929 8Z"
></path>
</svg>
</button>
</div>
</footer>
contenteditable
elementActually, I just inserted the original field-sizing solution and my new solution so that the results can be compared.
The alternative solution works here even without JavaScript. The JavaScript is needed to hide and show the placeholder, and for that, I had to listen for the input event on the contenteditable
div.
document.addEventListener("DOMContentLoaded", function () {
const contentEditableDiv = document.getElementById("prompt__input__alternative");
const placeholderSpan = document.getElementById("primpt__input__alternative__placeholder");
// Hide placeholder when input length > 0
function togglePlaceholder() {
if (contentEditableDiv.textContent.trim().length > 0) {
placeholderSpan.style.display = "none";
} else {
placeholderSpan.style.display = "inline";
}
}
contentEditableDiv.addEventListener("input", togglePlaceholder);
togglePlaceholder();
});
<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<footer
class="fixed bottom-0 left-1/2 w-full max-w-4xl -translate-x-1/2 transform bg-white shadow-[0_0_40px_40px_rgba(255,255,255,1)]"
>
<p>Original with field-sizing-content</p>
<div
class="mx-6 mb-6 flex h-fit flex-none items-center justify-between gap-x-2 rounded-lg border border-gray-200 bg-white py-3 pr-2 pl-4 shadow-sm"
>
<textarea
class="min-h-[24px] max-h-[240px] field-sizing-content flex-1 resize-none border-none text-base outline-0 placeholder:text-gray-400"
id="prompt__input"
type="text"
name="message"
placeholder="Comment puis-je vous aider ?"
></textarea>
<button
class="h-8 cursor-pointer px-3 text-xl font-black hover:rounded-lg hover:bg-gray-100 disabled:cursor-progress disabled:border-stone-200 disabled:text-stone-400"
id="prompt__submit"
type="button"
>
<svg
class="fill-gray-600"
aria-hidden="true"
focusable="false"
viewBox="0 0 16 16"
width="22"
height="22"
>
<path
d="M.989 8 .064 2.68a1.342 1.342 0 0 1 1.85-1.462l13.402 5.744a1.13 1.13 0 0 1 0 2.076L1.913 14.782a1.343 1.343 0 0 1-1.85-1.463L.99 8Zm.603-5.288L2.38 7.25h4.87a.75.75 0 0 1 0 1.5H2.38l-.788 4.538L13.929 8Z"
></path>
</svg>
</button>
</div>
<p>Alternative with contenteditable</p>
<div
class="mx-6 mb-6 flex h-fit flex-none items-center justify-between gap-x-2 rounded-lg border border-gray-200 bg-white py-3 pr-2 pl-4 shadow-sm"
>
<div class="relative w-full min-h-[24px] max-h-[240px] overflow-auto">
<span id="primpt__input__alternative__placeholder" class="w-full text-gray-400 absolute top-0 left-0 z-0">
Comment puis-je vous aider ?
</span>
<div
contenteditable="true"
class="relative z-10 w-full min-h-[24px] max-h-[240px] border-none text-base outline-0"
id="prompt__input__alternative"
></div>
</div>
<button
class="h-8 cursor-pointer px-3 text-xl font-black hover:rounded-lg hover:bg-gray-100 disabled:cursor-progress disabled:border-stone-200 disabled:text-stone-400"
id="prompt__submit"
type="button"
>
<svg
class="fill-gray-600"
aria-hidden="true"
focusable="false"
viewBox="0 0 16 16"
width="22"
height="22"
>
<path
d="M.989 8 .064 2.68a1.342 1.342 0 0 1 1.85-1.462l13.402 5.744a1.13 1.13 0 0 1 0 2.076L1.913 14.782a1.343 1.343 0 0 1-1.85-1.463L.99 8Zm.603-5.288L2.38 7.25h4.87a.75.75 0 0 1 0 1.5H2.38l-.788 4.538L13.929 8Z"
></path>
</svg>
</button>
</div>
</footer>
Upvotes: 1