8.8 KiB
رفع بهمریختگی کامل پنل ادمین روی iPhone 8 (Safari/Chrome iOS)
پروژه
clinicpro (فقط CSS پنل ادمین React — بدون تغییر backend یا API)
زمینه
پنل ادمین (https://clinic-pro.ddev.site/admin) روی دسکتاپ و موبایلهای جدید درست است، اما روی iPhone 8 با هر دو مرورگر Chrome و Safari کامل بهمریخته دیده میشود (رنگها، پسزمینهها، دکمهها، بوردرها خراب).
نکته کلیدی: Chrome روی iOS هم از موتور WebKit استفاده میکند (نه Blink). پس «هر دو مرورگر خراب» یعنی مشکل از موتور WebKit قدیمیِ iPhone 8 است، نه مرورگر. iPhone 8 حداکثر به iOS 16.7 میرسد و بسیاری از کاربران روی iOS ۱۵.x یا ۱۶.۰–۱۶.۱ میمانند.
مشکل / هدف
استایل پنل بهشدت به توابع رنگ مدرن CSS وابسته است که روی WebKit قدیمی پشتیبانی نمیشوند و مقدارشان نامعتبر میشود → مرورگر مقدار را دور میریزد → رنگ به transparent/سیاه/ارثی میافتد → کل UI بهم میریزد:
oklch()— فقط Safari 15.4+ . روی iOS 15.0–15.3 خراب.color-mix()— فقط Safari 16.2+ . روی iOS 15.x و 16.0/16.1 خراب. (۳۰ مورد در فایل)- Tailwind v4 — رسماً فقط Safari 16.4+ را هدف میگیرد (
@property, cascade layers, oklch). روی iPhone 8 قدیمی base/reset ناقص اجرا میشود.
هدف: افزودن fallback رنگ sRGB و گارد @supports تا پنل روی WebKit قدیمی هم صحیح رندر شود (progressive enhancement — روی مرورگر جدید دقیقاً مثل الان بماند).
فایلهای مرتبط
| فایل | نقش |
|---|---|
clinicpro/assets/admin/styles.css |
تمام متغیرهای رنگ + ۳۰ مورد color-mix + oklch |
clinicpro/templates/admin/index.html.twig |
shell پنل (viewport موجود و درست) |
clinicpro/package.json |
Tailwind v4 (tailwindcss@^4, @tailwindcss/postcss@^4) |
وضعیت فعلی
هیچ fallback و هیچ @supports وجود ندارد (grep -c "@supports" = 0).
متغیرهای رنگ فقط با oklch تعریف شدهاند (خط ۳۰ و ۸۵):
/* :root روشن */
--primary: oklch(0.55 var(--brand-c) var(--brand-h));
--primary-600: oklch(0.49 var(--brand-c) var(--brand-h));
--primary-700: oklch(0.43 var(--brand-c) var(--brand-h));
--primary-soft: oklch(0.95 0.03 var(--brand-h));
--primary-soft2: oklch(0.90 0.05 var(--brand-h));
--ring: color-mix(in oklch, var(--primary) 32%, transparent);
تم تیره (خط ۸۵+) کلاً روی color-mix سوار است → روی iOS قدیمی کامل خراب:
[data-theme="dark"] {
--primary: oklch(0.66 var(--brand-c) var(--brand-h));
--primary-soft: color-mix(in oklch, var(--primary) 16%, var(--surface));
--success-bg: color-mix(in oklch, var(--success) 18%, var(--surface));
--warning-bg: color-mix(in oklch, var(--warning) 18%, var(--surface));
/* ... danger-bg, info-bg, violet-bg, accent-bg, stat-*-bg همه color-mix */
}
استفاده inline در قوانین (خط ۴۶۹–۴۷۳ و بلوک settings جدید):
.appt-status.status-green { border-color: color-mix(in srgb, var(--success) 25%, transparent); }
.toggle-row.on { border-color: color-mix(in oklch, var(--primary) 40%, var(--border)); }
.save-bar.ok { border-color: color-mix(in oklch, var(--success) 45%, var(--border)); }
.gw-card ... /* و موارد مشابه */
وظایف
۱. fallback هگز sRGB برای متغیرهای رنگِ مبتنی بر oklch
برای هر متغیری که با oklch() تعریف شده، یک خط هگز sRGB قبل از خط oklch بگذار. مرورگر قدیمی خط oklch را نامعتبر میبیند و خط هگز قبلی را نگه میدارد؛ مرورگر جدید oklch را استفاده میکند.
الگو (در :root روشن):
:root {
/* primary = تقریب sRGB از brand-h:256 brand-c:0.15 */
--primary: #5b5ef0; /* fallback */
--primary: oklch(0.55 var(--brand-c) var(--brand-h));
--primary-600: #4a4dd6; /* fallback */
--primary-600: oklch(0.49 var(--brand-c) var(--brand-h));
--primary-700: #3d40b8; /* fallback */
--primary-700: oklch(0.43 var(--brand-c) var(--brand-h));
--primary-soft: #eceafd; /* fallback */
--primary-soft: oklch(0.95 0.03 var(--brand-h));
--primary-soft2: #d9d5fb; /* fallback */
--primary-soft2: oklch(0.90 0.05 var(--brand-h));
--ring: rgba(91,94,240,.32); /* fallback */
--ring: color-mix(in oklch, var(--primary) 32%, transparent);
}
- مقادیر هگز باید چشمی به رنگ oklch نزدیک باشند (با ابزار تبدیل oklch→sRGB بگیر؛
--brand-h: 256,--brand-c: 0.15). - همین کار را برای تم تیره (
[data-theme="dark"]) تکرار کن:--primary,--primary-600/700, و همه*-soft/*-bgکه با color-mix ساخته شدهاند، هرکدام یک هگز fallback قبل از خط color-mix بگیرند (رنگ تیره مناسب سطح تیره).
۲. fallback برای color-mix در قوانین inline
هرجا color-mix() مستقیم داخل یک قانون استفاده شده (نه در تعریف متغیر)، یک خط رنگ ساده قبل از آن بگذار:
.appt-status.status-green {
border-color: rgba(21,163,90,.25); /* fallback */
border-color: color-mix(in srgb, var(--success) 25%, transparent);
}
.toggle-row.on {
border-color: var(--border-2); /* fallback */
border-color: color-mix(in oklch, var(--primary) 40%, var(--border));
}
.save-bar.ok {
border-color: var(--success); /* fallback */
border-color: color-mix(in oklch, var(--success) 45%, var(--border));
}
- کل ۳۰ مورد
color-mixرا پیدا کن (grep -n "color-mix" assets/admin/styles.css) و برای هرکدام fallback مناسب اضافه کن. color-mix(in srgb, ...)هم روی iOS < 16.2 خراب است؛ پس اینها هم باید fallback بگیرند.
۳. تصمیم درباره Tailwind v4
Tailwind v4 فقط Safari 16.4+ را هدف میگیرد. بررسی کن پنل چقدر به utilityهای Tailwind وابسته است (بهنظر کم — بیشتر استایلها inline یا کلاسهای design-system سفارشیاند: grep -rho 'className="[^"]*"' assets/admin | grep -oE '(flex|grid|text-|bg-|p-[0-9]|gap-|rounded)').
- اگر وابستگی کم بود: کافی است وظیفه ۱ و ۲ انجام شود؛ مشکل اصلی رنگهاست.
- اگر جایی از رنگهای Tailwind (
bg-*,text-*) استفاده شده که oklch تولید میکنند و روی iOS قدیمی خرابند، همانها را با کلاس design-system سفارشی (که حالا fallback دارد) جایگزین کن. - در فایل پرامپت خروجی، حداقل نسخهٔ پشتیبانیشده را مستند کن.
۴. تست
- با Safari دسکتاپ: Develop → Enter Responsive Design Mode → iPhone 8 و نسخهی WebKit قدیمی؛ یا BrowserStack با iOS 15.x.
- چک کن: رنگ primary دکمهها، پسزمینه کارتها، بوردرها، تم تیره، chipهای وضعیت، صفحه
/admin/settings(toggleها و gw-cardها). - مطمئن شو روی مرورگر جدید هیچ تغییری در ظاهر ایجاد نشده (fallback فقط روی قدیمی فعال میشود).
نکات مهم
- ترتیب اعلانها حیاتی است: خط fallback باید قبل از خط مدرن بیاید. CSS اعلان نامعتبر را دور میریزد و آخرین اعلانِ معتبر را نگه میدارد.
- تغییر فقط در
assets/admin/styles.css(و در صورت نیاز جزئی در twig برایtheme-color). backend/API دست نخورد → نیاز به migration یا آپدیتdocs/api/نیست. - بعد از تغییر CSS:
ddev exec yarn devبزن و کامپایل موفق را تأیید کن (خطای شناختهشدهٔlightningcss.linux-arm64-gnuروی ddev بیربط است). - مراقب باش fallbackها با تم تیره تداخل نکنند؛
[data-theme="dark"]مقادیر خودش را دارد و باید fallback تیره بگیرد نه روشن. - viewport در twig درست است (
width=device-width, initial-scale=1) — دست نزن.