شاید تا کنون HTML را نادرست به کار میبردید! – بخش یکم
من دههی گذشته را به عنوان مشاور دسترسی پذیری و بهرهوری، صرف کار آزاد برای صاحبان سایتهایی کردهام که یا دچار مشکلهای شدید قانونی شده بودند، یا به دلیل تصمیمهای بد در توسعه، نیاز به پهنای باند زیادی پیدا کرده بودند. در آن زمان، یکی از درگیریهای همیشگی من با کارمندان markup ،IT دور ریختنی آنها بود؛ که اگر رک بگویم، بیشتر توسعه دهندگان در طرز فکر سال 1997 گیر کرده بودند. بیشتر اینها ریشه در این حقیقت دارد که همهی فریمورکهای front-end، به دست افرادی ساخته و نگهداری شدهاند که شایستگی نوشتن یک خط HTML را ندارند.
Semantic Markup : یک نامگذاری ناجور
این اصطلاح تنها و تنها به این دلیل ساخته شد تا مایهی رنجش نادانهایی نشود که از HTML نادرست استفاده میکنند و هنوز نسخهی تاریخ مصرف گذشته و از مد افتادهی markup نمایشی HTML3.2 را به کار میگیرند. حتی با وجود اینکه DOCKTYPE متعلق به HTML5 را در بالای صفحه میآورند و از یکدیگر تعریف میکنند که چقدر «مدرن» هستند.
هر چند که semantic markupقطعاً واژهی درستی است، زیرا به معنای به کار بردن تگهای HTML برای معنای آنها، به جای ظاهر پیشفرضشان است، اما چیزی که واقعا باید از آن برداشت کنند «به کار بردن درست HTML» است. همهی دلیلی که HTML دارای تگ است، برای شیوهی نمایش آن نیست، بلکه برای این است که بگوییم در یک document حرفهای، هر چیزی چه معنایی دارد یا باید داشته باشد.
چرا گفتن اینکه هر چیزی چه ماهیتی «دارد یا باید داشته باشد»، آنقدر مهم است؟
زیرا مبنای markup شما قرار نیست تنها برای آنهایی باشد که با بینایی خوب، روبروی یک نمایشگر مینشینند. از روز نخست، دلیلی که HTML بر آن بنا شد، انتقال documentها و اطلاعات، با وجود محدودیتهای دستگاه مقصد یا حتی ناتوانیهای کاربر بود.
Tim Berners-Lee، HTML را به عنوان انتقال دهندهای بینیاز از نوع دستگاه ساخت. در روزهای نخستِ اینترنت، دهها دستگاه کاملا متفاوت وجود داشتند که نیاز به راهی یکسان برای مخابرهی داده داشتند، و همچنین باید میتوانستند شیوهی نگارش حرفهای یک نوشته را حفظ کنند. اهمیتی نداشت که اگر دستگاه مقصد یک Teletype در CIA، یک دستگاه TTY برای نابینایان، یک چاپگر چرخ آفتابگردان(daisy wheel printer)، نمایشگر متن 21*22 VIC-20 لینوس توروالدز یا نمایشگر 40*25 روی یک APPLE II در برخی از دبیرستانها میبود. بسیاری از این دستگاهها حتی نمیتوانستند bold، italic یا طرح گرافیکی را نشان دهند. ممکن است بگویید که چرا چیزی باید یک قالب مشخص داشته باشد، دلیل این است که user-agant (دقت کنید که یک مرورگر یک user-agant است، اما یک user-agant همواره یک مرورگر نیست) بتواند بهترین راه را برای شیوهی انتقال آن، با توجه به محدودیتهای دستگاه پیدا کند.
آن دوران به هیچ وجه مشابه امروزه نبود که همهی افراد نمایشگرهایی دقیقا یک اندازه با رزولوشن دقیقا یکسان، با font stackهایی دقیقا یکسان، موتور رندر فونت دقیقا یکسان، در font-size پیشفرض و PPI(pixels بر inch) دقیقا یکسان به کار ببرند. برای کسانی که موضوع را نگرفتند، این یک طعنه بود.
HTML پایهی دسترسیپذیری است. ساخته شده تا با آن نوشتههای دسترسی پذیر ایجاد شود. documentهای درست و اصولی HTML، تنها برای آنهایی که با بینایی خوب، روبروی یک نمایشگر نشستهاند نیست!!! برای کسانی است که صفحهخوانها (نرمافزاری که محتوای صفحه را بلند میخواند)، نمایشگرهای بریل(Braille reader)، TTY، چاپگر... را به کار میبرند، و حتی برای موتورهای جستجو که چشم ندارند و نباید به style شما اهمیتی بدهند!
در حقیقت موتورهای جستجو style را تنها برای تشخیصِ سو استفاده – مانند content cloaking – و سازگاری با موبایل بررسی میکنند. آنها میتوانند هیچ اهمیتی به ساختار و چینش صفحههای شما ندهند.
پس چگونه آن را «نادرست به کار میبریم»؟
کاربردهای نادرست، برآمده از بد فهمیهای مختلف و همچنین پیادهسازیهای نادرستی است که افراد برای markup خود برمیگزینند.
Markup نمایشی
بیشتر شما به نظر میرسد که هنوز تگهای خود را بر پایهی ظاهر پیشفرض آن انتخاب میکنید، نه معنای آن. دوباره تکرار میکنم، همانگونه رفتار میکنید که در گذشته، خیال میکردند HTML3.2 نقطهی عطف تکنیکهای توسعه بود. جالب است که بیشتر چیزهایی که از دورههای قبل وارد HTML3.2 شدند، دور ریختنیهایی نمایشی بودند و دلیلی که HTML از نخست بر پایهی آن ساخته شد را نقض میکردند.
H1 تا H6 را در نظر بگیرید. اینها معنای شروع بخشها یا زیربخشها را دارند. H1 قرار است یگانه headingای باشد که همهی محتوای سایت زیربخش آن باشد. و تگ «section» در HTML5 که تلاش میکند این را تغییر دهد، تنها کار را بدتر میکند. بنابراین، عنوان یا لوگوی سایت احتمالا نزدیکترین گزینه برای قرار گرفتن در تنها H1ای است که باید در صفحه داشته باشید. یک H2، شروع زیربخش بزرگی از صفحه را نشان میدهد، با نخستین H2، آغاز محتوای اصلی را نشان میدهید. که تگ «main» را به تگی اضافی و بیهوده تبدیل میکند. یک H3 آغاز زیربخشی را نشان میدهد که پیشتر با H2 آغاز شده بود. که هر دوی «section» و «article» را اضافی و بیهوده میکند. یک H4 آغاز زیربخشی را نشان میدهد که پیشتر با H3 آغاز شده بود. حدس بزنید H5 و H6 چه معنایی میدهند! حتی HR به معنای «تغییر در موضوع یا بخش است که عنوانی برای آن نیازی نیست یا نا به جا است».
اینها به معنای فونت در اندازهها و وزنهای مختلف، یا کشیدن یک خط افقی نیستند!!!
به همین دلیل است که نباید از مرتبههای heading بپرید، به H5 بروید بدون اینکه H4ای داشته باشید تا زیربخش آن باشد. به همین دلیل است که نباید document خود را با یک H4 آغاز کنید. به همین دلیل است که جفت کردن H1 و H2 برای عنوان و زیرعنوان سایت، افتضاحی ناشی از نادانی است. و این دلیل دیگری است بر اینکه کسانی که در WhatWG هستند، به وضوح برای نوشتن جایگزین HTML4 Strict شایستگی ندارند، چرا که به نظر میرسد حتی نمیدانند headingها به چه دلیل وجود دارند. به تگ احمقانه و بیمعنی HGROUP نگاه کنید که W3C پس از ماهها آن را در specification، منسوخ شده دانست.
به همین ترتیب، P برای یک پاراگراف دستوری است. نه برای یک تکهی تصادفی از یک جمله در یک جایی، نه برای یک تصویر تنها، نه برای یک جفت LABEL و INPUT، نه به این دلیل که «من یه margin دور این المان میخوام». درست به همین ترتیب UL یا OL برای نقطههای گلولهای(Bullet points) دستوری است، نه برای اینکه «من میخوام قبلشون نقطه باشه» و نه برای sectionهای بزرگی که نیاز به heading دارند. (زیرا headingها semantic مشابهی را پیاده میکنند. اغلب semantic اضافی برای user-agantهای غیر نمایشی، بدتر از نبودن آن است)
حتی تگهای کم کاربرد B/CITE/EM/I/STRONG، جدا از شیوهی نمایش پیشفرضشان، دارای معنا هستند. این جا، جایی است که «دلم میخواد» خودش را نشان میدهد. شما نباید هیچ یک از این تگها را به این دلیل که «من میخوام متن bold یا italic باشه» انتخاب کنید. جای آن، باید بر این پایه که چرا میخواهید متن bold یا italic باشد آنها را انتخاب کنید.
برای گزینش تگهای گفته شده، دلایل دستوری وجود دارد.
<em> - تاکید
<strong> - تاکید بیشتر
<cite> - استنادی که برای یک عبارت یا پشتوانه از کاری ارائه میدهید
<i> - هنگامی که یک دلیل دستوری برای خمیده(italic) کردن داریم منتها شامل CITE و EM نمیشوند، مانند عنوان کتاب یا نام documentای که به آن اشاره میکنید.
<b> - همانند ایتالیک است، منتها برای وقتی که متن به دلایل دستوری باید bold باشد، مانند نهادی در یک سند حقوقی
اگر نتوانید برای به کار بردن هر کدام از تگهای semantic– در واقع همهی تگهایی که داخل BODY به کار میروند، به جز SPAN ،DIV و A – دلیل دستوری یا ساختاری پیدا کنید، در این صورت احتمالا نباید تگ semantic را به کار ببرید.
از این رو، گفته میشود که:
اگر هر کدام از تگهای semantic را برای شیوهی نمایش آنها به کار ببرید، در این صورت تگهای نادرستی را برای دلایل نادرستی به کار میبرید.
ین مثال را در نظر بگیرید که یکی از دوستان من یک دهه و نیم پیش نوشت، و مانند گذشته فراخور امروزه نیز است.
<p>
<i>GURPS,</i> <b>Steve Jackson Games'</b> flagship role-playing game, was first released in 1985. Several licensed adaptations of other companies' games exist for the system, such as <i>GURPS Bunnies and Burrows.</i> However, <b>SJ Games</b> has no connection with <b>Wizards of the Coast</b>, producers of the <i>Dungeons and Dragons</i> RPG. <em>No <i>GURPS</i> content is open-source.</em> <strong>Do not plagiarize <b>SJ Games</b> work!</strong>
</p>
در ضمن، دلقکهایی که هنوز طوطیوار میگویند «همیشه EM و STRONG را به کار ببرید» و «B و I منسوخ شده هستند» از روی شکمشان حرف میزنند، و واقعا باید ساکت باشند!
به همین ترتیب، TABLE برای دادههای جدولی است. این دادهها برای زمانیاند که ستونها و سطرها یک ارتباط semantic دارند.
بله، به کار بردن «جدولها برای layout» بد است. نباید با این منطق که «من ستون میخوام» از table استفاده کنید. در عین حال، دیگر تگها – مانند لیستها – را برای دادههایی که به وضوح نیاز به جدول دارند، به کار نبرید.
جدولهای گفته شده همچنین باید «به خوبی ساخته شده باشند»، به این معنا که هم در THEAD و هم در TBODY دارای heading باشند، همراه با SCOPE و AXIS که ارتباط آنها را ایجاد میکند. اگر جدول headingای دارد که برای آن COLSPAN را به کار نمیبرید، پس باید CAPTION را به کار ببرید. تگهای دیگری جز TR و TD هستند که داخل table قرار میگیرند، اما متاسفانه بیشتر کسانی که HTML مینویسند این مطلب را نمیدانند.
یک سبد خرید عادی را در نظر بگیرید که اغلب افتضاح دور ریختنیای مانند کد زیر را میبینید:
<table class="cart">
<tr class="title">
<td colspan="4"><b>Shopping Cart</b></td>
</tr><tr class="headers">
<td><b>Item</b></td>
<td><b>Quantity</b></td>
<td><b>Unit Price</b></td>
<td><b>Total</b></td>
</tr><tr>
<td>Rovner Eddie Daniels II Ligature</td>
<td>1</td>
<td>21.99</td>
<td>21.99</td>
</tr><tr>
<td>Yamaha 5C Alto Sax Mouthpiece</td>
<td>1</td>
<td>28.99</td>
<td>28.99</td>
</tr><tr>
<td>Vandoren #3 Alto Sax JAVA Reeds, Box of Ten</td>
<td>2</td>
<td>32.99</td>
<td>65.98</td>
</tr><tr class="footer">
<td colspan="3" align="right"><b>Shipping</b></td>
<td>
Free<br>
<i>For orders over $50</i>
</td>
</tr><tr class="footer">
<td colspan="3" align="right"><b>Total</b></td>
<td><b>116.96</b></td>
</tr>
</table>
اگر HTMLای را مانند نمونهی بالا ببینید، در واقع به کدی نگاه میکنید که نویسندگان آن، شایستگی نوشتن tableها را ندارند. نخستین TR و TD باید CAPTION باشند. TR دارای کلاس header باید داخل یک THEAD باشد، که با TH دارای ”SCOPE=”COL پر شده باشد، زیرا اینها ستون را توصیف میکنند. TR که محتوا است، باید داخل TBODY باشد و نخستین TD آن، یک TH باشد که دارای ”SCOPE=”ROW است، زیرا اینها سطر را توصیف میکنند. دو TR نهایی که دارای کلاس footer هستند، باید با TH داخل TFOOT باشند. هیچ کدام از تگهای bold نباید وجود داشته باشند و آن یگانه تگ italic نیز باید EM(به معنای تاکید) باشد. حتی ویژگی ALIGN نیز دور ریختنی است، زیرا مربوط به شیوهی نمایش (presentation) است (و همچنین منسوخ شده است و در وبسایتهای جدید به کار برده نمیشود)، موردی است که اصلا وظیفهی HTML نیست. همچنین، تا زمانی که برای تگ TABLE یک کلاس تعریف شده است، تگهای داخلی نیاز به تعریف کلاس ندارند، زیرا با استفاده از selectorها و combinatorها میتوان به آنها دسترسی داشت.
کد بالا – برای semantic و دسترسی پذیری درست – باید به شکل زیر باشد:
<table class="cart">
<caption>Shopping Cart</caption>
<thead>
<tr>
<th scope="col">Item</th>
<th scope="col">Quantity</th>
<th scope="col">Unit Price</th>
<th scope="col">Total</th>
</tr>
</thead><tbody>
<tr>
<th scope="row">Rovner Eddie Daniels II Ligature</th>
<td>1</td>
<td>21.99</td>
<td>21.99</td>
</tr><tr>
<th scope="row">Yamaha 5C Alto Sax Mouthpiece</th>
<td>1</td>
<td>28.99</td>
<td>28.99</td>
</tr><tr>
<th scope="row">Vandoren #3 Alto Sax JAVA Reeds, Box of Ten</th>
<td>2</td>
<td>32.99</td>
<td>65.98</td>
</tr>
</tbody><tfoot>
<tr>
<th scope="row" colspan="3">
Shipping<br>
<em>Free for orders over $50</em>
</th>
<td>0</td>
</tr><tr>
<th scope="row" colspan="3">Total</th>
<td>116.96</td>
</tr>
</tfoot>
</table>
در ضمن، اکنون HTML5 میگوید که TFOOT باید پس از TBODY قرار بگیرد. من میگویم که این ترتیبِ اشتباهی است، زیرا دلیل برعکس بودن آن را فراموش کردهاند (در HTML4 ترتیب به این صورت بود:THEAD، TFOOT و TBODY. زیرا این ترتیب،User Agentها را قادر به پشتیبانی از scroll در محتوا یا همان TBODY میساخت، جدا از head یا foot آن جدول)، اما از WhatWG چه توقعی میتوان داشت! هر چه میگذرد، بیشتر به نظر میرسد که آنها شایستگی ساختن جایگزین HTML4 Strict را نداشتند و برای W3C احمقانه بود که به این سادگی آن را بپذیرد.HTML5 اغلب یادآور بازسازی بدترینهای HTML3.2 و پیاده سازی طرز فکرِ «به جای کاری که افراد باید انجام بدن، هر چی مرورگرها پشتیبانی میکنن رو document کنیم» است. همچنین، به ضد «specification» نیز شناخته میشود. برای آنهایی که متوجه نشدند، این بخش از نوشته که خمیده(italic) شده است، از دیدگاه دستوری/ادبی/ساختاری در واقع یک ASIDE برشمرده میشود؛ این تنها دیدگاهی است که برای HTML اهمیت دارد، زیرای به معنای «انتقال نوشتهها به یک طرف» نیست.
به هر ترتیب، مثال دوم همهی پیوندهایی را پیاده میکند که باعث میشود table در دسترسیپذیری نلنگد، و در واقع برای صفحهخوانها (screen reader)، بریلخوانها (braille reader) و امثال اینها نیز مفید است. همچنین، (با تگهای بیشتر و ساماندهی شده) انتخابهای بیشتری را برای style دادن ارائه میدهد، بدون اینکه با تعریف کلاس برای هر تگی، markup را خراب کند.
براستی، چند نفر از شما واقعا جدولیهایی مانند نمونهی دوم دیدهاید؟ با پیادهسازی کامل headerها و scopeها؟ کاربرد درست سه تگ THEAD، TBODY، و TFOOT. چه تعداد از شما حتی از وجود تگ CAPTION آگاه بودید؟
با نبود آنها، جدول از دید دسترسیپذیری میلنگد. کاربرد نادرست دیگر تگها برای انجام همین کار، بی معنی و در واقع دَک کردن بسیاری از مراجعه کنندگان است.
کلاسهای نمایشی
این یک مرض رایج بین همهی frameworkهای چرندی است که اکنون معروف و بر سرزبانها هستند، حتی با این که به وضوح به دست کسانی ساخته شدهاند که هیچ سر و کاری با نوشتن HTML و CSS ندارند، چه برسد به آنکه به دیگران نیز بگویند چگونه بنویسند. به کار بردن کلاس برای این که بگوییم المانها چه ظاهری باید داشته باشند، اشتباه است!
انجام این کار در markup برابر با به کار بردن همهی آن تگهای نمایشی است که در سال 1998 و با آمدن HTML4 واقعی (به Strict نیز معروف است) منسوخ شد.
شاید تفاوتی جزئی بین طرز فکر این دو باشد:
<div class="w3-center w3-silver w3-xlarge">
<center><font color="silver" size="+3">
در کدنویسی به این شیوه که کلاسها را به دلایل نمایشی در آن بریزید، در مقابل با دلیلی رفتار میکنید که باعث منسوخ شدن تگهایی مانند FONT و CENTER شد، و همچنین در مقابل با دلیلی که باعث ساخت دوبارهی HTML در نسخهی Strict، چهار شد که در تلاش برای جلوگیری از تکرار دو دههی قبل بود.
به کار بردن کلاسها برای این که بگوییم ظاهر قرار است به چه شکل باشد اشتباه است، زیرا همهی هدف CSS این است که امکانِ داشتن چند نوع شیوهی نمایش را به یک markup بدهد. HTML «ایدهآل» باید بینیاز از تغییر، یا نیازمند کمترین میزان تغییر برای یک پوستهی سراسر تازه باشد، تنها با ایجاد یک stylesheet تازه. این باید شما را قادر به داشتن چند گونه stylesheet برای دستگاههای رسانهای مختلف کند – از جمله aural، projection ،print و دیگر موارد. چه میخواهید بکنید اگر المانی داشته باشید که دارای ”class=”text-red است، اما در یک پوستهی دیگر آبی باشد؟
حتی اگر بخواهید مفهوم مدرنتری مانند تغییر بین روز و شب را پیادهسازی کنید، بیشتر مشکلساز خواهد بود.
HTML شما برای این است که بگویید چه چیزی دارید، یا باید داشته باشید، یا اینکه چرا ممکن است یک style دریافت کنند. این موضوع باید در classها و idها نیز گسترش یابد، بنابراین، اگر کلاسهای نمایشی را به کار میبرید، یا میخواهید از آن دفاع کنید، لطفا همین الان شکست خود را بپذیرید و برگردید به نوشتن HTML3.2.