platform icon indicating copy to clipboard operation
platform copied to clipboard

Добавляет значки для авторов

Open igsekor opened this issue 3 years ago • 1 comments

Этот PR связан с 3877 в контенте

Требуется:

  • [ ] подделать картинки значков по размеру;
  • [ ] до конца проработать скрипт для расстановки значков в сетке;
  • [ ] зафиналить дизайн всплывашки;
  • [ ] проверить и исправить описание;
  • [ ] доработать генерацию значков с текстом;
  • [ ] внедрить значок с датой первого контрибьюшна.

igsekor avatar Oct 07 '22 08:10 igsekor

  • [ ] зафиналить дизайн всплывашки;

@igsekor здесь нужна моя помощь? :)

skorobaeus avatar Oct 14 '22 11:10 skorobaeus

  • [ ] зафиналить дизайн всплывашки;

@igsekor здесь нужна моя помощь? :)

Думаю да. Сейчас ширину пока задаю заголовком. Может стоит иначе? 🙃

igsekor avatar Oct 20 '22 09:10 igsekor

Пара моментов, которые надо будет пофиксить в следующих версиях:

  • Если значков много, то попапы от верхних уезжают краями за верхний край страницы. Потенциальное решение: считать позицию бэджика относительно верхнего края окна и если места мало, то навешивать доп.класс. При наличии этого класса показывать попап по центру бэджика или ниже него.
  • Написала медиазапрос, чтобы попапы показывались только на устройствах с ховерами. Надо подумать, как и в каком виде показывать попапы на мобилке.
  • Показ попапа по ховеру — слегка неудобно. В частности для людей с экранной лупой — попап пропадает раньше, чем они успевают на него навестись. Надо будет подумать над показом по другому тригеру. Например, сделать бэджики не дивами, а диалогами. И прикрутить к попапам кнопку закрытия. Тогда будет вообще по красоте.

solarrust avatar Oct 26 '22 10:10 solarrust

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

Как должен работать тултип

  • Тригер для тултипа — интерактивный элемент. Кнопка, ссылка, поле.
  • Тултип должен становиться видимым при наведении мыши на элемент, клавиатурном фокусе и тапе.
  • Тултип должен исчезать при убирании курсора и при потере фокуса, а ещё закрываться при нажатии на Esc.
  • Для пользователей экранных луп хорошо добавить с тултип кнопку закрытия, при нажатии на которую тултип больше не появляется при наведении мыши на элемент (до перезагрузки страницы).
  • Содержимое должно дополнять элемент, который его вызывает, быть кратким. И вообще содержимое должно быть просто строкой текста, это связано с типичной реализацией компонента.

Что точно нельзя

  • Использовать роль tooltip. Плохая поддержка, бесполезный лишний код.
  • Использовать title. Недоступен для клавиатуры и тач-устройств и с этим ничего не поделаешь.
  • Использовать aria-haspopup для тригера.
  • Добавлять для области с тултипом aria-live.
  • Скрывать тултип не сразу, а через какое-то время.
  • Добавлять в тултипы заголовки, графику, как-то играть с форматированием с помощью тегов.

Как предлагают реализовывать

  • Тригер — <button>, <a>, <input>.
  • Сам тултип — aria-describedby (для более расширенного видимого описания элемента, который показывает тултип) или aria-labelledby (для краткого видимого имени элемента). Оба атрибута навешиваются на тригер и связываются с содержимым тултипа через id. id должна быть уникальными для каждого тултипа.
  • Для тултипа также стоит использовать aria-hidden, которое будет по умолчанию всегда висеть на нём со значением true и менять его на false, когда тултип появляется. Альтернатива — display: block, когда тултип виден, и display: none, когда скрыт.
  • Обрабатывать события фокуса, onblur, mouseout, mousein и нажатие на клавишу Esc для закрытия тултипа.

Экстра реализация

Добавить в тултип кнопку для закрытия, которая доступна только для клика мышкой и не находится в порядке фокуса. Когда пользователь кликнет по такой кнопке, то тултип не будет больше появляться при наведении мыши до перезагрузки страницы. Это предлагают делать для пользователей экранных луп, которым могут мешать постоянно всплывающие окна. Такая кнопка не должна быть доступна скринридерам.

