«کد بدون خطا کامپایل میشود و در مرورگر محلی با دادههای نمونه، آمادهی ارسال به دست کاربر به نظر میرسد.» این وعدهی فریبندهی تولید یک کامپوننت داشبورد پیچیده در عرض چند ثانیه با استفاده از Cursor، Claude یا GitHub Copilot است. شما از مدل میخواهید یک مودال یا یک کارت داشبورد بسازد و مدل در دو ثانیه، پنجاه خط کد تمیز TypeScript و کلاسهای Tailwind را بیرون میریزد. با این حال، این کد اغلب به محض رسیدن به محیط Staging یا نمایش در یک صفحهی موبایل، شکست میخورد. پس از استقرار، باگهای ظریف UI ظاهر میشوند: متنها در صفحههای کوچکتر بریده میشوند، نامهای کاربری طولانی از کانتینرهای خود بیرون میزنند و چیدمان صفحه هنگام بارگذاری دچار پرش میشود. در حالی که مدلهای هوش مصنوعی در سینتکس (Syntax) عالی هستند، آنها بهطور مداوم الگوهای تدافعی CSS را نادیده میگیرند که منجر به شکست در دسترسپذیری (Accessibility) و جابهجاییهای آزاردهنده در چیدمان میشود.
این شکاف در توانایی مدلها، نکتهی حیاتیای را تقویت میکند که در پوششهای قبلی خود بررسی کردیم: دستیارهای کدنویسی هوش مصنوعی نمیتوانند جایگزین اصول بنیادین مهندسی نرمافزار شوند. تکیه بر یک مدل برای مدیریت بخش «بصری» بدون نظارت دستی، اغلب باعث ایجاد بدهی فنی (Technical Debt) میشود که تنها در مواجهه با دادههای لبهای (Edge-case) کاربران نمایان میگردد.
دکمهای را تصور کنید که در لحظهی کلیک کاربر روی «ذخیره»، کل چیدمان صفحه را منقبض کرده و جابهجا میکند، زیرا اسپینر بارگذاری (Loading Spinner) باریکتر از متن دکمه است. این یک مثال کلاسیک از کدهای «تمیز به نظر رسانندهی» هوش مصنوعی است که در محیط عملیاتی، تجربهی کاربری (UX) بسیار ضعیفی ایجاد میکند.
تلهی جابهجایی چیدمان (Layout Shift)
دستیارهای هوش مصنوعی معمولاً در حالتهای بارگذاری، متن دکمه را با یک اسپینر جایگزین میکنند. یک پیادهسازی معمولی توسط AI از یک عملگر Ternary برای جایگزینی متن با یک <Spinner className="w-4 h-4" /> استفاده میکند. از آنجایی که یک اسپینر ۱۶ پیکسلی بهطور قابلتوجهی باریکتر از عبارتی مانند «Save Changes» است، عرض دکمه بلافاصله پس از کلیک جمع میشود. این اتفاق باعث ایجاد Cumulative Layout Shift (CLS) میشود که ورودیها و دکمههای مجاور را در سراسر صفحه جابهجا میکند.
برای رفع این مشکل، توسعهدهندگان باید برچسب اصلی را در DOM نگه دارند اما هنگام بارگذاری آن را به صورت invisible علامتگذاری کنند. با قرار دادن اسپینر در یک لایه مطلق با استفاده از absolute inset-0 flex items-center justify-center، عرض دکمه بدون توجه به وضعیت بارگذاری، قفل شده و ثابت میماند.
فلکسباکس و سرریز متن (Text Overflow)
ابزارهای هوش مصنوعی مکرراً از Flexbox بدون تعریف محدودیتهای عرض تدافعی استفاده میکنند. وقتی کاربری نامی غیرمعمول و طولانی دارد یا فایلی با عنوانی ۵۰ کاراکتری آپلود میکند، چیدمان میشکند.
- خطای هوش مصنوعی: AI اغلب کلاس
truncateرا به یک span داخل یک کانتینر flex اضافه میکند، اما این کار هیچ اثری ندارد زیرا فرزندان flex بهطور پیشفرض دارایmin-width: autoهستند. - نتیجه: اگر کانتینر تحت فشار قرار گیرد، متن اجازه کوچک شدن نمیدهد و المان والد را به بیرون از Viewport هل میدهد.
- راهکار عملیاتی: توسعهدهندگان باید کلاس
min-w-0را به فرزند flex که متن را نگه داشته است اضافه کنند. این کلاس کاربردی صراحتاً به مرورگر میگوید که فرزند flex اجازه دارد کمتر از عرض محتوای خود منقبض شود و بدین ترتیب، قطع شدن متن (Truncation) همانطور که انتظار میرود عمل میکند.

