Потребность в семантической структуре HTML5 и CSS

У меня есть веб-страница, такая как следующая:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Title</title>
    </head>
    <body>
        <header>
            <span>Logo</span>
            <nav>Navigation</nav>
        </header>
        <main>
            <h1>Page heading</h1>
            <div>
                Page content
            </div>
        </main>
        <footer>
            Content information
        </footer>
    </body>
</html>

Структура страницы похожа на один пример в текущем черновике HTML5: http://www.w3.org/html/wg/drafts/html/master/grouping-content.html#the-main-element, и я думаю, что это семантически правильно.

Теперь я хотел бы создать этот документ с помощью CSS. Я хотел бы быть заголовком сверху и снизу внизу, что, конечно же, легко выполнимо. Внутри заголовка я хотел бы поместить логотип вправо и навигацию по центру, что также хорошо (например, используя гибкую модель макета коробки, которая в том или ином виде поддерживается современными браузерами, или с помощью поплавки).

Мои проблемы начинаются, когда я хочу нарисовать основной заголовок содержимого (элемент h1) визуально слева от заголовка. Я мог бы сделать с позицией: абсолютный, но такой макет не очень гибкий и сломался, как только изменились заголовок или размеры заголовка. Предложенная компоновка сетки CSS http://www.w3.org/TR/css3-grid-layout/ может выполнять именно то, что я хочу, но она, насколько мне известно, поддерживается только (как-то ) в IE 10.

Одним простым и рабочим решением будет просто реструктурировать мою страницу:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Title</title>
    </head>
    <body>
        <div>
            <h1 id="heading">Page heading</h1>
            <header>
                <span>Logo</span>
                <nav>Navigation</nav>
            </header>
        </div>
        <main aria-labelledby="heading">
            <div>
                Page content
            </div>
        </main>
        <footer>
            Content information
        </footer>
    </body>
</html>

Однако это решение, хотя и легко макетируемое, имеет свою полную семантику, выраженное только через атрибуты aria- * и, похоже, противоречит духу семантики HTML5 (особенно основного элемента).

В то время как моя примерная страница может быть простой, вы можете легко представить себе более сложную, где визуальная позиция многих других элементов находится не в том же порядке, что и порядок потока разметки HTML5 (и вложен, чтобы гибкая компоновка ящика свойство заказа не будет достаточным). Как бы вы решили проблему? Перепишите разметку HTML5 с не семантическими элементами (например, divs), чтобы она соответствовала визуальному расположению и затем заменила не семантические элементы семантическими (например, нижним колонтитулом или основным), где это возможно, с новой структурой?

Ответ 1

Я сталкиваюсь с той же загадкой, что и вы, и я ценю разочарование. Я попробую отрицательный ответ, потому что я чувствую, что оба этих положительных (которые говорят, что вы можете достичь обоих своих целей) не имеют смысла.

Во-первых, как я его вижу, ваша основная трудность заключается в том, что CSS не может перемещать элемент в новый контейнер. Два ответа делятся на две категории:

  • Некоторые из них представляют собой ультра-специфические хаки (субъективно говоря), включающие поплавки, отрицательные поля и/или абсолютное позиционирование, которые могут перемещать элемент из своего контейнера. Они могут быть эффективными, но только в очень конкретных случаях. По мере роста ваших потребностей его трудно поддерживать, и для этого необходимо положить достаточно большой объем мышления для решения каждой новой необходимости или краевого случая, который вы пропустили ранее. Ответ @jennifit пытается переместить вас в этом направлении. Это, я считаю, нормальный маршрут, те стараются следовать духу семантической HTML5, которая достойна восхищения. Но это может быть трясина, которая заставляет вас начинать спрашивать, для кого вы поддерживаете свою смысловую чистоту? Это для поисковых систем, для чтения с экрана или простоты обслуживания? Я вернусь к этому после следующей классификации.

  • Некоторые из них являются прагматическими рационализациями, которые утверждают, что они эквивалентны семантически, но, по правде говоря, отличаются смысловым смыслом. На мой взгляд, это действительно семантический взлом. @volker-e ответ - пример этого. Он прав, это альтернативная разметка, которая может работать, но она не совпадает с тем же смысловым смыслом. h2 принадлежит main как h1 - нет смысла перемещать его внутри заголовка страницы. Фактически, вы говорите, что ваш заголовок не связан с вашим основным контентом. Это, в некотором смысле, хуже, чем использование этого div, который вы хотели использовать, потому что вы создаете ложную семантическую связь, группируя заголовок страницы и заголовок сайта в один и тот же семантически значимый header. Семантически бессмысленный контейнер, такой как div, для header и main, на мой взгляд, на самом деле менее извращен.