Тут у меня есть сомнения.

  1. Как зрячий пользователь клавиатуры будет себя чувствовать, если он не может сделать фокус на кнопке?
  2. В тултипе не должно быть интерактивных элементов, так мы нарушаем это правило.
  3. Просто не хочется лишний раз использовать отрицательное значение tabindex на интерактивном элементе.

Примерный вариант реализации

Только с текстом

<button aria-describedby="btn">Кнопка с тултипом</button>
<div class="tooltip" id="btn" aria-hidden="true">Эта кнопка с тултипом что-то делает и пока скрыта.</div>

С кнопкой для пользователей луп

<button aria-describedby="btn">Кнопка с тултипом</button>
<div class="tooltip" aria-hidden="true">
  <button tabindex="-1" aria-hidden="true">X</button>
  <span id="btn">Эта кнопка с тултипом что-то делает и пока скрыта.</span>
</div>

Мои мысли, идеи и предложения по улучшению

Я знаю, как лучше сделать сам тултип, но пока не уверена, что должно быть для него тригером. Псевдоссылка <a href="">? Кнопка, которая не делает ничего? Навесить на картинку tabindex="0", что делать не очень хорошо?

Второе сомнение насчёт того, как сделать доступно для пользователей экранных луп. Для начала можно подумать о том, чтобы сделать меньше текст в тултипах и картинку заодно. Кажется, что они очень много места занимают даже на десктопах и перекрывают контент. Это вопрос к @skorobaeus. Ну и можно пойти по пути с добавлением кнопки для закрытия в тултип, как я писала про экстра реализацию.

Я предлагаю примерно такое решение.

{% macro personBadges(badges, fields) %}
  <div class="person-badges {{ class if class }}">
    {% for badge in badges %}
      <div class="person-badges__sign person-badges__sign--col-{{ badge.field.width }} person-badges__sign--row-{{ badge.field.height }}">
        <div tabindex="0" aria-labelledby="{{ badge.id }}" class="person-badges__shape person-badges__shape--{{ badge.shape }} person-badges__shape--height-{{ badge.field.height }} person-badges__shape--width-{{ badge.field.width }} person-badges__shape--angle-{{ badge.angle }}">
          {% if badge.src %}
            <img class="person-badges__default-image" src="{{ badge.src }}" alt="{{ badge.alt }}">
          {% elif badge.text %}
            {{ badgeWithText(badge) }}
          {% endif %}
        </div>
        {% if badge.description and badge.title %}
          <div class="person-badges__pop-up">
            {% if badge.src %}
              <img class="person-badges__pop-up-image" src="{{ badge.src }}" alt="">
            {% elif badge.text %}
              {{ badgeWithText(badge) }}
            {% endif %}
            <span class="person-badges__pop-up-content" id="{{ badge.id }}">
              <span person-badges__pop-up-title>{{ badge.title }}</span>
              <p class="person-badges__pop-up-description font-theme font-theme--code">{% parseAndInsert badge.description, fields %}</p>
            </span>
          </div>
        {% endif %}
      </div>
    {% endfor %}
  </div>
{% endmacro %}

В нём я навесила на тригер tabindex="0" и добавила элемент в порядок фокуса. Я честно не знаю пока, как это сделать более семантично.

Также убрала <figure> и заменила на семантически нейтральный контейнеры для стилизации и группировки.

Также на этот тригер я навесила атрибут aria-describedby, с которым связан .person-badges__pop-up-content. В этом случае нам надо добавить в файлик с картинками ещё поле id.

.person-badges__pop-up-content содержит псевдозаголовок и само описание ачивки. Рядом с ним лежит картинка без alt. Мы делаем её декоративной, так как у нас уже есть описанная картинка-триггер. Просто не дублируем контент и как бы не включаем её в важное содержимое всплывашки. Псевдозаголовок потому, что в тултипе не может быть настоящего заголовка. Содержимое aria-describedby должно быть простой краткой строкой текста. Но стилизовать мы можем как хотим.

Ну и надо не забыть ещё отслеживать клавиатурный фокус на тригере, а также закрывать всплывашку при нажатии на Esc и когда на ней нет фокуса в придачу к всплыванию тултипа при наведении.