باگ تولتیپ در دکمههای غیرفعال
وقتی یک عملیات مسدود شده است — برای مثال، زمانی که کاربر برای حذف یک پروژه به مجوزهای ادمین نیاز دارد — شما میخواهید یک تولتیپ (Tooltip) نمایش داده شود که دلیل این اتفاق را توضیح دهد. مدلهای هوش مصنوعی تقریباً همیشه ویژگی نیتیو HTML یعنی disabled را مستقیماً روی دکمه اعمال میکنند.
با این حال، مرورگرها تمام رویدادهای موس (Mouse Events) را روی المانهایی که ویژگی disabled دارند، متوقف میکنند. در نتیجه، Hover کردن روی دکمه باعث تحریک mouseEnter نمیشود و تولتیپ هرگز رندر نمیشود. کاربران با دکمهای مرده مواجه میشوند و هیچ ایدهای ندارند که چرا دکمه غیرفعال است.
به جای disabled، توسعهدهندگان باید از aria-disabled استفاده کنند. با مدیریت دستی استایلهای تعاملی (با استفاده از کلاسهایی مانند opacity-50 cursor-not-allowed pointer-events-auto) و جلوگیری از رویداد کلیک در جاوااسکریپت از طریق e.preventDefault()، دکمه برای صفحهخوانها (Screen Readers) در دسترس باقی میماند و اجازه میدهد تولتیپها بهطور طبیعی عمل کنند.
ارتفاعهای سختافزاری Viewport
مودالها، دراورها (Drawers) و پنلهای تنظیمات تولید شده توسط AI اغلب از ارتفاعهای پیکسلی ثابت استفاده میکنند، مانند h-[600px] و w-[500px]. در حالی که این مقادیر در یک مانیتور دسکتاپ درست به نظر میرسند، اما در صفحههای کوچکتر موبایل یا لپتاپهایی که نوار ابزار مرورگر در آنها باز است، باعث بریده شدن فوتر میشوند. این موضوع اغلب باعث میشود کاربران نتوانند دکمه Submit را ببینند یا روی آن ضربه بزنند، زیرا فوتر مودال به بیرون از لبهی پایین صفحه رانده شده است.
کد آماده برای محیط عملیاتی باید از واحدهای پویای Viewport و نواحی اسکرول داخلی استفاده کند:
- کانتینر: استفاده از
max-h-[90dvh]وw-full max-w-lgبرای اطمینان از اینکه مودال در تمام صفحهها جای میگیرد. - ساختار: پیادهسازی یک چیدمان flex-column که در آن هدر و فوتر دارای پدینگ و حاشیههای ثابت باشند.
- بدنه: تنظیم
ModalBodyرویoverflow-y-auto flex-1. این کار تضمین میکند که هدر و فوتر در معرض دید باقی بمانند، در حالی که محتوای طولانی فرم بهطور تمیزی در داخل بدنه اسکرول میشود.
وضعیتهای منقضی (Stale State) در مودالها
هنگام ایجاد مودالهای ویرایش، ابزارهای AI اغلب ورودیهای فرم را در وضعیت کامپوننت (با استفاده از useState) ذخیره میکنند، بدون اینکه هنگام تغییر موجودیت هدف (Target Entity)، آنها را ریست کنند.
به عنوان مثال، اگر کاربر «Alice» را ویرایش کند، مودال را ببندد و سپس روی ویرایش «Bob» کلیک کند، ممکن است ورودیها همچنان نام «Alice» را نشان دهند. این اتفاق به این دلیل میافتد که وضعیت (State) در اولین Mount مقداردهی اولیه شده و هرگز برای شیء کاربر جدید رفرش نشده است.
به جای کلنجار رفتن با هوکهای پیچیدهی useEffect برای ریست کردن در داخل کامپوننت فرزند، بهینهترین راه این است که نمونهی مودال را در محل فراخوانی با استفاده از ID موجودیت کلیدگذاری (Key) کنید (مثلاً <EditUserModal key={activeUser.id} ... />). این کار باعث میشود React هر بار که کاربر فعال تغییر میکند، کامپوننت را کاملاً تخریب کرده و دوباره با وضعیتی تازه (Fresh State) مونت کند.
این خطاهای تکراری نشان میدهند که هوش مصنوعی در حال حاضر یک «موتور سینتکس» است تا یک «معمار سیستم». AI میتواند کدی بنویسد تا یک کامپوننت وجود داشته باشد، اما نوسانات محیطی وب باز (Open Web) را درک نمیکند.
برای توسعهدهندگان، این بدان معناست که نقش بازبین کد (Code Reviewer) تغییر کرده است. شما دیگر فقط به دنبال خطاهای منطقی نیستید؛ بلکه در حال حسابرسی «CSS تدافعی» هستید — همان نردههای ایمنی نامرئی که مانع از شکست UI تحت استرسهای دنیای واقعی میشود.
برای متوقف کردن اصلاح دستی این باگهای تکراری، توسعهدهندگان میتوانند قوانین سختگیرانهی CSS را در فایلهای .cursorrules یا AGENTS.md تعریف کنند تا مدل را از الگوهای شکننده دور کنند. متناوباً، استفاده از کتابخانهای از Primitivesهای UI پیشتایید شده و دسترسپذیر — مانند مجموعهی متنباز برای React 19 و Next.js 16 در devpreflight.com — میتواند این ریسکها را بهطور کامل حذف کند.
توسعهدهندگان باید کامپوننتهای فعلی تولید شده توسط AI خود را برای الگوهای min-w-0 و aria-disabled بازبینی کنند تا از شکستهای خاموش در محیط عملیاتی جلوگیری نمایند.




گفتگو