CSS-live.ru

Фреймворк AngularJS не для сайтов

Перевод статьи AngularJS is not for websites с сайта wolfslittlestore.be, c разрешения автора — Йохана Ронсе.

Я хотел написать небольшую предысторию про мой комментарий в Твиттере об AngularJS и сайтах, и тем самым предоставить более детальный обзор.

Люди, поймите, AngularJS не предназначен для сайтов. Два новых крупных сайта в Бельгии, финансируемые деньгами налогоплательщиков, не доступны для слепых. Это больно видеть.

— Йохан Ронсе (@wolfr_) 14 Октября 2014

Я не знаю, о чем я думал, когда писал, что это больно «видеть». Шутки в сторону, этот комментарий о недавних редизайнах antwerpen.be и stubru.be.

Сайты с государственным финансированием: доступность информации – это обязанность

Эти сайты финансируются государством: Antwerpen.be был сделан «Digipolis» – в котором работает большая команда. А новый сайт Студии Брюсселя – внутренней командой.

Бельгийское радио «ВРТ» озвучило примерную сумму, потраченную правительством на «Интернет и мобильные приложения». В 2012 году эта сумма составила 16.9 миллионов евро, а в 2011 – 14.5 миллионов. В 2013 году «Digipolis» получил субсидию на сумму 39 миллионов евро. Эти цифры были получены из беглого поиска в интернете и вероятнее всего не описывают полную картину. Я просто хотел подчеркнуть, что эти сайты сделаны на деньги налогоплательщиков.

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

AngularJS для сайтов?

Оба вышеназванных сайта используют Javascript-фреймворк под названием AngularJS

AngularJS – мощный Javascript-фреймворк созданный Google с целью расширить HTML, чтобы делать лучшие веб-приложения. Это отличный мост в будущее, где приложения могут быть построены с веб-компонентами.

Главный проект над которым я работаю – крупное веб-приложение, использует AngularJS для фронтенда. Это веб-приложение, защищённое паролем, которое люди используют, чтобы эффективнее решать свои задачи.

AngularJS работает очень хорошо, когда он используется для приложений. Но, возможно, это не совсем правильный инструмент для информационных сайтов.

В моём твитте я сказал, что AngularJS не предназначен для сайтов, обвинив во всём только AngularJS. Вообще-то это мнение уж больно упрощено. Проблема не в самом AngularJS. Проблема не во фреймворке, а в коде, написанном с помощью фреймворка. Хотя можно поспорить, что фреймворк позволяет легко писать такой код, который приводит к недоступности сайтов.

Тестирование

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

Фрэнк отметил, что в наше время скринридеры понимают Javascript:

@wolfr_ В наши дни скринридеры врубаются в Javascript :)

— Фрэнк Луверс (@frank_be) 14 Октября 2014

И это правда: недавний опрос организации WebAIM, который касался пользователей скринридеров, показал, что 97.6% корреспондентов используют браузеры с включённым Javascript.

(WebAIM — сокращение от «с мыслью о веб-доступности» — американская организация, продвигающая веб-доступность)

Тест с voiceover: Stubru.be

Чтобы подтвердить мою точку зрения, я запустил программу VoiceOver от Apple и постарался ориентироваться на сайт Студии Брюселя.

Часть сайта работала хорошо. Однако, я столкнулся с множеством проблем.

Сгенерированный HTML является довольно проблематичным. Например, разметка статей на главной странице выглядит так:

<a zoomy="" ng-href="/linde/lindewasvandaagonzekinderoppasvandienst" image="foto_15-10-14_12_51_05_0.jpg" class="grid-item-link ng-isolate-scope pseudo-active" tabindex="300" title="Linde was vandaag onze kinderoppas van dienst" href="/linde/lindewasvandaagonzekinderoppasvandienst">
  <div class="zoomy">
    <div class="image" ng-style="::{backgroundImage: 'url(' + image + ')'}" style="background-image: url(foto_15-10-14_12_51_05_0.jpg?itok=kM7WoYEt);"></div>
    <div class="content" ng-transclude="">
      <div class="grid-item-article ng-scope">
        <div class="info">
          <div class="heading ng-isolate-scope" aria-label="title article" tag="Linde">
          <!-- ngIf: ::tag -->
          <h4 ng-if="::tag" aria-label="Tag article" class="tag ng-binding ng-scope" ng-bind="::tag">Linde</h4>
          <!-- end ngIf: ::tag -->
          <!-- ngIf: ::!head -->
          <h1 ng-if="::!head" aria-label="Title article" class="title ng-scope" ng-transclude="">
            <span class="ng-binding ng-scope">Linde was vandaag onze kinderoppas van dienst</span>
          </h1>
          <!-- end ngIf: ::!head -->
          <!-- ngIf: ::head -->
        </div>
        <div class="teaser" aria-label="intro article">
          <p class="ng-binding">Bijna klaar voor het echte werk, maar toch nog even oefenen!</p>
          <div class="timestamp ng-binding" aria-label="date article">2 uur geleden</div>
        </div>
      </div>
    </div>
    </div>
  </div>