Что не решает моё предложение

  • Проблему доступности тултипа, которая есть у этого паттерна по умолчанию.
  • Доступность для экранных луп.
  • Доступность для пользователей голосового управления.
  • Всякие потенциальные юзабилити и UX-проблемы.

Ссылки

  • https://sarahmhigley.com/writing/tooltips-in-wcag-21/
  • https://codepen.io/smhigley/pen/KjoerX
  • https://dequeuniversity.com/library/aria/tooltip
  • https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/

TatianaFokina avatar Oct 26 '22 17:10 TatianaFokina

  1. Передвинула мету под основную инфу о человеке в разметке персональной страницы
  2. На мобильном и планшете поставила колонку с бэджами справа от хэдера. Альтернативой были гигантские значки =) (согласовано с @skorobaeus )
  3. Добавила :focus-visible для значков для показа попапа.
  4. Поправила мелочи

solarrust avatar Oct 27 '22 08:10 solarrust

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

// Слушаем события с тултипами
function initTooltip(tooltipContainer) {
    const trigger = tooltipContainer.querySelector('.person-badges__default-image');
    const tooltip = tooltipContainer.querySelector('.person-badges__pop-up');

    // Показываем тултип при наведении курсора и при фокусе
    tooltipContainer.addEventListener('mouseenter', () => {
        showTooltip(tooltip);
    });
    trigger.addEventListener('focus', () => {
        showTooltip(tooltip);
    });

    // Прячем тултип, когда курсор не на значке и фокус на другом элементе
    tooltipContainer.addEventListener('mouseleave', () => {
        hideTooltip(tooltip);
    });
    trigger.addEventListener('blur', () => {
        hideTooltip(tooltip);
    });

    // Скрываем тултип при нажатии на Esc
    trigger.addEventListener('keydown', (event) => {
        if (event.key === 'Escape') {
        hideTooltip(tooltip);
        }
    });
}

function showTooltip(tooltip) {
    tooltip.style.display = 'block';
}

function hideTooltip(tooltip) {
    tooltip.style.display = 'none';
}
  
// Вызываем функцию
const tooltips = document.querySelectorAll('.person-badges__sign');

tooltips.forEach((tooltip) => {
    initTooltip(tooltip);
});

TatianaFokina avatar Oct 27 '22 09:10 TatianaFokina

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

Тоже внедрил! Круто и невероятно!

igsekor avatar Oct 27 '22 20:10 igsekor

Сделала красивый попапчик на мобильных. Но теперь сломался скрипт. У попапа есть подложка на 100% ширины и высоты. И слушатель «ломается». Ещё надо добавить document.body.style.overflow = 'hidden' и в обратную сторону. И менять дисплей на grid, а не на block. @igsekor @TatianaFokina помогите, пожалуйста.

CleanShot 2022-10-28 at 10 22 48@2x

solarrust avatar Oct 28 '22 06:10 solarrust

Ещё дополнительная потенциальная проблема с доступностью, о которой надо как-нибудь подумать, — размер значков на мобилках. Какие-то могут быть за счёт формы более большими, а какие-то могут быть слишком мелкими. Но проблему тут может усугубить их скученность.

TatianaFokina avatar Oct 28 '22 16:10 TatianaFokina

Забыла ещё сказать. У нас сейчас скроллбар во всплывашке на дестопах из-за overflow-y: scroll.

Скроллбар слева у попапа.

TatianaFokina avatar Oct 28 '22 16:10 TatianaFokina

@TatianaFokina спасибо что заглянула!

  1. Подправила скрипт. Нашла решения через стили, чтобы тап по затемнению закрывал тултип.
  2. Убрала скролл на десктопе

Имхо, всё готово.

solarrust avatar Oct 28 '22 17:10 solarrust

~~Конструктор значков не протестировала — не смогла понять синтаксис.~~ ~~В остальном ок!~~

Кастомные значки огонь!

solarrust avatar Oct 31 '22 10:10 solarrust

Превью контента из b467eb69a4d724fb8e8066bffc80cfbbbbdd2ba9 опубликовано.

github-actions[bot] avatar Oct 31 '22 11:10 github-actions[bot]