وب مدرن، رابط کاربری و تجربهی وب · فصل ۲ — HTML، CSS، Responsive و RTL · 38
Responsive CSS: Grid, Flex و Logical Properties
میتواند «Responsive CSS: Grid, Flex و Logical Properties» را در یک feature محدود طراحی/پیادهسازی کند و correctness، accessibility یا failure behavior مرتبط را اثبات کند.
خلاصهٔ درس
میتواند «Responsive CSS: Grid, Flex و Logical Properties» را در یک feature محدود طراحی/پیادهسازی کند و correctness، accessibility یا failure behavior مرتبط را اثبات کند.
خروجی این درس
میتواند «Responsive CSS: Grid, Flex و Logical Properties» را در یک feature محدود طراحی/پیادهسازی کند و correctness، accessibility یا failure behavior مرتبط را اثبات کند.
پیشنیازها
یک صفحه ممکن است در موبایل «درست دیده شود» اما از نظر مهندسی Responsive خراب باشد
فرض کنید صفحه فهرست محصولات روی لپتاپ کاملاً مرتب است. در سمت چپ یک پنل فیلتر دیده میشود، نتایج در سمت دیگر قرار گرفتهاند، و در Header لوگو، Search و Actionهای حساب کاربری در یک ردیف جا شدهاند. برنامهنویس عرض Browser را کم میکند؛ جایی نزدیک عرضهای رایج موبایل چیدمان میشکند. اولین واکنش بسیار آشناست: یک @media در 768px اضافه میشود، ستونها روی هم میافتند، با order: -1 فیلتر به بالای نتایج برده میشود و برای فاصلهگذاری هم چند margin-left و margin-right نوشته میشود. Screenshot در 375px خوب است، پس کار تمامشده به نظر میرسد.
بعد نسخه عربی یا فارسی وارد میشود. فاصلهای که معنایش «بعد از این عنصر در مسیر خواندن» بوده، چون با margin-left نوشته شده در سمت اشتباه میماند. یک شناسه محصول طولانی باعث میشود ستون اصلی از Viewport بزرگتر شود. ترتیب Tab یا ترتیب خطی محتوا با چیزی که CSS روی صفحه جابهجا کرده همراستا نیست. بعد یک Breakpoint دیگر برای Tablet میآید، یکی برای Laptop کوچک، یکی برای نسخه Embedded. چند ماه بعد هیچکس نمیداند هر عدد واقعاً نماینده چه Constraintی بوده است.
مسئله این درس «یاد گرفتن چند Property جدید» نیست. مسئله این است که Responsive Layout را بهعنوان یک Contract قابل توضیح، قابل آزمایش و قابل تعمیر ببینیم. یعنی قبل از اینکه بگوییم «Grid بزن» یا «Flex بهتر است»، مشخص کنیم دقیقاً چه رابطهای باید حفظ شود، چه چیزی در عرض کمتر میشکند، Direction چه اثری دارد، و از کجا میفهمیم Repair واقعاً علت را حل کرده است.
برای سناریوی محدود این درس چهار بعد بحرانی داریم:
- Layout model: برای هر Container مکانیزمی انتخاب شود که با هندسه واقعی مسئله همخوان است. Grid وقتی مناسب است که رابطه Trackها در دو بعد مهم باشد؛ Flexbox وقتی مناسب است که توزیع و Alignment در یک محور اصلی، مسئله غالب باشد. هیچکدام برنده همیشگی نیستند.
- Responsive constraint: تغییر State باید از یک Constraint واقعی محتوا یا فضا ناشی شود، نه صرفاً از نامهایی مثل Mobile، Tablet یا Desktop.
- Direction intent: هر جا مفهوم «ابتدا/انتها در جریان نوشتار» داریم، باید بررسی کنیم Logical Properties بهتر از Physical left/right معنا را بیان میکنند یا نه.
- Order integrity: ترتیب منطقی DOM/source باید درست بماند. Visual reordering ابزار نمایش است، نه ابزار اصلاح معنای Document.
خروجی اصلی شما در طول درس Responsive Layout Evidence Matrix v1 است. این Matrix مجموعه Screenshot نیست. در هر Row باید Scenario، ناحیه، Contract ترتیب، نوع مسئله Layout، مکانیزم انتخابی، Constraint تغییر State، تصمیم Direction، Observation واقعی، Inference، Mutation، Repair و Residual Limitation ثبت شود.
معیار پایان درس هم «در عرض من خوب شد» نیست. باید Baseline و Changed Context را بررسی کنید، حداقل یک Failure عمدی ایجاد شود، سیستم Evidence آن Failure را تشخیص دهد، و Repair بدون خرابکردن Source Order یا ورود به Scope درسهای مجاور Contract را بازگرداند.
سه مسیر یادگیری، یک استاندارد Evidence
ممکن است شما تازه با Layout مدرن CSS آشنا شده باشید، یا سالهاست display: flex و display: grid مینویسید. تفاوت تجربه فقط مقدار توضیح Syntax را تغییر میدهد؛ سطح Evidence تغییر نمیکند.
مسیر Foundation. ابتدا Axis، Track، Intrinsic sizing، Logical Direction و مفهوم Constraint را دقیق بسازید. هر بار فقط یک Container را بررسی کنید. قبل از تغییر CSS پیشبینی کنید Browser چه خواهد کرد و بعد نتیجه را مشاهده کنید. هدف این مسیر ساختن Mental Model است، نه حفظکردن Recipe.
مسیر Repair. اگر Responsive CSS میدانید اما یک Failure تکراری دارید—مثلاً Horizontal Overflow، مشکل عجیب min-width، باگ RTL یا اختلاف Visual Order و DOM—Fixture را به همان Contract شکستخورده تقلیل دهید. علت را Observation-based پیدا کنید، Mutation بزنید، کوچکترین Repair را اعمال کنید و بعد به Full Scenario برگردید.
مسیر Experienced. توضیحهای پایه Syntax را سریعتر رد کنید. مستقیم Contract هر Container را بنویسید، مکانیزم را دفاع کنید، Width و Direction را تغییر دهید، Source Order را Inspect کنید و Limitation باقیمانده را ثبت کنید. سابقه زیاد جای Evidence را نمیگیرد.
پیشنیاز سخت این درس WEB-009 است. از آن درس فرض میکنیم Structure و Source Order معنایی پایه از قبل قابل دفاع است. این درس Semantic HTML را از اول آموزش نمیدهد. اگر DOM از ابتدا ترتیب منطقی غلطی داشته باشد، CSS نمیتواند با Visual Reordering آن را واقعاً اصلاح کند.
در عین حال Scope را کنترل میکنیم. برای Interactive controlها میتوانیم Default Sequential Focus را بهعنوان Signal اختلاف Visual/Source Order مشاهده کنیم، اما طراحی Keyboard Interaction سفارشی هدف این درس نیست. Direction را بین LTR و RTL تغییر میدهیم و Logical Properties را میسنجیم، ولی ادعا نمیکنیم این کار تمام مسائل Unicode Bidi، Text Isolation، Punctuation یا Mixed Script را حل میکند.
قاعده عملی این درس:
Syntax را میتوان فشرده کرد؛ Evidence را نه.
اگر gap، minmax() یا margin-inline-start را میشناسید، وقت را روی تعریف آنها تلف نکنید. اما اگر نمیتوانید بگویید کدام Constraint را حل میکنند، چه Observationی تصمیم شما را رد میکند و چه Limitationی باقی مانده، هنوز مهارت کامل نشده است.
Mental Model: Source Structure → Constraint → Layout Model → Responsive State → Evidence
Responsive CSS وقتی قابل پیشبینیتر میشود که صفحه را مجموعهای از Rectangleهای خالی نبینید. هر Box از محتوا، Intrinsic Size، Formatting Context، Minimumها، Available Space و Direction تأثیر میگیرد. CSS در واقع روی یک سیستم Constraint کار میکند.
1. Source Structure یک Invariant مهم است
HTML ترتیب عناصر را تعریف میکند. CSS میتواند Boxها را روی Trackهای متفاوت بگذارد، در یک Axis توزیع کند، Wrap کند یا Visual Order آنها را تغییر دهد. همین جدایی Presentation از Structure قدرت CSS است؛ اما همانجا یک مسئولیت هم ایجاد میشود: Visual Placement نباید به اشتباه بهعنوان تغییر Source Order فهمیده شود.
برای Catalog ما یک Structure سطح بالا میتواند این باشد:
header
main
filter controls
results heading/status
product list
در عرض زیاد، Filter کنار Results دیده میشود. در عرض کم، Filter بالای Results میآید. اگر Source Order از ابتدا همین رابطه منطقی را دارد، میتوان هر دو Presentation را بدون order ساخت. اگر مجبور شدید با order: -999 یک Control مهم را به جایی ببرید که از ابتدا باید در Sequence منطقی مناسب قرار میگرفت، لازم است Contract را دوباره بررسی کنید.
2. محتوا Minimum Demand ایجاد میکند
Text، Image، Form Control، Aspect Ratio، Long Token، min-content، Explicit Width و Minimum Size همه در Sizing شرکت میکنند. بنابراین ممکن است جمع ساده عددها بگوید فضا کافی است اما Layout Engine نتیجه دیگری بدهد.
مثلاً:
.catalog {
display: grid;
grid-template-columns: 18rem 1fr;
gap: 1.5rem;
}
برداشت ساده این است که 1fr هر مقدار فضای باقیمانده را میگیرد و تا هر اندازه لازم باشد کوچک میشود. این برداشت کامل نیست. Intrinsic Minimum Contributionهای فرزندان میتوانند اجازه ندهند Track یا Item به اندازه مورد انتظار Shrink شود. یک Product ID بدون Break Opportunity یا یک Child با Minimum Inline Size میتواند Horizontal Overflow بسازد.
سؤال درست این نیست که «Breakpoint موبایل چند باشد؟» سؤال درست این است:
کدام Box یا Track حاضر نیست کوچکتر شود، و چرا؟
3. Grid و Flex را بر اساس Relationship انتخاب کنید
Grid و Flexbox همپوشانی دارند. بسیاری از Layoutها با هر دو ساخته میشوند. ما از یک Heuristic محدود استفاده میکنیم، نه قانون مطلق.
وقتی Contract حول رابطه صریح Row/Column است—مثلاً ستون Filter و Results باید Trackهای مشخص داشته باشند، چند Region باید Span کنند یا Alignment دو بعدی مهم است—Grid اغلب مدل واضحتری میدهد.
وقتی مسئله اصلی توزیع در یک Main Axis است—مثلاً Brand، Search و Actionها در Header؛ Button Group؛ Toolbar؛ Tag list؛ Footer داخلی Card—Flexbox معمولاً رابطه را مستقیمتر بیان میکند.
یک Page میتواند هم Grid داشته باشد و هم Flexbox. سؤال «این صفحه Grid است یا Flex؟» معمولاً بیشازحد درشت است. سؤال بهتر:
این Container دقیقاً مالک چه Relationshipی است؟
4. Responsive State باید Trigger واقعی داشته باشد
یک Breakpoint زمانی قابل دفاع است که بتوانید بگویید آن سوی Threshold چه Contractی Fail میشود. نمونهها:
- Filter و Results دیگر Minimum Useful Width خود را همزمان حفظ نمیکنند؛
- Search در Header به زیر Minimum قابل استفاده میرسد؛
- Card trackها از Width پذیرفتهشده کوچکتر میشوند؛
- Action group مجبور به Wrapی میشود که Hierarchy را خراب میکند؛
- Labelهای Localized با وجود Fit شدن نسخه انگلیسی Collision ایجاد میکنند.
ممکن است در نهایت همان @media (max-width: 48rem) بنویسید. تفاوت این است که عدد 48rem توضیح مهندسی دارد؛ اسم Tablet نیست.
5. Direction یک Changed Context واقعی است
Physical Propertyها Geometry ثابت را بیان میکنند: left، right، top، bottom. Logical Propertyها Relative به Writing Flow هستند: inline-start، inline-end، block-start، block-end.
اگر Badge باید بهخاطر Art Direction همیشه در گوشه فیزیکی چپ تصویر باشد، left ممکن است کاملاً درست باشد. اگر فاصله یعنی «بین Icon و Label بعدی در مسیر Inline»، margin-inline-end Intent را بهتر از margin-right بیان میکند.
این مهم است چون direction و writing-mode Mapping محورهای Logical را تغییر میدهند. Logical Property میتواند بدون Override دستی left/right همان Intent را نگه دارد.
اما مرز را حفظ کنید: Logical Properties تمام مسائل RTL/Bidi را حل نمیکنند. آنها فقط Class مشخصی از Directional Layout Intent را بهتر Encode میکنند.
6. Evidence حلقه را کامل میکند
در هر Scenario بحرانی حداقل اینها را ثبت کنید:
- Viewport یا Container Size؛
- Direction؛
- Layout Model هر Region؛
- DOM/source order؛
- Visual Placement؛
- وجود یا عدم وجود Horizontal Overflow؛
- Default Sequential Focus در جایی که مرتبط است؛
- Mutation؛
- Mutation Result؛
- Repair؛
- Repair Result؛
- یک Residual Limitation.
پس Mental Model اصلی این است:
Structure را حفظ کن → Constraint را پیدا کن → Mechanism را انتخاب کن → State transition را به Failure واقعی وصل کن → نتیجه را مشاهده و ثبت کن.
Foundation: Axis، Track، Intrinsic Size و Logical Direction
این بخش دایرةالمعارف CSS نیست. فقط Vocabulary لازم برای Decision و Lab را میسازیم.
Flexbox: مسئله توزیع در Main Axis
Flex Container یک Main Axis و Cross Axis دارد. Itemها در Main Axis توزیع میشوند و میتوانند Grow/Shrink کنند. Wrapping میتواند چند Line بسازد، اما مدل پایه همچنان Axis-oriented است.
مثلاً Header:
.header-row {
display: flex;
align-items: center;
gap: 0.75rem;
}
.header-search {
flex: 1 1 24rem;
min-inline-size: 12rem;
}
.header-actions {
display: flex;
gap: 0.5rem;
}
این Code را Recipe نبینید. Contract را بخوانید: سه گروه اصلی داریم؛ Search میتواند Grow و Shrink کند اما Minimum مفید دارد؛ Actionها گروه تکمحوره جدا هستند. وقتی مجموع Demandها دیگر Fit نشود باید State دیگری تعریف شود.
gap وقتی فقط «فاصله بین Siblingها» میخواهیم مزیت مهمی دارد: Directional left/right assumption وارد نمیکند.
Grid: Trackها رابطه دو بعدی را بیان میکنند
Grid Row و Column تعریف میکند و Itemها را در آنها قرار میدهد. برای Shell اصلی Catalog:
.catalog-layout {
display: grid;
grid-template-columns: 18rem minmax(0, 1fr);
gap: 1.5rem;
align-items: start;
}
Track اول Filter است. Track دوم Results و Flexible است. minmax(0, 1fr) بهطور صریح میگوید Minimum Track میتواند تا صفر پایین بیاید و سپس Free Space با fr توزیع شود.
این یک Cure عمومی Overflow نیست. Descendant میتواند هنوز Width ثابت یا Content غیرقابل شکستن داشته باشد. پس هر بار علت را مشخص کنید.
1fr به معنی «هر طور شده جا میشود» نیست
یک خطای ذهنی رایج این است که فکر کنیم Fraction Unit بهتنهایی تمام Shrinkability را حل میکند. Intrinsic Minimumها هنوز میتوانند نقش داشته باشند.
فرض کنید در Results داریم:
<p class="product-id">
PART-2026-VERY-LONG-UNBROKEN-IDENTIFIER-ALPHA-00000001
</p>
بسته به Structure و Sizing، Repairهای متفاوتی ممکن است درست باشند:
.results {
min-inline-size: 0;
}
یا:
.catalog-layout {
grid-template-columns: 18rem minmax(0, 1fr);
}
یا در لایه محتوا:
.product-id {
overflow-wrap: anywhere;
}
این سه Rule یک چیز را حل نمیکنند. اولی Minimum Item را تغییر میدهد؛ دومی Track Minimum را؛ سومی Break Opportunity متن را. اگر هر سه را بیدلیل همه جا Paste کنید، Bug فعلی شاید ناپدید شود اما Model شما بهتر نشده است.
روش درست:
- Box/Track کنترلکننده را پیدا کنید؛
- پیشبینی کنید کدام تغییر باید اثر بگذارد؛
- فقط همان تغییر محدود را اعمال کنید؛
- نتیجه و Side Effect را مشاهده کنید.
Logical Properties یعنی Coordinate System درست را انتخاب کنید
چند Mapping رایج:
/* Physical */ /* Logical */
margin-left: 1rem; margin-inline-start: 1rem;
margin-right: 1rem; margin-inline-end: 1rem;
padding-top: 1rem; padding-block-start: 1rem;
width: 20rem; inline-size: 20rem;
min-width: 0; min-inline-size: 0;
left: 0; inset-inline-start: 0;
نسخه Logical صرفاً چون جدیدتر است بهتر نیست. باید Intent شما Logical باشد.
مثلاً Icon قبل از Text:
.icon {
margin-inline-end: 0.5rem;
}
در LTR افقی معمولاً این Margin روی Side فیزیکی Right قرار میگیرد و در RTL Mapping تغییر میکند. CSS یک بار Intent را نوشته است.
Breakpoint از Constraint میآید، نه از Device Catalog
ممکن است Design System شما Tokenهایی مثل sm, md, lg داشته باشد. استفاده از Token اشکال ندارد. خطا زمانی است که Token جای دلیل را بگیرد.
منابع واقعی Constraint میتوانند اینها باشند:
- Minimum useful inline size یک Control؛
- Intrinsic/min-content pressure؛
- Maximum readable measure؛
- Minimum accepted card width؛
- Collision بین Region ثابت و Flexible؛
- Translation طولانیتر؛
- Direction change که Physical assumption را آشکار میکند.
پس فقط Test کردن 320، 768 و 1440 Evidence قوی نیست. اطراف Boundary واقعی هم باید Probe شود.
Deep Explanation: چرا Shortcutهای رایج Responsive شکست میخورند
Shortcut 1: «برای Page از Grid، برای Component از Flex استفاده کن»
این Rule حافظهای ساده است اما مرز واقعی را خراب میکند. یک Component میتواند رابطه دو بعدی مهم داشته باشد؛ یک Region بزرگ Page میتواند مسئله ساده تکمحوره باشد.
مثلاً Pricing Comparison با Row/Columnهای هماهنگ ممکن است داخل یک Component باشد اما Grid طبیعیتر است. Header کل Page ممکن است فقط Brand، Search و Actions را در یک محور توزیع کند و Flex کافی باشد.
جایگزین Evidence-based:
- Relationship مالک Container را نامگذاری کنید؛
- یکمحوره یا دوبعدی بودن آن را تشخیص دهید؛
- کوچکترین Model واضح را انتخاب کنید؛
- بنویسید چه Evidenceی Alternative را بهتر میکند.
Shortcut 2: «Overflow شد، Breakpoint اضافه کن»
Breakpoint State را عوض میکند؛ Cause را توضیح نمیدهد. اگر علت min-inline-size، Intrinsic Content، Fixed Width یا Unbreakable Descendant باشد، Breakpoint فقط Failure را از یک Width به Width دیگر هل میدهد.
قبل از Media Query جدید، Sizing را Diagnose کنید:
- Available inline size را کدام Container تعیین میکند؟
- کدام Child یا Track بیشتر از آن Demand دارد؟
- Explicit
min-*داریم یا Automatic Minimum؟ - Content unbreakable است؟
- یک Image یا Control Width ثابت دارد؟
- Contract میخواهد Box Shrink کند، Text Break شود، Region Scroll شود یا State تغییر کند؟
اینها Product Decisionهای متفاوتاند.
مثلاً Horizontal Scroll برای Data Table ممکن است عمدی باشد. برای Primary Page Shell معمولاً Horizontal Viewport Overflow بدون دلیل Signal شکست است. برای Identifier شاید Wrapping مجاز باشد یا نباشد. این درس Outcome عمومی تعیین نمیکند؛ Evidence و Contract را اجباری میکند.
Shortcut 3: «overflow: hidden بزن، درست میشود»
overflow: hidden خودش بد نیست. میتواند Decorative Bleed را کنترل کند. اما اگر برای پنهانکردن Root Cause استفاده شود، Evidence را حذف میکند.
اگر CTA مهم Clip شود، Screenshot شاید تمیز شود اما Feature Fail کرده است. قبل از Clip کردن، بنویسید Content Availability جزو Contract هست یا نه.
Shortcut 4: «DOM را برای Mobile بچین، Desktop را با order درست کن»
Grid placement و Flex order میتوانند Visual Sequence را تغییر دهند، اما Source Order را Rewrite نمیکنند. Standardهای Grid و Flex صریحاً Visual Reordering را از Source/Speech/Sequential Navigation جدا میکنند.
برای Catalog ما اگر Filter منطقی باید قبل از Results باشد، همان DOM میتواند Wide و Narrow را پوشش دهد: Wide کنار هم، Narrow پشت سر هم. نیاز به order نداریم.
اگر Design واقعاً Visual Sequence متفاوتی میخواهد، Trade-off را ثبت و User Flow مربوط را Test کنید. Rule محدود ما:
Visual Reordering را بهعنوان Repair Source Order غلط استفاده نکنید.
Shortcut 5: «RTL یعنی همه left/rightها را Flip کن»
Manual Flip در Scale بزرگ شکننده است. بعضی Geometryها باید Physical بمانند، بعضی Relationshipها Logical هستند.
برای هر Rule Directional بپرسید:
- این Side از نظر فیزیکی مهم است؟
- یا منظور Start/End در جریان متن است؟
- Dimension باید Inline/Block-relative باشد؟
- Nested Direction با Document فرق دارد؟
بعد Property مناسب را انتخاب کنید.
یک مرز دیگر: direction: rtl Layout Mapping را تغییر میدهد، اما Mixed Script Bidi مسئله جداست. Passing Screenshot RTL مجوز ادعای Full i18n نیست.
Shortcut 6: «Flex اگر Wrap کند دیگر مثل Grid است»
Flex Wrap چند Line تولید میکند، اما مدل همچنان Main-Axis oriented است. Itemهای Lineهای مختلف لزوماً یک Track System مشترک دوبعدی ندارند.
اگر Alignment Columnها بین Rowها مهم است، Grid ممکن است Relationship را مستقیمتر بیان کند. اگر هر Line مستقل است و Distribution مهمتر است، Flexbox ممکن است بهتر باشد.
ظاهر «چند سطر و چند ستون» برای تصمیم کافی نیست.
Shortcut 7: «Logical Properties یعنی RTL تمام شده»
Logical Properties یک Class مهم از Assumptionهای Physical Direction را حذف میکنند، اما Translation طولانی میتواند Intrinsic Size را عوض کند؛ Mixed Text میتواند Bidi issue داشته باشد؛ Font Metrics و Line Breaking میتوانند Layout را تغییر دهند.
در این درس RTL دو نقش دارد:
- Physical left/right assumption را آشکار کند؛
- Layout را در Changed Context دیگری تحت فشار قرار دهد.
نتیجه را محدود نگه دارید: «Layout Direction در Fixture تست شد»، نه «Localization کامل است».
Decision Loop دقیقتر
برای هر Region این Sequence را اجرا کنید:
- Invariant را بنویسید. چه Source Order و Relationshipی باید حفظ شود؟
- Geometry را نام ببرید. One-axis، Two-dimensional Track، Normal Flow یا چیز دیگر؟
- Constraintها را لیست کنید. Minimum Control Size، Intrinsic Content، Available Space، Direction، Wrapping، Product Rule.
- Baseline Model را انتخاب کنید. Grid، Flex، Flow یا ترکیب محدود.
- Transition را پیدا کنید. Width/Content/Direction را تغییر دهید تا Constraint Fail شود.
- Responsive State را تعریف کنید. فقط چیزی را تغییر دهید که Failure لازم کرده است.
- Failure Probe بزنید. Long Token، Narrower Container، Direction switch یا Visual Reorder.
- Observation ثبت کنید. قبل از Conclusion.
- Repair کنید. کوچکترین Change متعلق به Cause.
- Residual Limitation بنویسید. یک Browser Session Universal proof نیست.
این روش در اولین اجرا از Copy/Paste کندتر است؛ در Maintenance بسیار ارزانتر است چون هر Rule Reason دارد.
Worked Example: Workspace مستندات با Section Index، Article Canvas و Utility Strip
این Worked Example عمداً از Feature متفاوتی نسبت به Lab اجرایی Product Catalog استفاده میکند. مفهومها Transfer میشوند، اما Fixture، Selectorها، Geometry، Thresholdها و تصمیم CSS نهایی یکسان نیستند. این جداسازی مهم است: Worked Example باید روش فکرکردن را آموزش دهد، نه اینکه Answer قابل Copy برای Lab اجباری بسازد.
سناریو یک Workspace مستندات داخلی است. در حالت Wide، Section Index کنار Article قرار دارد. Utility Strip بالا شامل لینک Workspace، Search و دو Action است. در حالت Narrow، Index به Block فشردهای قبل از Article تبدیل میشود. رابط باید در LTR و RTL قابل دفاع بماند و نامهای بلند API داخل Article نباید کل صفحه را از Available Inline Size عریضتر کنند.
گام 1: Source-order Contract را قبل از Layout بنویسید
ساختار ساده میتواند این باشد:
<header class="docs-tools">
<a class="workspace-link" href="/docs">Engineering Docs</a>
<form class="docs-search" role="search">
<label for="docs-q">جستوجوی مستندات</label>
<input id="docs-q" name="q" type="search">
</form>
<div class="docs-actions">
<button type="button">تاریخچه</button>
<button type="button">اشتراکگذاری</button>
</div>
</header>
<main class="docs-shell">
<nav class="section-index" aria-label="در این صفحه">
<!-- section links -->
</nav>
<article class="doc-article">
<h1>Request signing</h1>
<p>...</p>
<section class="related-topics">...</section>
</article>
</main>
Index در Source قبل از Article است، چون همین Sequence در Narrow هم قابل دفاع است: کاربر Local Navigation را میبیند و بعد Document مربوط به آن را. این تصمیم Product/Semantics است، نه تصمیم Grid. CSS میتواند Geometry را عوض کند، اما نباید فقط برای راحتشدن Screenshot، Sequence منطقی را مخفیانه بازتعریف کند.
قبل از CSS چند Invariant بنویسید:
- Index و Article دو Region مستقل بمانند؛
- Article سطح اصلی خواندن باشد؛
- Local Navigation طبق Contract انتخابشده قبل از Article بماند؛
- Utility Actionها بدون وابستگی به Visual Reorder قابل دسترسی باشند؛
- Spacingهایی که Flow-relative intent دارند با Direction سند Map شوند.
گام 2: Geometry هر Container را جدا Classify کنید
Main Workspace در Wide یک رابطه صریح دو Track دارد: Track مربوط به Index و Track انعطافپذیر Article. Grid Candidate طبیعی است چون هر دو Track در یک Placement Model دوبعدی شرکت میکنند.
Utility Strip مسئله دیگری دارد. Requirement غالب آن Distribution روی یک Row است؛ Search میتواند رشد کند و Actionها کنار هم بمانند. Flexbox Baseline معقولی است. اگر Requirement بعدی یک Row دوم دقیق با Alignment ستونی بخواهد، Geometry جدید میتواند تغییر Mechanism را توجیه کند. انتخاب اولیه Flexbox قرارداد ابدی نیست.
Related Topicهای داخل Article هم Container مستقلاند. اگر Cardهایی با Track تکرارشونده باشند، Grid ممکن است مناسب باشد. اگر فقط Tagهایی هستند که Wrap میشوند، Flexbox یا Normal Flow شاید واضحتر باشد.
قاعده قابل Transfer این است: Layout Model را برای Geometry همان Container انتخاب کنید، نه برای Brand صفحه، Framework یا عادت Developer.
گام 3: رابطه دو Track در Wide را صریح کنید
یک Baseline ممکن:
.docs-shell {
display: grid;
grid-template-columns: minmax(12rem, 16rem) minmax(0, 1fr);
gap: clamp(1rem, 2.5vw, 2rem);
align-items: start;
}
.doc-article {
min-inline-size: 0;
}
دو Boundary متفاوت داریم. Track اول Range محدود دارد چون Index باید فضای مفید داشته باشد ولی نباید بینهایت رشد کند. Track Article Flexible است. Minimum صفر برای Track دوم اجازه میدهد Shrinkability مطابق Contract بررسی شود و Automatic Minimum بیدلیل همیشه برنده نباشد.
min-inline-size: 0 در Boundary خود Item است، نه Track Definition. این Declaration طلسمی نیست که همهجا Paste شود. اگر Intrinsic Contribution یک Descendant یا Automatic Minimum خود Item مانع Shrink مطلوب است، میتواند Repair مربوط باشد. اگر Evidence Cause دیگری نشان داد، Repair را همانجا نگه دارید.
عددهای 12rem و 16rem قانون عمومی نیستند. سؤال مهندسی این است که کدام Minimum واقعاً Product Constraint است و کدام فقط پیامد Content یا Default Sizing.
گام 4: State Transition را از Constraint Failure استخراج کنید
فرض کنید Index یک Minimum مفید دارد، Article هم Minimum خوانایی پذیرفتهشده دارد و Gap نیز Minimum Design System دارد. Available Inline Size را آرام کم کنید.
در نقطهای این Requirementها دیگر در دو ستون همزمان جا نمیشوند. این دلیل State Change است، نه واژه «Tablet». Media Query ممکن است Transition مشاهدهشده را Encode کند، اما Evidence باید Cause را نگه دارد.
برای این Fixture فرض کنیم بعد از Test روی Labelهای واقعی، Transition در حدود یک Width مشخص دیده شده است:
@media (max-width: 56rem) {
.docs-shell {
grid-template-columns: minmax(0, 1fr);
}
.section-index {
border-block-end: 1px solid currentColor;
padding-block-end: 0.75rem;
}
}
عدد Threshold Observation همین Fixture است. اگر Translation، Font Metric، عمق Index یا Product Requirement تغییر کند، ممکن است Threshold هم تغییر کند. Evidence قوی میگوید چرا حالت دو ستونه دیگر پذیرفتنی نبود، نه اینکه آن Width اسم چه Deviceی بوده است.
گام 5: Contract تکمحوره Utility Strip را حفظ کنید
.docs-tools {
display: flex;
align-items: center;
gap: 0.75rem;
padding-block: 0.75rem;
padding-inline: 1rem;
}
.docs-search {
flex: 1 1 24rem;
min-inline-size: 10rem;
}
.docs-actions {
display: flex;
gap: 0.5rem;
}
حالا Content واقعی را Test کنید. اگر Workspace Label + Minimum Search + Action Group دیگر Fit نشوند، چند Repair ممکن است: Flex Wrap، انتقال Search به Row جدید، یا تغییر Visible Action اگر Product Contract اجازه دهد.
نتیجه نباید «Flexbox شکست خورد» باشد. یک Configuration مشخص از Flex در یک Constraint مشخص Fail شده است. شاید همان Flex با Wrapping/Basis بهتر کافی باشد؛ شاید Requirement جدید Grid را واضحتر کند. Mechanism را با Evidence تغییر دهید.
گام 6: Directional Intent را بنویسید، نه Coordinate صفحه انگلیسی را
فرض کنید Index یک Border در Edge مجاور Article دارد. اگر Intent واقعاً «Article-facing logical edge» است، آن را Flow-relative بنویسید:
.section-index {
border-inline-end: 2px solid currentColor;
padding-inline-end: 1rem;
}
در RTL Mapping فیزیکی Inline Start/End عوض میشود ولی Relationship ثابت است.
Logical Property به معنی ممنوعیت Physical Property نیست. اگر Watermark عمداً باید در Physical Top-left یک Frame تصویری بماند، Physical Intent واقعی است. دلیل را ثبت کنید. معیار این است که Property با Relationship موردنظر Product همخوان باشد.
گام 7: Intrinsic Content Pressure را بدون تبدیلکردن آن به مسئله Breakpoint Test کنید
Documentation معمولاً Method Name، URL، Hash یا Code Fragment بلند دارد. فرض کنید Related Topic شامل Identifier بدون Break Opportunity است و صفحه Horizontal Scroll پیدا میکند. اول Boundary را پیدا کنید.
Causeهای ممکن:
- Automatic Minimum خود Item؛
- Track Minimum بزرگتر از Intent؛
- Descendant با Inline Size ثابت؛
- Content واقعاً Unbreakable که Policy شکستن متن آن باید تغییر کند.
Probe هدفمند بزنید. اگر فقط اجازه Shrink به Article بدهید و نتیجه هیچ تغییری نکند، Hypothesis مربوط به Item Minimum ضعیف میشود. اگر فقط Break Opportunity Identifier را تغییر دهید و Overflow حذف شود، Evidence به Boundary دیگری اشاره میکند.
«Viewport Horizontal Scroll دارد» Observation است. «Grid Track Cause است» Inference است تا زمانی که Mutation هدفمند از آن پشتیبانی کند.
گام 8: Visual Reordering را Shortcut خطرناک ببینید
فرض کنید کسی میخواهد Article در یک Width قبل از Index دیده شود و با order یا Placement صریح Grid آن را جلو بیاورد، درحالیکه Source Sequence ثابت است. Screenshot ممکن است درست به نظر برسد، اما Visual Sequence و Source/Sequential Order از هم جدا میشوند.
قاعده این نیست که «CSS Reordering همیشه ممنوع است». باید Contract را دوباره بررسی کنید. اگر Information واقعاً Sequence منطقی دیگری میخواهد، شاید Source Architecture باید تغییر کند. اگر فقط Decoration جابهجا میشود، CSS Placement میتواند معتبر باشد. اما CSS نباید وانمود کند Visual Position، Reading یا Default Sequential Navigation Order را بازنویسی کرده است.
Source Sequence و Visual Sequence را جدا Observe کنید. اگر Control تعاملی دارید، Default Focus Progression همان صفحه Testشده را هم ثبت کنید. این Evidence دقیقتر از جمله کلی «Accessibility خوب است» است.
گام 9: Alternativeها را مقایسه کنید
Main Shell را میتوان با Flex Row هم ساخت و در Constraint مشخص Wrap یا Direction را تغییر داد. اگر Cross-axis Track Alignment Requirement نیست، آن Alternative ممکن است کاملاً معتبر باشد. در این Feature، Grid رابطه دو Track را Inspectableتر میکند، اما Winner جهانی نیست.
Utility Strip هم در Product دیگری که Search باید با Trackهای Content زیرش Align شود ممکن است Grid شود. Requirement جدید یعنی Decision Evidence جدید.
در Matrix حداقل یک Alternative و Evidence تغییردهنده تصمیم را بنویسید. Tool Choice باید Falsifiable باشد، نه سلیقه ثابت.
گام 10: Example را با Evidence ببندید، نه Final CSS مقدس
یک Record قابل دفاع برای این Workspace میتواند چنین باشد:
Region: docs-shell
Source-order contract: section index precedes article and remains meaningful in narrow flow
Layout problem: coordinated navigation/article tracks in wide state
Chosen model: Grid
State constraint: two useful minimums + gap stop fitting in available inline size
Observation: wide state stable in tested content; narrow transition required after constraint collision
Directional rule: article-facing spacing expressed with inline-end semantics
Inference: Grid expresses the coordinated-track relationship clearly in this feature
Residual limitation: tested content/browser do not prove every translation or AT combination
چیزی که عمداً وجود ندارد: «همین Selectorها، Breakpointها و CSS را در Product Catalog Lab Copy کنید». این Example Reasoning Pattern را میدهد؛ Lab اجرایی Catalog باید Starter خودش را Inspect کند، Failure خودش را کشف کند، Repair خودش را انتخاب کند و Evidence خودش را بسازد.
Failure Modeها و Mutationهای عمدی
یک Lab قوی فقط Final CSS را Test نمیکند؛ باید نشان دهد سیستم Evidence میتواند Implementation غلط ولی ظاهراً قابل قبول را Catch کند.
Failure A: Intrinsic/Min-content Pressure باعث Horizontal Overflow میشود
Mutation: Rule مربوط به Shrinkability را حذف کنید یا Long Unbreakable Token اضافه کنید.
Diagnosis ضعیف: «Breakpoint موبایل بد است.»
Diagnosis بهتر: Box یا Trackی که Minimum Contribution آن از Available inline size بیشتر شده مشخص شود. scrollWidth/clientWidth یا Observation معادل ثبت شود. بعد Cause محدود Test شود.
اهمیت: Breakpoint جدید ممکن است Bug را در یک Width پنهان کند و در Locale دیگری برگرداند.
Failure B: Physical Spacing فرض LTR را Leak میکند
Mutation: margin-inline-end را با margin-right یا Rule مشابه عوض و RTL را فعال کنید.
Expected Evidence: فاصله روی Side فیزیکی ثابت میماند در حالی که Intent «بعد از عنصر در Inline Flow» بوده است.
Repair: Logical Property برگردد، اگر Intent واقعاً Flow-relative است.
Limit: برای Requirement فیزیکی، Physical Property میتواند درست باشد.
Failure C: Visual Order با Source Order Diverge میشود
Mutation: روی یک Control از order:-1 یا Grid placement استفاده کنید تا عنصر دیرتر در DOM زودتر دیده شود.
Observation: Visual Sequence عوض میشود اما DOM Sequence نه. در Controlهای Focusable ممکن است Tab Sequence هم Source-based بماند.
Repair: اگر Meaningful Sequence باید همان Presentation را پشتیبانی کند، CSS Reorder را حذف کنید و Source/Layout Contract را اصلاح کنید.
Failure D: Breakpoint به Device Name بسته شده است
Mutation: Translation را طولانی یا Base Font Size را بزرگ کنید ولی Breakpoint «Tablet» را ثابت نگه دارید.
Observation: Layout ممکن است قبل یا بعد از Threshold نامگذاریشده Fail شود.
Repair: Trigger واقعی را مستند و State logic را به Constraint مربوط کنید.
Failure E: انتخاب Grid/Flex فقط Habit است
Mutation: Requirement جدیدی اضافه کنید؛ مثلاً Metadata کارتها باید بین چند Row در Column مشترک Align شوند، یا بالعکس Toolbar فقط Distribution ساده و Wrap میخواهد.
Observation: Model فعلی ممکن است برای Relationship جدید Indirection یا Hack زیادی لازم داشته باشد.
Repair: Model همان Container را Reconsider کنید.
Failure F: Overflow با Clipping «حل» میشود
Mutation: overflow:hidden روی Container بگذارید.
Observation: Scrollbar ناپدید میشود اما Content مهم میتواند Clip شود.
Repair: اگر Contract Content Availability میخواهد، Root Cause Sizing/Wrapping/Layout را حل کنید.
Failure G: RTL Screenshot Pass میشود و نتیجه «i18n کامل» اعلام میشود
Mutation: Mixed-direction Text یا Translation طولانی وارد کنید.
Observation: Layout spacing ممکن است درست بماند ولی Bidi/Text یا Intrinsic Size Failure جدیدی ظاهر شود.
Repair: Conclusion را محدود کنید. این درس Layout-direction Contract را Test میکند، نه کل Internationalization را.
اگر Mutationهای عمدی شما هیچ Failure قابل مشاهدهای تولید نمیکنند، احتمالاً Evidence System ضعیف است یا Mutation به Critical Dimension واقعی وصل نشده است.
برای برنامهنویس باتجربه: CSS را Constraint System ببینید، نه نقاشی Coordinate
اگر Background شما Desktop UI، Native Mobile، Game UI یا Enterprise Formهای قدیمی است، ممکن است CSS Responsive غیرقابل پیشبینی به نظر برسد چون Browser مثل یک Canvas ساده با x/y ثابت عمل نمیکند. Geometry از Interaction چند Constraint حل میشود: Formatting Context، Intrinsic Content، Available Space، Writing Mode، Minimum Size و Author Rules.
یک Mapping مفید:
- Grid Trackها شبیه Constraint Relationship بین Row/Column هستند، نه Position دستی.
- Flex Itemها در Main Axis بر اساس Basis/Grow/Shrink توزیع میشوند.
- Intrinsic Sizing یعنی Child در Geometry Parent نقش دارد.
- Logical Axes یعنی Horizontal/Vertical تنها Coordinate abstraction نیست؛ Inline/Block مهماند.
- Media Query یک State Gate است؛ دلیل State باید خارج از عدد Breakpoint قابل توضیح باشد.
دو خطای رایج Senior Developerها:
Overengineering قبل از فهم Contract
Framework Layout Component، ResizeObserver، Utility abstraction یا Design Tokenهای متعدد اضافه میشود قبل از اینکه معلوم شود Native Grid/Flex چه چیزی را حل نمیکند. این کار Indirection را زیاد میکند و Evidence را سختتر.
اصل این درس: ابتدا Smallest Native Mechanism که Contract را بیان میکند. Abstraction بعداً، اگر Repetition و Product Architecture آن را توجیه کند.
Recipe confidence
Senior Developer میداند min-width:0 خیلی از Bugها را رفع میکند و آن را همه جا میگذارد. ممکن است نتیجه درست شود، اما Skill اصلی این است که Automatic Minimum Boundary را تشخیص دهید و ثابت کنید Rule در Box درست لازم است.
در Code Review به جای Taste Question اینها را بپرسید:
- این Container چه Relationshipی مالک است؟
- Narrow State دقیقاً از چه Constraintی میآید؟
- این Value چرا وجود دارد؟
- Directional Rule Physical است یا Logical؟
- DOM/source sequence چیست؟
- Long Localized Content چه میکند؟
- چه Mutation عمدی اجرا شده؟
- چه Observationی Grid/Flex decision را عوض میکند؟
Abstraction نباید Meaning CSS را پاک کند
مثلاً:
<Stack direction="horizontal" gap="md" collapseAt="tablet" />
API تمیز است، ولی سؤالهای مهم پنهاناند: tablet چه Constraintی است؟ Horizontal Physical است یا Inline-relative؟ Implementation Flex است یا Grid؟ RTL چه میشود؟ Child minimum چیست؟
Abstraction ممنوع نیست. باید Contract را طوری Preserve کند که Evidence هنوز ممکن باشد.
CSS Source و Screenshot هرکدام نیمه Evidence هستند
Static Review میتواند left, right, order, Fixed Width و Breakpointهای بیدلیل را پیدا کند، ولی Runtime Behavior را ثابت نمیکند. Screenshot Layout را نشان میدهد اما Source Order و Cause Sizing را نه.
پس Source Inspection + Rendered Observation + Targeted Mutation را کنار هم استفاده کنید.
Alternativeها و Trade-offها: Mechanism را از Contract انتخاب کنید
Grid در برابر Flexbox
| سؤال | Grid بیشتر مناسب است وقتی… | Flexbox بیشتر مناسب است وقتی… |
|---|---|---|
| Relationship اصلی چیست؟ | Row/Column باید با هم هماهنگ باشند | Distribution در یک Main Axis غالب است |
| Shared Track بین Rowها لازم است؟ | بله | نه، Lineها میتوانند مستقل باشند |
| Wrapping رفتار اصلی است؟ | Track Count/Placement مدل مسئله است | Itemها در Axis Wrap میشوند |
| Region باید Area/Span صریح داشته باشد؟ | معمولاً طبیعیتر است | با Nesting ممکن است اما Core Model نیست |
| یک Item باید Free Space Row را بگیرد؟ | ممکن است | معمولاً مستقیم با Flex Growth |
این جدول Scoreboard نیست. Maintainability، Team Convention، Future Requirement و Browser behavior میتواند تصمیم را تغییر دهد.
Intrinsic Responsiveness در برابر Explicit State
auto-fit/minmax() یا Flex Wrap میتوانند بدون Media Query تعداد Itemها را نسبت به Space تغییر دهند. وقتی Contract واقعاً «هر چند Card که با Minimum Width مشخص جا میشود» است، این رفتار عالی است.
Media Query وقتی مفید است که State فقط Geometry نیست: Filter به Disclosure تبدیل میشود، Header Relationship عوض میشود یا Product Rule جدید داریم.
«بدون Media Query» KPI کیفیت نیست.
Logical در برابر Physical
اگر Intent Flow-relative است، Logical Property مناسبتر است. اگر Requirement فیزیکی است، Physical Property را نگه دارید. مسئله Coordinate System درست است، نه Modern بودن Syntax.
Reordering در برابر Source Restructuring
اگر Visual Design اختلاف زیادی با Meaningful Sequence دارد، Alternativeها را بررسی کنید:
- Source Order را بهبود دهید؛
- Design را با Sequence منطقی هماهنگ کنید؛
- Decorative content را در صورت مناسب جدا کنید؛
- اگر Divergence واقعاً لازم است آن را محدود، مستند و Test کنید.
Interactive Control را صرفاً برای دو Position Duplicate نکنید بدون اینکه State Sync و Relationshipها را بررسی کنید.
Fixed Width در برابر Bounded Flexible Width
Sidebar ثابت ممکن است درست باشد اگر Contract آن را Fix کند. Full-fluid هم ممکن است درست باشد. ابزارهایی مثل minmax, min, max, clamp, flex-basis, min-inline-size, max-inline-size برای بیان Range هستند.
اصل: وقتی Requirement Bounded است، Geometry هم Bounded بیان شود.
Container-based responsiveness
در بعضی Architectureها Component نسبت به Container خودش Responsive میشود نه Viewport. این ایده میتواند Constraint-localتر باشد. Container Query جزو Source Set منجمد این درس نیست، پس وارد Tutorial آن نمیشویم. Transferable principle همان است: Trigger State باید به Space/Constraint مالک Component نزدیک باشد.
Guided Practice و Lab اجرایی
Lab با شناسه WEB010-LAB1 یک Fixture Local از Header و Product Catalog دارد. Starter عمداً چند Failure دارد. وظیفه شما Repair کردن Contract است، نه زیباتر کردن صفحه.
Phase 1 — Contract را قبل از CSS بنویسید
Checkpoint WEB-010-AF1 را کامل کنید.
برای Header، Main Shell، Product Grid و Card Actions بنویسید:
- Source Sequence؛
- Geometry غالب؛
- Minimum Useful Constraints؛
- Direction Intent؛
- Evidence مورد نیاز.
عبارت «Mobile layout» Constraint نیست. آن را با Statement قابل مشاهده جایگزین کنید.
Phase 2 — Baseline Wide LTR
Fixture را در Width عریض باز کنید. قبل از Repair Failureها را ثبت کنید. Baseline لازم نیست Pass باشد.
Inspect کنید:
- Distribution Header؛
- Relation Filter/Results؛
- Card trackها؛
- Viewport Horizontal Overflow؛
- DOM/source order؛
- Physical directional ruleها.
Phase 3 — Narrow Probe
Width را تدریجی کم کنید. مستقیم روی Preset یک Device نپرید. اولین جایی که Contract نامقبول میشود ثبت کنید.
مشخص کنید Failure از کدام Class است:
- Track Geometry؛
- Intrinsic Content؛
- Fixed Sizing؛
- State Requirement؛
- چیز دیگر.
بعد کوچکترین Repair را انتخاب کنید.
Phase 4 — Long Content Mutation
Identifier طولانی را فعال کنید. قبل از Run کردن، WEB-010-AF2 را جواب دهید: پیشبینی Failure و Falsifying Observation.
یک Measurement ساده:
const root = document.documentElement;
console.log({
clientWidth: root.clientWidth,
scrollWidth: root.scrollWidth,
hasHorizontalOverflow: root.scrollWidth > root.clientWidth
});
این فقط وجود Viewport Overflow را میگوید؛ Cause را مشخص نمیکند.
Phase 5 — RTL
Direction را RTL کنید و Wide/Narrow را دوباره اجرا کنید. هر Physical Rule که Intent Flow-relative داشته ولی Mapping غلط شده ثبت شود.
همه left/rightها را Blindly Replace نکنید؛ Rule فیزیکی Legitimate را Explain کنید.
Phase 6 — Visual/Source Order Mutation
Mutation مخصوص Reordering را فعال کنید. Visual sequence، DOM sequence و Default Focus movement Controlهای موجود را مقایسه کنید. Mutation را بردارید و Reason Repair را ثبت کنید.
Phase 7 — Independent Transfer
Transfer Fixture چند Variable را با هم عوض میکند:
- Initial Direction = RTL؛
- Titleها طولانیتر؛
- Filter در Narrow به Disclosure بالای Results تبدیل میشود؛
- Source Sequence باید منطقی بماند؛
- Breakpoint Worked Example نباید Copy شود مگر Evidence مستقل همان Threshold را توجیه کند.
Deliverable همان Evidence Matrix است.
Checker چه چیزی را میتواند ثابت کند؟
Public Checker فقط Packaging، وجود Probeها، ساختار JSON، Required Evidence Fieldها و Completion Flagها را بررسی میکند. Browser Geometry را اجرا نمیکند، درستبودن Semantic یک CSS Mechanism را تعیین نمیکند، نبود Overflow را اثبات نمیکند و Visual/Accessibility Quality را Certify نمیکند. این Claimها باید از Browser/DOM Observation ثبتشده و Evidence Review بهدست بیایند. بنابراین PASS شدن Checker فقط درباره Checkهایی است که واقعاً اجرا کرده، نه جایگزین Observationهای Lab.
Human Observation جزو Evidence باقی میماند.
Verification: Evidence دقیقاً چیست؟
Artifact باید چهار چیز را از هم جدا نگه دارد: Observation، Inference، Decision، Limitation.
Observation
چیزی که واقعاً در Environment ثبتشده دیدهاید:
- «در 420px،
scrollWidth=462وclientWidth=420است.» - «بعد از
dir=rtlفاصله Icon هنوز روی Physical Right باقی مانده چون Rulemargin-rightاست.» - «DOM Filter را قبل از Results دارد اما
orderResults را Visual-first کرده است.» - «با حذف
min-inline-size:0Overflow بازتولید شد.»
Inference
توضیح شما درباره Meaning Observation:
- «نتیجه با این Hypothesis سازگار است که Automatic Minimum Results از Shrink شدن Intended جلوگیری میکند.»
Mutation Targeted این Inference را قویتر میکند، اما هنوز Universal Truth نیست.
Decision
انتخاب Engineering:
- «برای Shell Wide از Grid استفاده میکنیم چون Relationship دو Track صریح است؛ وقتی Minimumهای پذیرفتهشده Fit نمیشوند به یک Column میرویم. داخل Action Group از Flex استفاده میکنیم چون Distribution تکمحوره است.»
Residual Limitation
مرز Evidence:
- «در Browser/Version ثبتشده Test شد؛ Certification همه Browser/ATها نیست.»
- «RTL Layout spacing تست شد؛ Mixed-script bidi خارج از Scope بود.»
- «Default focus sequence مشاهده شد؛ Custom keyboard behavior تست نشده است.»
Minimum Scenario Matrix
| Width | Direction | Long Content | Order Mutation | هدف |
|---|---|---|---|---|
| Wide | LTR | Off | Off | Baseline |
| Narrow | LTR | Off | Off | Responsive State |
| Narrow | LTR | On | Off | Intrinsic/Overflow Probe |
| Wide/Narrow | RTL | Off | Off | Logical Direction Probe |
| Narrow | RTL | On | Off | Combined Changed Context |
| یک State منتخب | هرکدام | Off | On | Visual/Source Order Detection |
این Minimum است، نه Maximum.
Automation بدون False Authority
Script میتواند Observable محدود اندازه بگیرد: scrollWidth, clientWidth, Computed Style یا Source Sequence. خطر وقتی است که Result محدود به Claim بزرگتر تبدیل شود.
به جای Test مبهم مثل:
responsive_ok = true
Testهای Claim-specific بهترند:
no_viewport_horizontal_overflow_at_420px
filter_precedes_results_in_source
rtl_inline_spacing_maps_to_expected_computed_side
order_mutation_is_detected
Final Evidence Gate
قبل از Completion:
- دلیل Layout Model هر Container را میتوانم توضیح دهم؟
- Constraint واقعی هر State را میدانم؟
- Long Content را تست کردهام؟
- Direction را عوض کردهام؟
- Source Order را جدا از Visual Order Inspect کردهام؟
- یک Mutation عمدی Failure قابل انتظار ساخته؟
- Repair بدون Rewrite نامرتبط Contract را برگردانده؟
- Observation و Inference جدا هستند؟
- Limitation ثبت شده؟
- Transfer مستقل انجام شده؟
هر No در Dimension بحرانی یعنی Artifact ناقص است.
Assessment و Transfer
Assessment این درس Syntax Quiz نیست. حفظ بودن اسم grid-template-columns یا flex-grow مهارت را ثابت نمیکند.
S1 — Retrieval
یک Rule محدود برای Grid/Flexbox بنویسید و توضیح دهید Breakpoint چرا باید از Content/Layout Constraint بیاید. یک Non-claim اضافه کنید تا Rule به Universal Winner تبدیل نشود.
S2 — Application
Fixture اصلی را در Wide/Narrow و LTR/RTL Repair کنید. Evidence Matrix کامل لازم است. چون Lesson اجرایی است، Prose بدون Working Artifact Skill را ثابت نمیکند.
S3 — Diagnosis
در یک Flex Layout تغییریافته، Code Sample داخلی با Token طولانی باعث میشود Content Pane انعطافپذیر از Container عریضتر شود. قبل از Repair، Automatic Minimum مربوط به Flex Item، Breakability محتوا و Fixed Descendant را بهعنوان Hypothesisهای جدا بررسی کنید؛ Observation ردکننده Leading Diagnosis را بنویسید و بعد کوچکترین Test Repair را انتخاب کنید.
S4 — Decision
Header One-axis distribution میخواهد و Main Shell Track Alignment مشخص. Mixed Grid/Flex یا Alternative منسجم را دفاع کنید و Trade-off و Decision-changing Evidence بدهید.
S5 — Independent Transfer
Catalog جدید از RTL شروع میشود، Localized Content طولانیتر است و Narrow Filter رفتار متفاوت دارد. Source Sequence را حفظ کنید، Critical Horizontal Overflow نداشته باشید، Mechanism را از Constraint انتخاب کنید، Mutation عمدی و Repair اجرا کنید و Limitation ثبت کنید.
Worked Example را Copy نکنید؛ Method را Transfer کنید.
Remediation
- Failure در S1 → Mental Model + Foundation؛
- Failure در S2 → Worked Example + Evidence؛
- Failure در S3 → Intrinsic Sizing + Failure Modes؛
- Failure در S4 → Alternatives/Trade-offs؛
- Failure در S5 → Critical Dimension شکستخورده را جدا کنید و همان را Repair کنید.
Remediation نباید Final Stylesheet Canonical را Reveal کند. Engineering Judgment باید برای Learner باقی بماند.
Standards، Freshness و مرز ادعاها
این درس فقط به سه Source رسمی قفل است و هرکدام Usage محدود دارد.
CSS Grid Layout Module Level 2 — S-CSS-GRID2
Source: https://www.w3.org/TR/css-grid-2/
برای این Claim محدود استفاده میشود که Grid برای Relationshipهای دوبعدی Layout طراحی شده و Visual Placement/Reordering جای Source Order صحیح را نمیگیرد. این Technical Report روی Draft/Recommendation Track است و میتواند تغییر کند؛ بنابراین Detailهای آن Review-dated هستند.
CSS Flexible Box Layout Module Level 1 — S-CSS-FLEX1
Source: https://www.w3.org/TR/css-flexbox-1/
برای Axis-oriented Distribution/Alignment و تفکیک Visual Order از Source/Speech/Sequential Navigation استفاده میشود. این Source نمیگوید هر Layout ظاهراً تکبعدی حتماً باید Flexbox باشد.
CSS Logical Properties and Values Module Level 1 — S-CSS-LOGICAL1
Source: https://www.w3.org/TR/css-logical-1/
برای Mappingهای Writing-mode-relative مثل Inline/Block Start/End استفاده میشود. این Source مجوز ادعای «Logical Properties همه RTL/Bidi/i18n را حل میکنند» نیست.
Non-claimهای اجباری
- Grid همیشه بهتر از Flexbox نیست و برعکس.
- Responsive Design لیست Universal از Breakpointهای Mobile/Tablet/Desktop ندارد.
- CSS Visual Reordering ترتیب DOM/source را Rewrite نمیکند.
- Logical Properties تمام مسائل RTL/Bidi را حل نمیکنند.
- Screenshot موفق Proof کامل Responsive Contract نیست.
- Observation یک Browser Universal certification نیست.
Freshness Boundary
Method این درس—Contract، Constraint، Mechanism، Changed Context، Mutation، Evidence—نسبتاً Stable است. Specification wording و Browser behavior میتوانند تکامل پیدا کنند. وقتی Review Due برسد، Source تغییر Material داشته باشد یا Fixture در Standards-capable Browser رفتار متفاوتی نشان دهد، Re-review لازم است.
اگر فقط یک جمله از این Lesson نگه میدارید، این باشد:
Responsive CSS یعنی بتوانید توضیح دهید چه Relationshipی را پیاده میکنید، چرا Layout در یک Constraint خاص State عوض میکند، Direction چگونه Intent را Mapping میکند، Source Order چگونه محافظت میشود و چه Evidence واقعی نتیجه را در Context تستشده ثابت میکند.
ارزیابی
پاسخنامهی این درس در بستهی آموزش وجود ندارد؛ خودت جواب بده و صادقانه علامت بزن. «نیاز به مرور» درس را به صف تکرار میفرستد.
WEB-010-S1 retrieval
یک قاعده محدود و قابل دفاع برای انتخاب Grid در برابر Flexbox بنویسید؛ سپس توضیح دهید چرا breakpoint باید به constraint واقعی محتوا/layout متصل باشد نه نام دستگاه. یک non-claim صریح هم ثبت کنید.
WEB-010-S2 application
fixture مربوط به product-list/header را طوری پیادهسازی کنید که در state عریض/باریک و هر دو جهت LTR و RTL کار کند. Responsive Layout Evidence Matrix v1 را با layout model هر ناحیه، constraint ایجادکننده تغییر state، استفاده از Logical Properties، evidence مربوط به overflow و source order کامل کنید.
WEB-010-S3 diagnosis
یک Settings Workspace از Flex Row برای Navigation و Content Pane استفاده میکند. در عرض باریک، یک Code Sample داخل Pane با Token طولانی و بدون Break باعث میشود Row از Container عریضتر شود، با اینکه Pane بهصورت Flexible تعریف شده است. قبل از Repair، Failure را Diagnose کنید: Automatic Minimum مربوط به Flex Item، Break Behavior محتوای داخلی و هر Fixed Descendant Constraint را از هم جدا کنید؛ یک Observation بنویسید که Leading Diagnosis شما را رد کند و کوچکترین Repair اولیه را مشخص کنید.
WEB-010-S4 decision
یک header شامل brand، search field و actionهاست. header عمدتاً توزیع تکمحوره میخواهد، اما body باید alignment پایدار بین filter و results column داشته باشد. یک تصمیم ترکیبی Grid/Flex یا یک alternative تکمدلی را دفاع کنید و trade-off، قاعده جهت منطقی، و evidence تغییردهنده تصمیم را بنویسید.
WEB-010-S5 transfer
یک catalog تغییرکرده را مستقل repair کنید: filter در عرض باریک به disclosure بالای results تبدیل میشود، عنوان کارتها متن محلیشده و طولانی دارند و document از RTL شروع میشود. ترتیب اصلی DOM/source را حفظ کنید، layout mechanism را از constraintها انتخاب کنید، overflow افقی بحرانی نداشته باشید و evidence matrix کامل شامل یک mutation عمدی و نتیجه repair شده تحویل دهید.
ملاکهای ارزیابی (rubric)
Critical dimensions
- Contract correctness: mechanism choice is tied to the actual layout geometry and content constraints.
- Evidence quality: observations, mutations, repairs, width/direction states, and residual limitations are traceable.
- Direction correctness: logical start/end intent is not silently encoded as physical left/right without justification.
- Order integrity: visual rearrangement does not substitute for correct source/DOM order.
- Transfer independence: the changed-context case is solved without copying a decisive worked-example answer.
Decision rule
A passing implementation may use different CSS from the worked example. It fails if a critical dimension is unsupported, hidden by visual-only proof, or repaired by violating source-order/direction boundaries. AI-generated prose is not execution evidence.
منابع و تازگی
مطالعهٔ موارد (case studies)
فایلهای آزمایشگاه
هدف
fixture مربوط به فهرست محصول را در constraint عریض و باریک و در هر دو جهت ltr و rtl اصلاح و از تصمیم خود دفاع کنید. هدف فقط «خوب دیدهشدن» صفحه نیست. باید یک تصمیم layout محدود و قابل دفاع بگیرید، رفتار واقعی Browser/DOM را مشاهده کنید، یک failure mutation عمدی اجرا کنید، آن را repair کنید و evidence را در Responsive Layout Evidence Matrix v1 ثبت کنید.
وضعیت شروع
Starter عمداً کامل نیست و چند انتخاب ظاهراً معقول اما ناامن دارد. کل fixture را با framework یا صفحهای کاملاً متفاوت جایگزین نکنید. در همین مرز محدود کار کنید تا evidence قبل و بعد از repair قابل مقایسه بماند.
Starter عمداً به شما نمیگوید کدام ناحیه باید Grid یا Flexbox باشد، مقدار دقیق breakpoint چه باشد یا کدام declaration تنها repair صحیح است. این تصمیمها باید از constraint واقعی layout و مشاهده شما بهدست بیایند.
Stateهای اجباری
حداقل این چهار حالت را بررسی کنید:
- عریض +
ltr - باریک +
ltr - عریض +
rtl - باریک +
rtl
برای تغییر جهت از کنترل داخل صفحه استفاده کنید. عرض Browser یا container را تغییر دهید و نام یک دستگاه را علت breakpoint در نظر نگیرید.
Failure Probeهای اجباری
هر سه probe را اجرا کنید و قبل از مشاهده، نتیجه را پیشبینی کنید.
- Long identifier را فعال کنید. بررسی کنید آیا intrinsic/min-content sizing باعث horizontal overflow بحرانی میشود و boundary ایجادکننده مشکل کجاست.
- بین
ltrوrtlجابهجا شوید. بررسی کنید spacing و placement واقعاً intent منطقی start/end را بیان میکند یا به left/right فیزیکی وابسته است. - Visual reorder mutation را فعال کنید. visual sequence را با DOM/source sequence مقایسه کنید. semantic source order را با visual reordering «تعمیر» نکنید.
Evidence اجباری
فایل Responsive_Layout_Evidence_Matrix_v1_template.json را به فایل evidence کاری خود کپی کنید و این موارد را ثبت کنید:
- region و source-order contract؛
- layout problem واقعی؛
- chosen model و rationale محدود آن؛
- constraint ایجادکننده responsive state؛
- تصمیم مربوط به Logical Properties؛
- overflow و visual order مشاهدهشده؛
- DOM/source order و default focus sequence مشاهدهشده؛
- یک mutation عمدی و نتیجه واقعی آن؛
- کوچکترین repair آزمایششده و نتیجه واقعی repair؛
- یک residual limitation؛
- نتیجه یک changed-context transfer مستقل.
Observation را از Inference/Decision جدا نگه دارید.
مرز پذیرش
یک submission قوی، بدون لو دادن answer key پنهان، این موارد را اثبات میکند:
- در stateهای repairشده، critical horizontal overflow وجود ندارد؛
- تغییر direction نیازمند stylesheet جداگانه left/right نیست؛
- ترتیب منطقی DOM/source قابل دفاع باقی میماند؛
- انتخاب Grid/Flex/normal flow از geometry مسئله میآید نه عادت؛
- حداقل یک failure mutation واقعاً مشاهده و repair شده است؛
- transfer fixture بهصورت مستقل حل شده است؛
- حداقل یک residual limitation ثبت شده است.
اجرای محلی
فایل starter/index.html را در یک Browser استاندارد باز کنید. Network، package manager، build system، server، account یا credential لازم نیست.
run_checks.py فقط Public Structural/Evidence Check انجام میدهد: Required File/Probe، اعتبار JSON، همه Fieldهای Public Row Contract و Completion Flagها. Browser Geometry را اجرا نمیکند، درباره Semantic Correctness خود CSS حکم نمیدهد و Hidden Expected Solution را در خود ندارد.
فرمان Public Checker
از همین پوشه learner/ پیش از ویرایش python run_checks.py --structure-only را اجرا کنید. پس از تکمیل evidence/learner_evidence.json، فرمان python run_checks.py را اجرا کنید. Checker همچنان فقط Structural/Evidence Check است و مشاهدههای Browser باید توسط فراگیر ثبت شوند.
رسانه و اسلایدهای درس
فایلهای آموزشی (دانلود)