</a>

Как ни странно, разработчики были в курсе доступности и использовали aria-label, чтобы пометить различные части HTML. Атрибут aria-label используется для обозначения того, что должны прочитать скринридеры, когда в HMTL нет подходящих меток. Например:

<button aria-label="Закрыть">x</button>

В данном случае скринридер прочитает слово «Закрыть», тем самым помогая пользователю понять, что это кнопка для закрытия (например, всплывающего окна).

Проблема здесь в том, что вместо прочтения реального заголовка статьи, скринридер прочитает слова «заголовок статьи».

Не знаю как вас, а меня на занятиях по верстке учили, что следует писать как-то вот так:

<div class="grid-item-article">
    <img src="images/foto_15-10-14_12_51_05_0.jpg" alt="Linde kinderoppas">
    <h1><a href="#"><span class="tag">Linde</span> - Linde was vandaag onze kinderoppas van dienst</a></h1>
    <p>2 uur geleden</p>
    <p>Bijna klaar voor het echte werk, maar toch nog even oefenen!</p>
</div>

Если вы используете семантический HTML, то в ARIA-атрибутах нет необходимости. Скринридеры прочтут текст в ссылках. В качестве бонуса, вы не можете делать ошибки, используя неправильные теги ARIA.

Оптимальная разметка для этой ситуации спорна; но HTML, используемый в настоящее время stubru.be, является просто неправильным: злоупотребление aria-label, элемент h4 следует за h1 – не говоря уже о явной передозировке div-ов.

Как скринридер должен разобраться с этим? У многих скринридеров есть функции перечисления заголовков на странице – заголовок 4-го уровня, которому предшествует заголовок 1-го уровня, не имеет смысла.

Использование комментариев "если" предполагает, что кто-то пытался понять смысл этой разметки, тогда как разметка для описания статьи – одна из самых базовых вещей, которую можно написать в HTML

Зачем усложнять простые вещи?

Тест с voiceover: Antwerpen.be

При тестировании Antwerpen.be, на первый взгляд я был приятно удивлён, оказавшись неправым в моём тезисе, что сайты, использующие AngularJS, недоступны.

И действительно, разметка была хорошо структурирована и по сайту можно было перемещаться по навигации в скринридере.

Однако, при более глубоком рассмотрении пользоваться им, рассчитывая лишь на VoiceOver, оказалось довольно трудно. Например, первым важным элементом на сайте является поле поиска на главной странице, но с помощью VoiceOver мне не удалось узнать, где находится этот поиск. Не существовало меток, указывающих на то, что это поле поиска.

<div class="searchInputWrapper">
  <input class="searchInput ng-isolate-scope ng-valid ng-dirty" focus="searchfieldHasFocus" type="text" placeholder="Wat wilt u vinden?" data-ng-blur="submitSearch()" data-ng-model="searchQuery.query" data-ng-change="doSearch()" maxlength="140" value="searchQuery.query">
      <span data-ng-show="searchQuery.query.length" data-ng-click="emptySearchHard()" class="cancelSearchQuery ng-hide">?</span>
  <a class="submitSearch ng-scope" data-ng-click="searchOverview()" translate=""><i class="icon-search ng-scope"><span>Zoeken</span></i></a>
</div>

Снова похоже на то, что разработчик был отчасти осведомлён о доступности, используя «Zoeken» (Поиск) в качестве метки для иконки поиска. За исключением HTML, написанного таким образом, что скринридер на самом деле никогда не прочитает эту метку.

Поскольку это поле, в котором непосредственно во время печатания перечисляются результаты, стандартная структура для формы уже не сможет справиться.

<form>
  <label for="search">Zoeken</label>
  <input type="search" id="search">
  <input type="submit" value="Zoeken">
</form>

Именно здесь ARIA («Насыщенное («богатое») Интернет-приложение») вступает в дело: используя правильные теги ARIA, форму поиска можно сделать доступной. Вот пример доступного автозаполнения формы поиска.

Проблемы с навигацией и управление фокусом

AngularJS позволяет делать сайт более похожим на приложение: по сути он позволяет вам загружать содержимое более динамичным способом.