Итак, возвращаясь к тому, что я сказал о том, для кого вы поддерживаете семантическую чистоту, это настоящий философский вопрос в игре. Часто существует очевидное, эффективное и поддерживаемое решение без рационализированного неправильного использования существующих семантических элементов или трюков css. В вашем случае, если у вас есть элемент, который семантически является ребенком, но не является ребенком, ответ - тот, который вы уже задали в качестве вопроса:

Перепишите разметку HTML5 с не семантическими элементами (например, divs), поэтому что он больше соответствует визуальной компоновке, а затем обменивается не семантические элементы [sic] семантические (например, нижний колонтитул или основной), где бы возможно с новой структурой.

Это правильная вещь, чтобы сделать, чтобы вы были семантической чистотой, предназначенной для

  • Доступность: в этом случае вы можете достичь этого в неиерархическом порядке с ролями ARIA.
  • поисковые системы: поисковые системы по-прежнему понимают старый способ делать что-то, поэтому вы не столкнетесь с проблемой SEO, если будете следовать более старым подходам к семантике.
  • обслуживание: это причина, по которой большинство людей заманивают - но проблема в том, какой смысл поддерживаемого HTML, но неподдерживаемый CSS, или наоборот? у вас нет выбора, кроме как увидеть ваше обслуживание как комбинацию как CSS, так и HTML, и вам нужно найти среднюю площадку, где они оба неравнозначны, когда вы сталкиваетесь с трудной проблемой презентации.

Единственный другой возможный ответ, если вы считаете, что семантика HTML важна, - это принять ограничения, которые иерархическая семантика HTML размещается на вашем макете. Проблема в том, что в CSS не существует способа воссоздать иерархию компоновки. Пока это не произойдет, вам придется признать, что HTML - это как презентационный, так и семантический язык, и поэтому семантика всегда будет вопросом "лучше" и "хуже". Действительно красивая или богатая или совершенная семантика будет недостижимой во многих, если не в большинстве, макетах.

Ответ 2

Мой подход будет следующим:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a class="aural" href="#content">Jump to content</a>
    <header role="banner">
        <h1 class="site-logo">Logo</h1>
        <nav role="navigation" aria-labelledby="nav-heading">
            <h6 id="nav-heading">Navigation</h6>
            <ul>…</ul>
        </nav>
        <h2 id="heading">Page heading</h2>
    </header>
    <main id="content" role="main" aria-labelledby="heading">
        Page content
    </main>
    <footer role="contentinfo">
        Content information
    </footer>
</body>
</html>

а затем перейдите к набору правил CSS, например:

header h1,
header h2,
header nav {
    float: right;
}

Diff:

  • У вас есть подходящие доступные заголовки для содержимого страницы.
  • Вы сохраняете иначе, казалось бы, бесполезно div в header и main
  • У вас есть хороший контур структуры HTML5, который помогает SEO.
  • Я включил (не был частью вопроса) навигационные ориентиры в отношении спецификации проекта WAI-ARIA 1.0
  • Я включил пропущенную ссылку, которая по-прежнему рекомендуется наилучшей практикой.
  • Незначительное изменение: я знаю, что значение значения charset нечувствительно, но поскольку вы также пишете DOCTYPE uppercase, UTF-8 является более правильным значением, см. http://en.wikipedia.org/wiki/UTF-8#Official_name_and_variants

Ответ 3

Первая структура может по-прежнему работать, если есть позиция: относительная в <main> и использование позиции: абсолютная на h1 с z-индексом и a -ve margin. Таким образом, заголовок будет всегда плавать сверху в том же положении относительно основного содержимого. Хотя это может быть не лучшее решение, я думаю, что он не сломает макет (?)