[TWIG][CSS][Accessibility] Base template accessibility improvements. Applying more semantic HTML5 tags and aria to describe content actions.

This commit is contained in:
Eliseu Amaro 2021-08-19 20:37:16 +01:00 committed by Diogo Peralta Cordeiro
parent fc310a0b4e
commit 010f70e432
Signed by: diogo
GPG Key ID: 18D2D35001FBFAB0
7 changed files with 73 additions and 45 deletions

View File

@ -184,7 +184,12 @@
font-size: var(--medium-size); font-size: var(--medium-size);
padding: 4px; padding: 4px;
} }
.note-info a {
.note-author {
font-family: var(--display-font);
font-size: var(--medium-size);
font-weight: bold;
display: flex;
align-items: center; align-items: center;
align-self: center; align-self: center;
} }
@ -193,6 +198,7 @@
width: auto; width: auto;
height: var(--medium-size); height: var(--medium-size);
border-radius: var(--unit-size); border-radius: var(--unit-size);
margin-right: 4px;
} }
/* TODO: icons */ /* TODO: icons */
@ -266,8 +272,9 @@
/* no need to make the panels disappear at this size */ /* no need to make the panels disappear at this size */
.icon-left, .icon-left,
.icon-right { .icon-right {
display: none; visibility: hidden;
} }
} }
@media (max-width: 1200px) { @media (max-width: 1200px) {
/* content should occupy the entire width at this size */ /* content should occupy the entire width at this size */
@ -406,7 +413,7 @@
/* BUTTONS AND INPUT SHENANIGANS */ /* BUTTONS AND INPUT SHENANIGANS */
button, button,
input:not([type=radio]):not([type=checkbox]):not([type=text]) { input:not([type=radio]):not([type=checkbox]):not([type=text]):not([type=password]) {
font-size: var(--small-size) !important; font-size: var(--small-size) !important;
background-image: linear-gradient(180deg, var(--bg2), transparent) !important; background-image: linear-gradient(180deg, var(--bg2), transparent) !important;
color: var(--white) !important; color: var(--white) !important;
@ -415,8 +422,17 @@ input:not([type=radio]):not([type=checkbox]):not([type=text]) {
} }
textarea, textarea,
input[type=text] { input[type=text],
input[type=password] {
font-size: inherit !important; font-size: inherit !important;
display: inline-block;
position: relative;
color: var(--white);
border-radius: var(--unit-size);
padding: var(--unit-size);
box-sizing: border-box;
border: 2px solid var(--bg2);
background-color: var(--translucent);
} }
textarea:hover, textarea:hover,
@ -428,8 +444,8 @@ input[type=radio] {
border: solid 0.25em var(--bg2) !important; border: solid 0.25em var(--bg2) !important;
background-color: var(--bg1) !important; background-color: var(--bg1) !important;
} }
input[type=radio]:hover, input:hover,
input[type=radio]:focus { input:focus {
border-color: var(--bg3) !important; border-color: var(--bg3) !important;
} }
input[type=radio]:checked { input[type=radio]:checked {
@ -439,8 +455,11 @@ input[type=radio]:checked {
input[type=checkbox] { input[type=checkbox] {
background-color: var(--bg2) !important; background-color: var(--bg2) !important;
background-size: cover; background-size: cover;
mask-image: url("../icons/check-off.svg") !important;
-webkit-mask-image: url("../icons/check-off.svg") !important;
-o-mask-image: url("../icons/check-off.svg") !important;
-moz-mask-image: url("../icons/check-off.svg") !important;
mask-image: url("../icons/check-off.svg") !important;
} }
input[type=checkbox]:hover, input[type=checkbox]:hover,
input[type=checkbox]:focus { input[type=checkbox]:focus {
@ -448,6 +467,9 @@ input[type=checkbox]:focus {
} }
input[type=checkbox]:checked { input[type=checkbox]:checked {
background-color: var(--bg3) !important; background-color: var(--bg3) !important;
-webkit-mask-image: url("../icons/check-on.svg") !important;
-o-mask-image: url("../icons/check-on.svg") !important;
-moz-mask-image: url("../icons/check-on.svg") !important;
mask-image: url("../icons/check-on.svg") !important; mask-image: url("../icons/check-on.svg") !important;
} }

View File

@ -64,6 +64,12 @@
font-family: var(--main-font); font-family: var(--main-font);
padding-left: var(--unit-size); padding-left: var(--unit-size);
} }
#stats {
display: flex;
flex-direction: column;
font-size: var(--medium-size);
font-weight: bold;
}
/* TIMELINE NAVIGATION / PLUGINS */ /* TIMELINE NAVIGATION / PLUGINS */
.timeline-nav a, .timeline-nav a,

View File

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html xml:lang="en" lang="en">
<head> <head>
{% block meta %} {% block meta %}
<meta charset="UTF-8"> <meta charset="UTF-8">
@ -30,26 +30,26 @@
<body class="bg"> <body class="bg">
{% block header %} {% block header %}
<div id='header'> <header id='header' role="banner">
<details class="panel" id="left-container"> <details class="panel" id="left-container" role="group" aria-hidden="true">
<summary tabindex="0" aria-haspopup="true" role="button" aria-expanded="false"> <summary tabindex="0">
{{ icon('menu', 'icon icon-left') | raw }} {{ icon('menu', 'icon icon-left') | raw }}
{{ block("leftpanel", "stdgrid.html.twig") }} {{ block("leftpanel", "stdgrid.html.twig") }}
</summary> </summary>
</details> </details>
<a id='instance' href="{{ path('main_public') }}" tabindex="0"> <a id='instance' href="{{ path('main_public') }}" tabindex="0">
{{ icon('logo', 'icon icon-logo') | raw }} <div aria-hidden="true">{{ icon('logo', 'icon icon-logo') | raw }}</div>
<h1> {{ config('site', 'name') }} </h1> <h1> {{ config('site', 'name') }} </h1>
</a> </a>
<details class="panel" id="right-container"> <details class="panel" id="right-container" role="group" aria-hidden="true">
<summary tabindex="0" aria-haspopup="true" role="button" aria-expanded="false"> <summary tabindex="0">
{{ icon('notes', 'icon icon-right') | raw }} {{ icon('notes', 'icon icon-right') | raw }}
{{ block("rightpanel", "stdgrid.html.twig") }} {{ block("rightpanel", "stdgrid.html.twig") }}
</summary> </summary>
</details> </details>
</div> </header>
{% endblock header %} {% endblock header %}
<div class="container"> <div class="container">

View File

@ -1,6 +1,6 @@
{% extends 'stdgrid.html.twig' %} {% extends 'stdgrid.html.twig' %}
{% block title %}Welcome!{% endblock %} {% block title %}{{ 'Welcome! - Public Timeline' | trans }}{% endblock %}
{% block stylesheets %} {% block stylesheets %}
{{ parent() }} {{ parent() }}
@ -8,10 +8,9 @@
{% endblock %} {% endblock %}
{% block body %} {% block body %}
{# Backwards compatibility with hAtom 0.1 #} {# Backwards compatibility with hAtom 0.1 #}
<div class="timeline" tabindex="0"> <main class="timeline" tabindex="0" role="main" aria-label={{ 'Main public timeline feed.' | trans }}>
<main class="h-feed hfeed notes"> <div class="h-feed hfeed notes" role="feed">
{% if notes is defined and notes is not empty %} {% if notes is defined and notes is not empty %}
{% for conversation in notes %} {% for conversation in notes %}
{% include '/note/view.html.twig' with {'note': conversation['note'], 'have_user': have_user, 'replies': conversation['replies']} only %} {% include '/note/view.html.twig' with {'note': conversation['note'], 'have_user': have_user, 'replies': conversation['replies']} only %}
@ -19,8 +18,8 @@
{% else %} {% else %}
<div id="empty-notes"><h1>{% trans %}No notes here.{% endtrans %}</h1></div> <div id="empty-notes"><h1>{% trans %}No notes here.{% endtrans %}</h1></div>
{% endif %} {% endif %}
</main> </div>
</div> </main>
{% endblock body %} {% endblock body %}

View File

@ -1,25 +1,27 @@
<div class="h-entry hentry note"> <article class="h-entry hentry note">
<div class="note-info"> <div class="note-info" role="complementary">
{% set nickname = note.getActorNickname() %} {% set nickname = note.getActorNickname() %}
{# TODO: this should link to the note's user profile? #} {# TODO: this should link to the note's user profile? #}
<a class="u-url" href="#"> <header class="note-author u-url" href="#" >
{# Microformat's h-card properties indicates a face icon is a "u-logo" #} {# Microformat's h-card properties indicates a face icon is a "u-logo" #}
<img class="u-logo avatar" src="{{ note.getAvatarUrl() }}" alt="{{ nickname }}'s avatar"> <img class="u-logo avatar" src="{{ note.getAvatarUrl() }}" alt="{{ nickname }}'s avatar" aria-hidden="true">
<b class="p-nickname">{{ nickname }}</b> <label aria-roledescription={{ 'This note author nickname.' | trans }}>
</a> {{ nickname }}
</label>
</header>
{% set reply_to = note.getReplyToNickname() %} {% set reply_to = note.getReplyToNickname() %}
{% if reply_to is not null and not skip_reply_to is defined %} {% if reply_to is not null and not skip_reply_to is defined %}
{% trans with {'%name%': reply_to} %} in reply to %name% {% endtrans %} {% trans with {'%name%': reply_to} %} in reply to %name% {% endtrans %}
{% endif %} {% endif %}
<div class="note-actions"> <div class="note-actions" aria-roledescription={{ 'Favourite, reply and recycle this note' | trans }}>
{% if have_user %} {% if have_user %}
{% for current_action in get_note_actions(note) %} {% for current_action in get_note_actions(note) %}
{{ form_start(current_action) }} {{ form_start(current_action) }}
{% if current_action.submit_fav is defined %} {% if current_action.submit_fav is defined %}
<span title="Favourite this note." class="favourite-button-container"> <span title="Favourite this note." class="favourite-button-container" aria-atomic="true">
{{ form_widget(current_action.submit_fav) }} {{ form_widget(current_action.submit_fav) }}
</span> </span>
{% endif %} {% endif %}
@ -27,9 +29,8 @@
{% endfor %} {% endfor %}
{% endif %} {% endif %}
</div> </div>
</div> </div>
<div class="e-content entry-content note-content"> <div class="e-content entry-content note-content" aria-roledescription="">
{% block markdown %} {% block markdown %}
{% apply markdown_to_html %} {% apply markdown_to_html %}
{{ note.getContent() }} {{ note.getContent() }}
@ -63,6 +64,6 @@
{% endfor %} {% endfor %}
</div> </div>
{% endif %} {% endif %}
</div> </article>
<hr> <hr>

View File

@ -1,8 +1,8 @@
<aside id='left-panel' tabindex="-1"> <aside id='left-panel' tabindex="-1" role="feed" aria-label={{ 'Left page panel.' | trans }}>
<nav class='profile-nav'> <nav class='profile-nav'>
{% if app.user %} {% if app.user %}
<section class='profile'> <section class='profile' role="complementary">
<div id="profile-links"> <div id="profile-links">
<a id="user-avatar" href="{{ path('settings') }}"> <a id="user-avatar" href="{{ path('settings') }}">
<img src='{{ user_avatar }}' alt="Your avatar." class="icon icon-avatar"> <img src='{{ user_avatar }}' alt="Your avatar." class="icon icon-avatar">
@ -24,17 +24,17 @@
</span> </span>
</div> </div>
<span id="stats"> <section id="stats">
<h2>{{ 'Followers' | trans }} {{ user_followers }}</h2> <label>{{ 'Followers' | trans }} {{ user_followers }}</label>
<h2>{{ 'Followed' | trans }} {{ user_followed }}</h2> <label>{{ 'Followed' | trans }} {{ user_followed }}</label>
</span> </section>
{# {% for extra in profile_extras %} {# {% for extra in profile_extras %}
{% include '/'~ extra.name ~ '/view.html.twig' with {'vars': extra.vars} only %} {% include '/'~ extra.name ~ '/view.html.twig' with {'vars': extra.vars} only %}
{% endfor %} #} {% endfor %} #}
</section> </section>
<nav> <nav role="navigation">
<a href='#'>Messages</a> <a href='#'>Messages</a>
<a href="{{ path("replies", {'nickname' : user_nickname}) }}" <a href="{{ path("replies", {'nickname' : user_nickname}) }}"
class='hover-effect {{ active("replies") }}'>Replies</a> class='hover-effect {{ active("replies") }}'>Replies</a>
@ -53,11 +53,11 @@
</nav> </nav>
{% endif %} {% endif %}
<div class="timeline-nav"> <div class="timeline-nav" role="menu">
<nav> <nav>
<h1>Timeline</h1> <h1 role="tab">Timeline</h1>
<nav class='sec-nav'> <nav class='sec-nav' role="navigation">
<a href="{{ path('main_public') }}" <a href="{{ path('main_public') }}"
class='{{ active('main_public') }}'>Public</a> class='{{ active('main_public') }}'>Public</a>
@ -81,7 +81,7 @@
</nav> </nav>
<div class="footer"> <div class="footer" role="contentinfo">
<a href="{{ path('doc_faq') }}" class='hover-effect {{ active('doc_faq') }}'>FAQ</a> <a href="{{ path('doc_faq') }}" class='hover-effect {{ active('doc_faq') }}'>FAQ</a>
<a href="{{ path('doc_tos') }}" class='hover-effect {{ active('doc_tos') }}'>TOS</a> <a href="{{ path('doc_tos') }}" class='hover-effect {{ active('doc_tos') }}'>TOS</a>
<a href="{{ path('doc_privacy') }}" class='hover-effect {{ active('doc_privacy') }}'>Privacy</a> <a href="{{ path('doc_privacy') }}" class='hover-effect {{ active('doc_privacy') }}'>Privacy</a>

View File

@ -1,6 +1,6 @@
<aside id='right-panel' tabindex="-1"> <aside id='right-panel' tabindex="-1" role="region" aria-label={{ 'Right page panel.' | trans }}>
{% if post_form is defined %} {% if post_form is defined %}
<section class="section-widget"> <section class="section-widget" role="complementary" aria-label={{ 'Create a new note.' | trans }}>
<details class="section-title"> <details class="section-title">
<summary class="section-title-menu"> <summary class="section-title-menu">
{{ "Create a note" | trans }} {{ "Create a note" | trans }}