Если вы посмотрите на stubru.be с визуальной точки зрения, то увидите, что он на самом деле довольно впечатляющий: при переходе от одной статьи к следующей содержимое загружается почти мгновенно. Если вы кликните на видео, оно тут же загрузится между делом изобразив милую анимацию. Если вы захотите переместиться по навигации сайта, то она выскочит сбоку, чётко обозначив различные разделы.

В каком-то смысле это поведение, более свойственное приложениям, воспринимается как шаг вперед по сравнению с традиционными сайтами. Перезагрузки страниц пропали, всё выглядит более плавным.

Проблемой с выезжающим со всех сторон новым контентом является трудность понимания того, на чём сосредоточиться. А теперь представьте, что вы не можете использовать мышь и и ваш единственный проводник по контенту – клавиша «Tab». А теперь представьте, что вы слепой. Вообще.

Сочетание разметки в стиле masonry и скрытого всплывающего меню делает сайт очень запутанным по сравнению с перемещением по статичной странице клавишей таб.

Невольно возникает вопрос, есть ли реальная необходимость в таком навороченном дизайне для сайта, который по сути является списком новостей по категориям.

Гийс Вейфейкен – эксперт по веб-доступности в AnySurfer, предоставил хороший аргумент на счёт управления фокусом:

@wolfr_ @bram_ Результат Angular'а — обычный HTML и может быть прочитан скринридерами. Управление фокусом является ключевым фактором, чтобы сделать изменения страницы понятными.

— Гийс Вейфейкен (@veyfeyken) 15 октября 2014

Управление фокусом – вероятно одна из самых трудных вещей при попытке сделать навороченный сайт доступным. В этой статье на Sitepoint есть несколько хороших советов, как это сделать.

Заключение

Отчасти это напоминает мне о времени, когда очень много сайтов были построены на Флеше. У них были всякого рода проблемы: неиндексирование поисковыми движками, пользовательские элементы управления с нарушением взаимодействия (такие как невозможность скроллить и выделять текста) и проблемы доступости.

Мы учли эти ошибки прошлого и начали писать HTML осмысленно. Мы начали разделять структуру, содержание и поведение.

В этом новом мире адаптивных дизайнов и сайтов, которые работают только с включённым Javascript, давайте не забывать основы. Семантический HTML по прежнему имеет значение.

Я знаю, как трудно делать сайты, и не хочу этой статьёй пристыдить те два упомянутых. Во многих отношениях оба сайта – замечательные образцы веб-дизайна. Единственное, мне хотелось бы напомнить, что не стоит забывать о доступности.

Отдельное спасибо Гийсу Вейфейкену за исправление ошибок в черновике этой статьи.

P.S. Это тоже может быть интересно:

16 комментариев

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

      1. Angular сам по себе разметку не добавляет, если так сделал разработчик это не вина фреймворка. Точно такую же верстку можно ожидать где угодно, написав на чем угодно.

        1. Angular сам по себе может и не добавляет пагубной разметки, но вот разработчик, работая с Angular, зачатстую грешит этим. Тут проблема не в самом Angular, а в коде, который пишется с помощью этого фреймворка. Работая с Angular, разработчик начинает думать категорией «"веб-приложение"», вот в этом-то и проблема. О чём и говорит автор.

          1. С таким же успехом если человек не знает как пользоватся инструментом он может г. кодить и с другими фреймворками, а про jquery я вообще молчу…

            1. По-моему, тут акцент не столько на «как», сколько на «для чего». То, что идеально отлично для интерфейса приложения, используемого в строго определенном контексте, имеет кучу подводных камней в случае сайта, к которому могут обращаться разные люди из-под самого разного окружения. Насколько я понял, автор как раз призывает вспоминать об этом «для чего» прежде, чем начинать сосредотачиваться на «как».

  1. Angular вообще ни для чего. Прожорливый, медленный, большое приложение вообще на нем умрет. Не удивительно, что сам Google ничего не пишет на Angular. Стоит упомянуть, что это не проект Google, а проект его сотрудников. Что касает веб-компонентов, то Angular, как раз, противоречит этой идеологии, со своим перемешиванием логики и отображения. Компоненты — это, например, про React. Короче хорошее решение для тех, кто раньше не писал на JavaScript, а пришел "с сервера".

    1. Вот, вот. Люди вообще похоже не шарят. Нормальный опытный программист не будет это использовать. JS все что надо имеет. Даже jquery я использую только из-за лени. Но использую по классике чистого js. Без всяких предварительных инициализаций. И скрытых вызовов.

  2. Вот, вот. Люди вообще похоже не шарят. Нормальный опытный программист не будет это использовать. JS все что надо имеет. Даже jquery я использую только из-за лени. Но использую по классике чистого js. Без всяких предварительных инициализаций. И скрытых вызовов.

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Получать новые комментарии по электронной почте. Вы можете подписаться без комментирования.