Meta issue: #1980004: [meta] Creating Dream Markup
Problem/Motivation
We need better markup for pagination in terms of semantics and accessibility. Also, we need to follow our Drupal 8 style guide.
Proposed resolution
Much of this issue involves a discussion about removing the list from the markup. The version using list-items has more advocates than the version without lists, it is what we are currently using, and is what many other frameworks and CMSs also use. Therefore, the proposal at this point is
- Stop using theme_item_list; move as much markup as possible into the pager.html.twig Twig template.
- Follow Drupal 8 CSS Guidelines for CSS class nomenclature.
- Use Drupal's own visually-hidden class in combination with Aria attributes like aria-labelledby and aria-hidden to improve the way pagers are read aloud by screen-readers.
Current Drupal 8 pagination markup:
<div class="item-list">
<ul class="pager">
<li class="pager-first"><a href="/node" title="Go to first page">« first</a></li>
<li class="pager-previous"><a href="/node?page=4" title="Go to previous page" rel="prev">‹ previous</a></li>
<li class="pager-ellipsis">…</li>
<li class="pager-item"><a href="/node?page=1" title="Go to page 2">2</a></li>
<li class="pager-item"><a href="/node?page=2" title="Go to page 3">3</a></li>
<li class="pager-item"><a href="/node?page=3" title="Go to page 4">4</a></li>
<li class="pager-item"><a href="/node?page=4" title="Go to page 5">5</a></li>
<li class="pager-current">6</li>
<li class="pager-item"><a href="/node?page=6" title="Go to page 7">7</a></li>
<li class="pager-item"><a href="/node?page=7" title="Go to page 8">8</a></li>
<li class="pager-item"><a href="/node?page=8" title="Go to page 9">9</a></li>
<li class="pager-item"><a href="/node?page=9" title="Go to page 10">10</a></li>
<li class="pager-ellipsis">…</li>
<li class="pager-next"><a href="/node?page=6" title="Go to next page" rel="next">next ›</a></li>
<li class="pager-last"><a href="/node?page=12" title="Go to last page">last »</a></li>
</ul>
</div>
Proposed pagination markup:
(Last updated to match comment #202)
<nav class="pager" role="navigation" aria-labelledby="pagination-heading">
<h4 id="pagination-heading" class="visually-hidden">Pagination</h4>
<ul class="pager__items">
<li class="pager__item pager__item--first">
<a href="/node?status=All&type=All&title=" title="Go to first page">
<span class="visually-hidden">First page</span>
<span aria-hidden="true">« first</span>
</a>
</li>
<li class="pager__item pager__item--previous">
<a href="/node?status=All&type=All&title=" title="Go to previous page" rel="prev">
<span class="visually-hidden">Previous page</span>
<span aria-hidden="true">‹ previous</span>
</a>
</li>
<li class="pager__item ">
<a href="/node?status=All&type=All&title=" title="Go to page 1">
<span class="visually-hidden">Page</span>
1
</a>
</li>
<li class="pager__item is-active">
<a href="/node?status=All&type=All&title=&page=1" title="Current page">
<span class="visually-hidden">Current page</span>
2
</a>
</li>
<li class="pager__item ">
<a href="/node?status=All&type=All&title=&page=2" title="Go to page 3">
<span class="visually-hidden">Page</span>
3
</a>
</li>
<li class="pager__item pager__item--next">
<a href="/node?status=All&type=All&title=&page=2" title="Go to next page" rel="next">
<span class="visually-hidden">Next page</span>
<span aria-hidden="true">next ›</span>
</a>
</li>
<li class="pager__item pager__item--last">
<a href="/node?status=All&type=All&title=&page=2" title="Go to last page">
<span class="visually-hidden">Last page</span>
<span aria-hidden="true">last »</span>
</a>
</li>
</ul>
</nav>
This markup is based on feedback from various comments, and includes the following changes:
- Replace
<div class="item-list">
with<nav>
wrapper element. - Add a visually hidden
<h4>
element for announcing the section title, link it to the nav wrapper element via aaria-labelledby
attribute. - Add class
pager__items
to the unordered list element, following Drupal 8 CSS Style guidelines. - Add
pager__item
classes to all<li>
elements, following Drupal 8 CSS Style guidelines. - Make current page a link, for more consistent markup, making all elements easier to theme.
- Change from
pager-current
class tois-active
state, for consistency with Drupal 8 navigation active link state.
The proposed twig template will look like this:
{% if items %}
<nav class="pager" role="navigation" aria-labelledby="pagination-heading">
<h4 id="pagination-heading" class="visually-hidden">{{ 'Pagination'|t }}</h4>
<ul class="pager__items">
{# Print first item if we are not on the first page. #}
{% if items.first %}
<li class="pager__item pager__item--first">
<a href="{{ items.first.href }}" title="{{ 'Go to first page'|t }}"{{ items.first.attributes }}>
<span class="visually-hidden">{{ 'First page'|t }}</span>
<span aria-hidden="true">{{ items.first.text|default('« first'|t) }}</span>
</a>
</li>
{% endif %}
{# Print previous item if we are not on the first page. #}
{% if items.previous %}
<li class="pager__item pager__item--previous">
<a href="{{ items.previous.href }}" title="{{ 'Go to previous page'|t }}" rel="prev"{{ items.previous.attributes }}>
<span class="visually-hidden">{{ 'Previous page'|t }}</span>
<span aria-hidden="true">{{ items.previous.text|default('‹ previous'|t) }}</span>
</a>
</li>
{% endif %}
{# Add an ellipsis if there are further previous pages. #}
{% if ellipses.previous %}
<li class="pager__item pager__item--ellipsis" role="presentation">…</li>
{% endif %}
{# Now generate the actual pager piece. #}
{% for key, item in items.pages %}
<li class="pager__item {{ current == key ? 'is-active' : '' }}">
{% if current == key %}
{% set title = 'Current page'|t %}
{% else %}
{% set title %}
{%- trans %}Go to page {{ key }}{% endtrans -%}
{% endset %}
{% endif %}
<a href="{{ item.href }}" title="{{ title }}"{{ item.attributes }}>
<span class="visually-hidden">
{{ current == key ? 'Current page'|t : 'Page'|t }}
</span>
{{ key }}
</a>
</li>
{% endfor %}
{# Add an ellipsis if there are further next pages. #}
{% if ellipses.next %}
<li class="pager__item pager__item--ellipsis" role="presentation">…</li>
{% endif %}
{# Print next item if we are not on the last page. #}
{% if items.next %}
<li class="pager__item pager__item--next">
<a href="{{ items.next.href }}" title="{{ 'Go to next page'|t }}" rel="next"{{ items.next.attributes }}>
<span class="visually-hidden">{{ 'Next page'|t }}</span>
<span aria-hidden="true">{{ items.next.text|default('next ›'|t) }}</span>
</a>
</li>
{% endif %}
{# Print last item if we are not on the last page. #}
{% if items.last %}
<li class="pager__item pager__item--last">
<a href="{{ items.last.href }}" title="{{ 'Go to last page'|t }}"{{ items.last.attributes }}>
<span class="visually-hidden">{{ 'Last page'|t }}</span>
<span aria-hidden="true">{{ items.last.text|default('last »'|t) }}</span>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
Remaining tasks
- Review code.
User interface changes
- Minimal *visual* changes; the current proposal introduces the current page as a *link*, but it will be visually styled to not appear as a link.
- An improved page navigation experience for the visually impaired via screen-readers. Page navigation section will be announced by screen-readers as the "Pagination" section, and individual items will be read aloud with natural language such as "Next page" and "Previous page" as opposed to "next" and "prev"; similarly, the current page will be read aloud as "Current Page Six" as opposed to just "Six", and numbered pages will be read aloud as "Page Seven", "Page Eight", "Page Nine".
API changes
Currently, the proposal will change the unwritten "link label tags" API by adding the natural language version of the pagination items that are read aloud by screen-readers, so that they may be altered.
Original report by @criz
View the original report here (the summary here is too long for inclusion at this point).
Sources:
- BBC GEL Styleguide for pagination
- Zurb foundation pagination
- Google Webmasterblog documentation for pagination
- An accessible pagination pattern, by Mike West.
- SEO friendly Symfony2 paginator to sort and paginate
- CSS-Tricks.com Article on using lists for navigation
- Foundation:
ul.pagination li
- Bootstrap:
.pagination ul > li
- InuitCSS:
.pagination > li
- Gumby:
ul.pagination li
- GetWirefy:
.pagination li
What other frameworks/CMSs use:
Comment | File | Size | Author |
---|---|---|---|
#233 | interdiff-1912608-229-230.txt | 340 bytes | lauriii |
#233 | 1912608-230.patch | 31.08 KB | lauriii |
#229 | 1912608-229-seven-after.png | 7.26 KB | star-szr |
#229 | 1912608-229-seven-before.png | 7.24 KB | star-szr |
#229 | 1912608-229-stark-after.png | 13.41 KB | star-szr |
Comments
Comment #1
crizMaybe the title attribute would make sense too of course (like we have it now):
But maybe we can get rid of the "Go to last page" and the "Go to the first page" list items.
Comment #2
jwilson3Seems like #1913076: twig general pager may be a duplicate of this, but that has some alternate idea, to lose the ul/li entirely.
Comment #3
mortendk CreditAttribution: mortendk commentedi had more my head swapped around how the twig template could work than actually the markup ;)
to repeat the idea
pager.html.twig:
got pointed to some good info here about pagers at the sprint in sydney
https://github.com/KnpLabs/KnpPaginatorBundle
Comment #4
jwilson3I'm kind of with morten on this one...
I'm not sure but if screen readers read the ordinal in ordered lists, that would introduce confusion. eg based on the sample code in comment #1, a screen reader would read something like "Six, Go to page twelve", "Seven, Go to page thirteen", "Eight, Go to next page".
The only thing I half worry about with spans is the whitespace generated between them. Would be good to see if someone could come up with a jsbin prototype using spans, (completely themed with some border/background around each item, and prove that there isn't any whitespace between the items. Also, keep in mind that simply inlining them may not work correctly on narrow screens.
We should look for some solutions that other projects are already using that are mobile friendly, and see how they are doing it.
Comment #5
rikki_iki CreditAttribution: rikki_iki commentedI think UL, tbh.
~All css frameworks refer to an LI at the very least, if not a UL explicitly, so if the goal is to make it easy for newbie themers then css frameworks should be taken into consideration. It's also consistent with other navigation. If menu is a UL and breadcrumbs are a UL (i'm assuming), then pagination should be the same.
I also think we should be aiming to put the link context inside the link text rather than a title attribute (as suggested in the accessible pagination pattern). The title attribute isn't used by screen readers as it was intended and is no longer recommend for links (see http://www.paciellogroup.com/blog/2013/01/using-the-html-title-attribute...).
Something like:
A bit more markup I know, but more accessible...
UPDATE: moved rel onto the anchor.
Comment #6
jwilson3#5 sounds reasonable, but...
* by "~All css frameworks", which ones did you check, exactly? link?
* why is the
rel="next"
on the LI and not the anchor tag itself?Comment #7
rikki_iki CreditAttribution: rikki_iki commentedI didn't think much about the rel prev/next. My understanding is they belong in the
<head>
.But failing that I would agree they should be on the anchor tag.
As for css frameworks:
Foundation: http://foundation.zurb.com/docs/navigation.php#pagCode
with css selector: ul.pagination li
Bootstrap: http://twitter.github.com/bootstrap/components.html#pagination
with css selector: .pagination ul > li
Inuit: http://inuitcss.com/
with css selector: .pagination > li
Gumby: http://gumbyframework.com/
with css selector: ul.pagination li
GetWirefy: http://getwirefy.com/features.html#pagination
with css selector: .pagination li
It's pretty fair to say if the framework covers pagination it's using an li.
Comment #8
mortendk CreditAttribution: mortendk commentedtbh i dont think we should look at other cms'es and how they do the markup - we should look for the best kinda markup we can posibbel bring to the table.
The reason i dont like the li model & wants a span instead is that its not a list + we then have all the fun of having to add additional css to make it work the way we want it. (float:left, display:inline-block etc)
remember the pager.html.twig template will be easy to find, so it can be changed very easy to whatever you want.
Comment #9
rikki_iki CreditAttribution: rikki_iki commentedIt's not a list of available pages?
I know it requires extra css. Ideally we already have those float/display rules defined in a reusable .inline-list (or similar) class, applied to all menus. I just think you'll get a lot of people changing it back to a list.. possibly more than those who agree that pagination isn't a list of links. Sorry to be pest...
Comment #10
mortendk CreditAttribution: mortendk commentedyou are not a pest this is whats needed to get better markup :)
Comment #11
jwilson3I think at this point we need two side-by-side jsfiddles themed exactly the same way (inline horizontal format, that supports mobile/small screens), that can help everyone compare and see visually if a
div.pager span
is better than aul.pager li
.The criteria for calculating which is the winner should be:
Eg, its already obvious that div and spans add more bytes than ul and li ;)
Eg, its already obvious that divs and spans are only there for decoration/wrappers, while ul/li adds semantic structure (ie, elements grouped as a sequential list).
By cleanliness, we should consider things like extra css rules to make something appear inline that by default is not (i.e. ul/li loses that one). We need to ensure both solutions satisfy the basic default pagination guidelines:
text-align
Other than these, what other criteria am I missing?
Comment #12
jwilson3Also one observation:
I really am starting to get bothered by this pattern in Drupal. It is just not semantic to keep holding onto concepts like "div.inline-list ul".
In addition to not being semantic, this makes it too easy for your theme CSS to become really ugly and bloated, because if you want to make *one* exception out of all the places on a site that use this you have to add YET ANOTHER WRAPPER (or at least use an existing one from higher up in the dom) to *override* this specific case. Its at least been my experience that adding another class on the ul itself, would be the ideal solution, but that it is really more of an inconvenience than a convenience, its easier just to dirty up your CSS with something like:
Because of the wrapper that applies styles, even if you added a class to the ul, your code would *still* look something like this horrendous confusing information:
When this should all really just look like:
Yes. this is somewhat of a tangent and a rant, but the point is, if we are going to inline a ul/li here *please* dont add a wrapper div with a class to do it. JUST USE THE
ul.pagination
ORul.pager
CLASS!!!! /RANTComment #13
rikki_iki CreditAttribution: rikki_iki commentedOh sorry I never meant an extra div. I completely agree wrapper divs are rubbish. I think a js fiddle is a good idea. I'll put one together with what I'm suggesting and a comparable span version then we can discus it better.
Comment #14
rikki_iki CreditAttribution: rikki_iki commentedHey all,
Here are the jsfiddles.
Span version: http://jsfiddle.net/BZDWz/1/
List version: http://jsfiddle.net/2FmyK/1/
List version has an extra 10 lines of css, but I'm suggesting we also use this inline-list class on our menus and breadcrumbs (on the ul, not a wrapper div).
The markup has equal lines of code. Span version has 4 extra characters per line.
My only issue with the span version at this point is it's readability suffers a little from the double span.
The inner span could be substituted with an
<i>
tag if no one objects.It would certainly improve the readability and reduce the number of characters. eg...
The .pagination class is purely for presentational purposes and should be the only thing a themer needs to worry about.
The css meets basic pagination needs as outlined in #11.
Hopefully this will help :)
Rikki
Comment #15
jwilson3Thanks Rikki. Nice work.
I still stand against this, because now while we embrace responsive design, it is often the case that something that was "inline" for desktop is no longer inline for mobile. this is akin to adding a class="blue" to an element, for desktop, and then have to write special overrides for mobile that shows something like .blue { color: green; } for mobile. This illustrates the problem with mixing visual style, presentation (and layout) into the html.
I suggest we forget about "inline-anything" and "element-invisible" classes, and just start writing simple, straight-forward (and opinionated) defaults for the specific case to which it pertains: Eg
ul.pager { display: inline }
and.pager i { display: none; /* or whatever */ }
. This makes it trivially easy to override and customize for difference media queries without the need for stylesheet directives that seem to contradict themselves in our themes.I'm not sure about the negative margin solution myself. My suggestion would be to simply delete the whitespace between the LIs (this could be done in twig for either of the cases (span's or lis), and yes, it decreases readability. I *think* there is a patch somewhere from @sun that actually fixes this issue in core, by removing line-breaks after
</li>
in core (not sure).Comment #16
rikki_iki CreditAttribution: rikki_iki commentedYeah I wasn't sold on the negative margin either, it was just the simplest one to add (and remove).
I think there is a case for and against abstracting out those repeated rules into their own class (OOCSS). It means less css as they don't need to be repeated on each element we need to inline or hide, and I think it's fairly safe to assume that no designer will ever want the text 'Go to page' visible. Where text is only ever added for accessibility purposes I think it's important to have a generic class to visually hide them.
I agree these elements (menus in particular) won't always be inline. Menu probably needs it's own solution. But pagination and breadcrumbs generally stay inline on smaller screens don't they?
It's also easy for a themer to take the class out of the template, that way a novice themer doesn't need to worry about how to inline a list, and an experienced front-end dev can quickly remove defaults and take full control.
Comment #17
crizthanks for the jsfiddles, this is really helpful!
@ list vs. spans
I am not sure what would be the best solution here.
My thoughts:
- All pager elements don't need to be ordered (though mostly they are, depending on the styleguide). So at least ol makes no sense. On the other side I see no difference to menu items here. Is there any intention to get rid of the lists also for menus?
- I see the issue with the .inline-list class. But this is a general css architecture issue: http://drupal.org/node/1887918 Imho we shouldn't make assumptions how pagination should look like. So when using lists I am in favour of not such a class -> some more css lines needed. spans would be much better here.
- It is a point that every other cms/framework is using list items for pagination. Probably it would be more convenient for people coming from outside when we use lists.
Maybe we can summarize this issue in the following question:
Do we want to introduce new markup patterns for navigation in Drupal?
There are some points, but maybe the world is not ready yet for this. Read the following article and its comments: http://css-tricks.com/navigation-in-lists-to-be-or-not-to-be/
Comment #17.0
crizUpdated issue summary.
Comment #17.1
crizAdding some ressources mentioned in discussion.
Comment #18
steveoliver CreditAttribution: steveoliver commentedMy $0.02:
<li>
pagers? -1This list proudly powered by
<ol>
.Comment #19
jwilson3The accessibility point brought up in the css-tricks article is very interesting and convincing, but only on the condition that we do introduce a
<nav>
wrapper, to make the otherwise semantically "weak" series of spans, to regain some semantic karma points. Just wanted to point this out in writing because some of the previous examples in this thread didn't use the<nav>
element, but the jsfiddle does...http://jsfiddle.net/BZDWz/1/ wins?
Which means morten's original code would be pretty close except for the nagging issue of the extra spaces and negative margins. All the spans could appear printed out on the same line, mitigated by Twig whitepace cleanup controls.
Comment #20
crizAnother notable point:
- UL or OL seems not be allowed to use role="navigation": http://www.w3.org/html/wg/drafts/html/master/dom.html#wai-aria
As it would be really good to get rid of any wrapping element this is a strong argument for using no lists.
Also we have no hierarchical elements in paginations, so we can safely use spans in my opinion.
See this summary of above mentioned css-tricks article: http://codepen.io/chriscoyier/details/ztxvw
Comment #21
jwilson3I agree on that point.
One more point: it looks like HTML5.1 recommendation depicts that we should be putting a header element *inside* the
<nav>
not outside.what if we change from:
to
or something similar?
Comment #21.0
jwilson3Added KnpPaginatorBundle to sources.
Comment #22
Snugug CreditAttribution: Snugug commentedA handful of thoughts on this:
<ol>
lists, so we shouldn't use thosemenubar
,menu
, andmenuitem
roles. That's for menus though, maybe not applicable for this.With this all in mind, I'm in favor of the following:
<nav>
tag<ol>
Comment #23
crizOkay, trying to summarize all thoughts into 2 versions using Drupal 8 coding standards.
List version:
Span version:
Some notes:
Comment #24
jwilson3Why the change from classname "pager" to "pagination" ? IMO it's needless byte bloat, for questionable improvement on clarity, and introduces inconsistency with the existing php (now twig) theme template / function names.
I know I've made the point earlier, I agree with you in #16 where you state that the inline issue is a CSS architecture issue, but I still maintain that the layout in this case should be left up to the theme to implement, not done via a handy default layout ".l-inline" class. This is because, now with Twig and the Attributes object, it is now trivially easy to override the template file and an an extra CSS class to display the ul as inline if you so desire (which would automatically override any other default layout styles provided by Drupal, were we to just use the given semantic classes), however it is not so easy to *remove* such a class -- AFAIK, you still have to implement a PHP template preprocess and use PHP code (or deal with crappy over-qualified css workarounds like what I mentioned in #12). So, just as we wouldn't want to put a default grid-width class on the container element of the pager, I dont think we should put an inline. This argument alone, makes me really sway my vote towards the SPAN solution, unless we can agree to abandon the concept of "l-inline". Opinionated, yes. Wrong, maybe ;) Let me know what you think!
Comment #25
crizAh yes, some good points. The l-inline class is really bogus, let's remove it. As I understand it now the l-classes should only be used for containers, like "l-header" or "l-footer". My fault.
Was also thinking about using .pager, as it saves some characters, means the same and it is the current approach.
I also talked to fubhy about all this and he is against having another hierarchy with .pager-list, so the list items would just get a .pager-item class. He is right of course. Makes the list version much nicer.
So, here the updated versions:
List version:
Span version:
Any more ideas? When we agree on a version we should try to get some feedback by screen reader users, as Snugug proposed.
Comment #26
jwilson3Could we maybe get away with placing these cleaner classes on an inner wrapper element (either an A tag, or a span) inside the outer li.pager__item element:
I understand the need to have another wrapper element between the .pager__item element, and the actual content, so i might propose something like this instead:
Comment #27
oresh CreditAttribution: oresh commentedCode with changes from #26 + some of my changes.
'Pagination' is not a label, it's a header of pagination block, though invisible.
I wish we can move the arrows from code to css in pseudo ::before or ::after of the
<span> or <a>
elements. It makes more simple to change the text inside it or completely remove without any php work.Comment #28
jwilson3Screen readers apparently skip the
…
. I agree with moving the html entity glyphs that pagers use into CSS before and after pseudo selectors, where it will be a heluva lot easier to remove (or change them) with just CSS and not have to dig into a template file.But you didn't incorporate all of the changes I suggested. The problem with your version above is that now the current page is inconsistent with the other items in the list, which all have two elements (the LI and the A for links, and the LI and the SPAN for the ellipses). I think we need another SPAN around the active page text, and to move the pager__active to that SPAN. Also, the pager__first and pager__next, and pager__last should be moved to the anchor tag.
Comment #29
oresh CreditAttribution: oresh commentedCan we just drop
<li class="pager__item">
and add this class to a/span element ? The further we go - the less need i see in the li/span wrapper. Just having class on the<a>
covers 90% use cases for the pager. Ispacially now that we don't support IE7 and can use display: inline-block which is just awesome.Comment #30
jwilson3I was trying to come up with a reason why we need the extra wrappers, but couldn't. #29++
I've come up with two models, the first one implements the feedback from #29:
The second, is uber-minimalist, and uses an
<i>
for the ellipsis (hat tip rikki_iki, #14) and a<b>
for the current page.And, of course, the accompanying CSS, for clarity of where we've moved some of the HTML Entity markup.
Now that is some serious clean dream code there -- shaving bytes and splitting hairs.
The keen eye will also see that I changed
pager__ellipses
(plural) topager__ellipsis
(singular) to match singular form ofpager__link
.Comment #31
jwilson3Tagging for a11y review.
Comment #32
jwilson3Heres a fiddle containing the uber-minimalist version in #30: http://jsfiddle.net/kZr7k/
Comment #33
rikki_iki CreditAttribution: rikki_iki commentedI like this no list version now :)
I didn't realise you would need PHP to remove a class.
Couldn't the
<i>
tag wrap the 'go to page' text as well? http://jsfiddle.net/kZr7k/1/Comment #34
oresh CreditAttribution: oresh commented@jwilson3, this minimalistic version is awesome! jwilson3++
It really covers 99% of needs of a themer and it's still can be easily customized for the remaining 1%.
Fro those who see the code still being gigantic, check the code without hidden elements:
This is the smallest BEM version of pager I can think of :)
And even more - it becomes very stable because of only 1 level deep of DOM and class names.
Here is the minimum styles for it : http://jsfiddle.net/MZ9Qb/
It's almost the same as removing list-style, padding and margins from
ul / li
elements. But the markup is cleaner.The only thing i think we should add a common class to first/last/prev/next, something like
.pager__navigation
.It won't add a little bit of extra markup, but it will be easier to give those elements common styling.
Comment #35
crizgreat, the more minimalistic the better ;)
A few things:
<i>
for the ellipses? Semantics should go over readability I guess and<i>
is meant for text, also in html5: "Represents some text in an alternate voice or mood" http://www.w3.org/International/questions/qa-b-and-i-tags.en. Same for the<b>
.
should be present, isn't it? And for the sake of accessibility I think we should add some meaningful (invisible) text in html OR/AND use role="presentation".Comment #36
crizAbout removing classes and ellipses and arrows and stuff see morten's twig template in #3. Done like this it would be easy.
Comment #37
oresh CreditAttribution: oresh commentedi like @criz version.
- H4 just because it has default font size of 1em. The pager is not an important header at all. So making it h4 will print the same base page font size, only bold - which is ok for a pager.
- we don't need the
inside the ellipses - it will create an extra space. Empty is perfect - if we remove the :before of ellipses, the element will just count as empty. But with space you'll have to hide it.I would love to stop on this version:
1. all elements have common class, independently of element type
2. all variations have their class name
3. Without having wrapper we can easily use flexbox in future for the pager
4. Arrows and ellipsis is fully customizible just from css
5. this markup provides excellent base.
About (5) - for exmple for breadcrumb we could exactly the same markup, only adding .breadcrumb class. http://jsfiddle.net/Uaa6M/ The only problem with that - arrows will be part of link, so it's a bit silly :D But it's still possible!
Comment #38
crizGreat. By the way, the #dreammarkup metaissue says:
Comment #39
oresh CreditAttribution: oresh commented@criz - it's not clear yet. We need accessibility review - headers are seen in readers, if we could understand what we should show as headers in readers and what should show as labels or smth - it would be just great. for now just using header element )
Comment #40
jwilson3You know, I got to thinking about the active item...
Everywhere else in Drupal navigation (eg menu lists for example) a reference to the current page is rendered as a link, and an active class is added. Why do we make a special case for the pager?
Could we not also have the current page be a link, styled differently (or styled like Drupal styles active links by default)? Would this simplify and clean up the markup? Or is there a convincing argument for why we need to use plain text for the current page.
Comment #41
jwilson3Self-follow-up for #40....
I just played with the fiddle from #37, and realized that with the current page as a link it would take *more* lines of css code to null out any
a.pager__item:hover
code you create for the active page (generally, you don't want to see any hover state changes when you hover the active page). So perhaps, that by itself, is reason enough to not do #40.All good in the hood.
Code in #35 (and accompanying fiddle in #37) are good to go.
Comment #42
mortendk CreditAttribution: mortendk commentedone of the basic principles in the TWIG template thinking is that we wanna build for the 80% not for 100% and that we want to keep the markup & css as small as possbile, so we add instead of removing (i know its crazy talk )
so imho we should remove the pager__item cause we can easy target the a with a .pager a
If your theme needs a little bit of pager__item love its easy to add, and a themer dosnt need to remove it
whatta ya say to this code:
Comment #43
betz CreditAttribution: betz commentedDoes it make sense to have it like this?
Comment #44
oresh CreditAttribution: oresh commented@betz,
nono wrapper for elements, it can break using display:inline-block for example.
And.. oh there are cases, it's not the best idea and I'm not sure it will be used much.
@mortendk,
you are leading back to the Pitfalls described in the new CSS Architecture:
"Pitfall: Relying on HTML structure.
Mirroring a markup structure in our CSS selectors makes the resulting styles easy to break (with markup changes) and hard to reuse (because it’s tied to very specific HTML)."
I've seen you doing that for more issues related to markup. As you said - we are adding instead of removing. This rule also should be applied to class names.
Adding them I hope to keep the weight of any base component equal to [0 0 1 0] (1 for class name);
This makes it really easy to override if needed, and it stops being depended on html.
Does it make sense? :)
Comment #45
mortendk CreditAttribution: mortendk commentedJust had a talk with vincenzo @falcon03 about removing the
<ul><li>...
His recommendation is to keep the li's cause screenreaders works better with them (list amount of links etc)
so i guess its back to the drawing board ;)
Comment #46
mgiffordAlways better to have the more semantic option for accessibility. Screen reader users can pull meaning from well structured text.
Was an animated conversation, wish I was there for more of it - https://www.flickr.com/photos/mgifford/8763090948/
Comment #47
ry5n CreditAttribution: ry5n commentedI’m down with @Snugug in #22. If we choose the right ARIA roles, we might be able to still announce item count (#45).
General notes
- Since
<nav>
is a sectioning element, we may as well use<h1>
.- The icon component here is really a separate issue, but it means we don’t need special classes for the first/last next/prev links. See #1849712: Add theming template and prepare logic for rendering icons.
Accessibility notes
RE: the 'menu' role, the ARIA spec says:
So I am not entirely sure it is appropriate. However, the 'list' role is for “A group of non-interactive list items” so menu seems to fit best.
I tested this in VoiceOver on Mac OS X. It reads out:
- 'Entering navigation landmark (menu 7 items)' when entering the nav
- 'First page (menu item)' on the first link
- 'Next page (menu item)' on the next link
- '(Current) page 2' on the active link
- etc.
- 'End of menu’ when navigating past the last item.
CSS architecture notes
The new CSS standards say to use design semantics to apply styles to elements. Since we can’t make assumptions about design in core, we have to be conservative about what classes we apply. That means few if any utility classes like 'clearfix' or 'l-inline' etc. As noted, they are useful in themes but problematic in core.
I’ve noticed a couple of common issues as folks come to grips with the new CSS standards. Some of these appear in various proposals here:
- Variant classes used without the base class. Since variants like .pager__item--first only include styles needed to modify .pager__item, variants must appear with the base class in the markup:
class="pager__item pager__item--first"
. Yes, it’s verbose, but it’s the best choice we have until CSS supports some kind of module inheritance.- Mixing up states and variants. 'pager__item--active' is not a variant of 'pager__item'; it’s a state. As such, the markup should be
class="pager__item is-active"
and the CSS would be.pager__item.is-active {}
. I like to think of state classes as custom DOM states analogous toa:active
.Comment #48
mgiffordI really don't know what the fuss with lists is. Taking @mortendk guide in #42, adding in lists is easier to understand and takes 9 characters '
' while adding 'role="menuitem"' to every item adds 14 characters. If the goal is "to keep the markup & css as small as possible", then list items aren't adding much.
In #22 @Snugug wasn't opposed to UL, but rather OL. He was arguing for use of ARIA roles & the NAV element.
Anyways, this is riffing off the previous code:
Comment #49
manarth CreditAttribution: manarth commentedI see a lot of "Go to page </span>X" here: the "Go to" is already implied by the link tag, and would become very repetitive.
<span class="element-invisible">Page </span>X
,Next<span class="element-invisible"> page</span>
should be enough.As for the lists vs divs/spans, historically, good accessible markup has used lists for navigation items, so many screenreader users will have become used to that convention (and may, for example, use a shortcut to skip through each list on a page, looking for a navigation control). You can also skip over a list easily, if you recognise it as a navigation control that you don't want. I'm not sure that's as easy with divs/spans. That said, I haven't done any significant a11y work with HTML5 elements, so I don't know how the
<nav>
element affects this. It'd be great to have some user-testing or feedback from screen-reader users around this.Comment #50
mgiffordAgreed on the shortening of the text. Good suggestion @manarth
Also agree for the need for greater user-testing.
I've been trying to rally folks behind this, in various institutions but so far I've had no real traction.
Comment #51
dcmouyard CreditAttribution: dcmouyard commentedHere is the pager markup that I currently use:
We probably don't want all of those classes in the Stark theme, but they can be added to Bartik and Seven. I also add icons to the first, previous, next, and last items using
:before
in CSS.Comment #52
mortendk CreditAttribution: mortendk commentedwe dont want any classes in the stark theme unless theres a really really really good reason for it ;)
Comment #53
star-szrMoving to core queue.
Comment #54
jenlamptonCould someone please update the issue summary with the current proposed syntax?
Comment #55
criz@jenlampton: Yeah, will have a try...
Comment #56
jenlampton@criz can you assign this issue to yourself so that we know you are working on it?
Thanks!
Comment #57
crizsure.
Comment #57.0
crizmeta issue added
Comment #58
crizHere is an issue summary.
Current version using lists:
Seems to have more advocates right now (e.g. mgifford and some other a11y guys) than the version without lists.
Markup based on comment #48.
Changes:
- Removing
"id=pagination"
in h4 (as there could be more than 1 pagers on a page this could be conflicting), changing to aria-label- Adding
"pager__item"
and"pager__label"
css classes as pointed out in comment #47- Adding shorter hidden texts (comment #49)
- Changing from active-class to state (comment #47)
- Adding icon markup as proposed here: https://drupal.org/node/1849712 (comment #47); But I am not 100% sure that we should assume that everybody needs this icon markup here.
- Changing class
"element-invisible"
(d7) to"visually-hidden"
(d8) https://drupal.org/node/1849712 (comment #47)Current version without lists:
Markup based on comment #35.
Changes:
- Adding shorter hidden texts (comment #49)
- Removed
inside of ellipses (comment #37)- Adding
role="menuitem"
(comment #47)- Changing from active-class to state (comment #47)
- Adding icon markup as proposed here: https://drupal.org/node/1849712 (comment #47); But I am not 100% sure that we should assume that everybody needs this icon markup here.
- Changing class
"element-invisible"
(d7) to"visually-hidden"
(d8) https://drupal.org/node/1849712 (comment #47)Comment #58.0
crizUpdated issue summary.
Comment #58.1
crizAdding problem/motivation.
Comment #59
crizAnother thing: When adding the icon markup instead of the
.pager__item--variant
classes we maybe don't need the.pager__item
classes itself also. Maybe ry5n can confirm?This would save some characters and would make the markup for the version using list-items looking like this:
Comment #60
ry5n CreditAttribution: ry5n commented@criz: Yes, we can do away with a class on the individual list items. I’d like to standardize on this pattern with @jenlampton and @mortendk: In most cases, for `ol` or `ul` we can add a class to the list and allow descendent items to be styled using a child selector (`>`). So I would add `.pager__items`to the list (I think a class name with “items” in it is a good convention barring anything else).
I also removed the pager__label class on the heading: since it’s hidden, it shouldn’t need to be styled. BTW, does anyone know why we have a hidden heading *and* an aria-label attribute? Won’t that cause aria-savvy screen readers to read out something like “Entering navigation; Pagination; Pagination List”. *If* that’s the case, it’d be a bit verbose. Also per #2052473: Add aria-label or aria-describedby attributes to all <nav> elements, I’ve moved the aria-label to the
<nav>
element. I also removed the navigation role on the `ul`, it seems weird to have nested navigation landmarks. Needs further a11y review.Comment #60.0
ry5n CreditAttribution: ry5n commentedUpdated issue summary.
Comment #61
crizThx! Updated the issue summary.
I think we even can go with
.pager__items li
instead of child selectors then, as the breadcrumb navigation will never be a multi-level-list (list in a list). We should be careful about introducing selectors like.pager__items > li
.Comment #62
ry5n CreditAttribution: ry5n commentedSince the CSS really is a separate issue, we’re in agreement.
Comment #63
dcmouyard CreditAttribution: dcmouyard commentedSince we're using aria-label on the nav element, we can get rid of the h4.
Also, shouldn't we remove the
<a>
on the current item?Comment #64
ry5n CreditAttribution: ry5n commented@dcmounard Makes sense to not have an empty link like that, although if it were disabled that might be sufficient. The alternative (which would also be fine) would be to replace the
<a>
with a<span>
for the active item, and add a class so stylesheets can target the link/span independent of element type.Also, I just noticed we have
role="presentation"
on the ellipsis item. Shouldn’t screen readers read that out? I imagine an unannounced jump from page 4 to page 12 would be confusing without it.Comment #65
jwilson3I would agree with removing role="presentation" from the ellipsis.
http://stackoverflow.com/questions/453189/what-do-screen-readers-do-with...
Comment #66
mgifford@dcmounard There's been a bunch of discussion about this here #2052473: Add aria-label or aria-describedby attributes to all <nav> elements & #2045039: Cleanup HTML heading structure
More discussion over on GDO:
https://groups.drupal.org/node/157959
Comment #66.0
mgiffordUpdating proposed version by comment #60
Comment #67
mortendk CreditAttribution: mortendk commentedComment #68
adamjuran CreditAttribution: adamjuran commentedComment #69
adamjuran CreditAttribution: adamjuran commentedThis is my very first contribution to Drupal, so please be nice.
This patch contains the following:
Comment #71
mgiffordjust a reroll.
Comment #73
dawehnerIn general I wonder how much in scope of this issue is to also change the mini pager of views.
Here are some small points in the review.
\Drupal::request()->getRequestUri() should return you the value.
spaces all over the place
Out of scope and totally wrong
Comment #74
adamjuran CreditAttribution: adamjuran commentedThanks for the feedback, I'll clean things up and take another shot at the patch.
Comment #75
adamjuran CreditAttribution: adamjuran commentedI've debugged all of the errors from Simpletest and rerolled.
Note, I didn't use any of mgifford's work but instead continued from my original patch.
Comment #76
adamjuran CreditAttribution: adamjuran commentedSorry for the preview (and EMPTY) patch. This time with actual data plus interdiff!
Comment #78
adamjuran CreditAttribution: adamjuran commentedSome of my earlier work doesn't play nice with the views pager, so going to keep on working on it.
Comment #79
adamjuran CreditAttribution: adamjuran commentedA few rogue instances of filter_xss_admin were causing issues with the CommentBlockTest and GlossaryTest. This time skipping the interdiff because I think the other patches are a little messy and confusing. Still learning this whole process. :)
Comment #81
adamjuran CreditAttribution: adamjuran commentedComment #82
adamjuran CreditAttribution: adamjuran commentedSomehow I had lost the necessary changes to the various tests (needed because the markup changed obviously). This patch includes those, fixes some oversights on how I implemented getRequestUri() originally, plus a CSS tweak to hide the pagination icons in views previewing.
Comment #83
jwilson3Lots of trailing whitespace was introduced, as well as files with no newline at the eof. Please refer to the coding standards and if possible setup your editor to auto-fix these issues for you as you code.
"First page", "Previous page", "Next page", "Last page", all need to be translatable (eg with
{{ 'String'|t }}
?)http://twig.sensiolabs.org/doc/tags/for.html Suggests separating key and value with a comma and a space.
<span>Page </span>{{ item }}
in theory presents a problem for translatability, because the unit of text that needs to be translatable is "Page @count" (thinking in Drupal 7 terms).To my knowledge, this is overqualified, I might be wrong (if so, link?)
Why are we using three dots here instead of "\2026" ?
Comment #84
jwilson3Not 100% sure on this, but can't there be more than 1 pager on the url parameters? If so, sounds like we may need a test for this.
Comment #85
adamjuran CreditAttribution: adamjuran commentedThanks, jwilson3! I'm on it!!
Comment #86
adamjuran CreditAttribution: adamjuran commentedMy reroll included fixes for the following from #83
And re: #84, there is a testTwoPagers() function in CommentPageTest.php which passes, but that may not be testing for what jwilson3 was imagining.
Comment #88
jwilson3Looks like the trailing whitespace issues are gone. Good! I use Sublime Text 3 with the TrailingSpaces package installed via Package Control.
Screen readers will speak this as "Page two two". le sigh. :-/ I suppose the former solution
<span ...>{{ 'Page'|t }} </span>{{ item}}
is the lesser of the two evils, but we would need a nod from i18n people first.But there seems to be one more major problem with this implementation. The "?" in
{{ current_path }}?page={{ key }}
needs to have the ability to be an "&" in the case when the current_path already contains a query string with other URL parameters. Its hard to believe that all tests are passing the way this code is written and makes me thing we aren't testing this scenario well enough. I could be wrong about this.Comment #89
adamjuran CreditAttribution: adamjuran commentedCool, now to move the simpletest files so that the patch applies.
Comment #90
adamjuran CreditAttribution: adamjuran commentedWe could go back to generating the pager paths in the preprocess function, which I believe would solve that problem. But it creates a new one: matching the paths with the appropriate list item in the twig template.
Comment #91
adamjuran CreditAttribution: adamjuran commentedRerolled with correct PSR-4 filepaths. We still need to iron out the two issues raised by jwilson3 in #1912608-88: Update pagination markup for new CSS standards and improved accessibility before this is RTBC.
Comment #92
aspilicious CreditAttribution: aspilicious commentedCan we have some screenshots to ensure everything is still ok. (spark vs bartik vs seven)
Comment #93
adamjuran CreditAttribution: adamjuran commentedBartik needed a small CSS adjustment, hence the rerolled patch. Screenshots.zip contains screenshots for Bartik's and Seven's dblog and views preview pager. Other pagers available on request. I didn't make any changes to the Stark pager styles since there are, in fact, not any. Should there be?
Comment #94
adamjuran CreditAttribution: adamjuran commentedAdding styles for Stark and removing double page number for screen readers as per Lewis.
Comment #95
adamjuran CreditAttribution: adamjuran commentedAdded styles for Stark (in system.theme.css) and removed double page number for screen readers. Still have a question for a views guru about the way I'm generating the request URI. Relevant lines are 258-265 in pager.inc.
Comment #96
lauriiiFunctionality seems to work which is great!
Some things I'd like to point:
This should be removed.
Constants should be uppercase.
Comments should end with dot.
In general, all lines of code should not exceed 80 characters.
There should be white space before and after -
There should be white space after comma
Comment #97
adamjuran CreditAttribution: adamjuran commentedThanks, Lauri. I'll make your recommended changes.
Comment #98
adamjuran CreditAttribution: adamjuran commentedThis patch contains the following additions/changes from the previous one:
Note: because "item_list__pager" is the theme suggestion, we still have
<div class="item-list">
wrapping<ul class="pager__items">
Comment #99
lauriiiWe're green! I tested the patch by hand and it does what it should do. I'd suggest RTBC.
Comment #100
jwilson3This seems to be an overly generic style. also, according to standard class naming conventions, it should be .is-active. It looks like elsewhere in the other stylesheets this is done as
.pager__items .is-active
Please remove the lines of code that have been commented out.
Comment #101
adamjuran CreditAttribution: adamjuran commentedComment #102
LewisNymanYes that's right, according toe SMACSS you usually chain the class like this
.pager__items a.is-active
or ideally.pager__item.is-active
?Comment #103
adamjuran CreditAttribution: adamjuran commentedWith excellent guidance from Mark Carver, I properly restored the dream markup to the twig template. John Albin also helped in guiding me towards proper class naming conventions.
Comment #105
adamjuran CreditAttribution: adamjuran commented103: 1912608-pagination-twig-103.patch queued for re-testing.
Comment #107
adamjuran CreditAttribution: adamjuran commentedFound a small bug, fixed and ready for review.
Comment #109
adamjuran CreditAttribution: adamjuran commentedSomething in testActiveClass() is breaking here on d.o but it's fine when testing locally. Trying again. Also simplified ellipsis markup.
Comment #111
adamjuran CreditAttribution: adamjuran commentedRerolled to remove exceptions, but CommentBlockTest is failing on line 98. I'm a little at a loss as to why, but initial research makes me wonder if the URLs generated in the comment block are incorrect.
Comment #113
adamjuran CreditAttribution: adamjuran commentedRerolled.
Comment #115
adamjuran CreditAttribution: adamjuran commentedFor some reason I don't completely understand, the ellipsis character (…) was causing CommentBlockTest to fail. Using
…
fixed it.Comment #116
mgiffordThat's the right way to go, but don't think it's related to #44987: [meta] Use the UTF-8 ellipsis character instead of "..." in the user interface
Comment #117
adamjuran CreditAttribution: adamjuran commentedMoved the first/prev/next/last text from CSS files into pager.inc (so they are translatable).
Comment #119
markhalliwellThese strings, unfortunately, are not/cannot be translated because they are directly in the CSS.
We should instead use the
rel
attribute to populate this or even probably more appropriately thetitle
(although I am not entirely sure how the screen readers would react to a title being populated... data attribute mayhaps?):(first)
Why are we changing this? This really falls outside of the scope of what should really be changed in this issue.
Shouldn't this be changed to look for
.pager__item
instead of removing it altogether?Wouldn't having both an
aria-label
avisually-hidden
<h4>
cause a screen reader to announce "Pagination" twice?Furthermore, the
aria-label
is not translated either, should bearia-label="{{ 'Pagination'|t }}"
.Comment #120
adamjuran CreditAttribution: adamjuran commented1. that CSS is gone already as per Joel. Were you looking at the interdiff?
2. When we added a link to the current item in the dream markup, of course those tests have to change.
3. In the latest patch that change is already made.
4. I don't know, but that was from the dream markup in comment 60 I think.
Comment #121
markhalliwellThe issue summary is severely out of date.
Comment #122
mgiffordI'm doublechecking now, but I really think we can get rid of the
aria-label="Pagination"
in #119.4 above. @Mark Carver - good catch on the CSS as well.@scaragucc' - #60 is coming from #2052473: Add aria-label or aria-describedby attributes to all <nav> elements - It doesn't make sense though where there are duplicate titles for the heading.
Comment #123
mgiffordThis would add semantic value using ARIA to the navigation:
That is inline with other efforts to with navigation.
Comment #124
mgiffordIn #122 I was just looking at Mark's comment. Looking at the patch in #117 I can't find #119.1. @scaragucc' replied nicely to 2 & 3.
I've re-rolled the patch to address the concerns of duplication with #4.
Comment #125
adamjuran CreditAttribution: adamjuran commented#117 needs to have the extra span (the visible one) removed from the pager links. mark explained to me that we can add a data-label attribute and access that in the CSS content property. I will take that on as soon as the issue summary is updated and we know exactly what else needs to be done.
Comment #127
mgiffordseven/style.css moved to seven/css/style.css
Comment #129
jwilson3Were going from using « and ‹ to using « and <, which looks horrible in most fonts. TBH,
We should either:
a) use the html encoded version of ‹, which is
‹
and its counterpart›
instead of < and > respectively?OR
b) Just revert to using the strings that are there now.
I'm of a mind to revert, to lessen the need for new string retranslations.
This looks to be overqualified. Would just
.pager__item
work there, or is the nature of this being in a ul structure causing weird inheritance issues?Lewis pointed out above in #102 that the ideal format here would be to us chaining of the form
.pager__item.is-active
. Again, not sure about inheritance, but it certainly looks cleaner to do it that way.Comment #130
jwilson3#2033211: Move Seven CSS files into css directory was reverted, so #127 is no good any longer.
Comment #131
mgiffordOk, I think this gets those 3 points. And ya, annoying with the reversion, but... The css seems a bit messed up:
Comment #132
jwilson3Patch is looking good.
I think we should use "‹ previous" and "next ›" for two reasons:
1) Drupal is UTF8, so there is no reason to not encode these entities in the source (this was an argument used in another issue from long ago when the arrows were first introduced, but i cannot find the issue to link it here...
2) as mentioned above in #129, switching to the HTML entities introduces needless string changes, impacting translators.
Couple nit picks with the tests:
Can we consistently use single quotes in all of the modified asserts in our tests? There is a mix of both single and double quotes. In some cases, this patch is already simplifying some of them to single quotes. Let's get them all.
In some of the test messages we're using "Element for X" and in others we're using "Item for X". I dont know if this is on purpose, if one means the actual link element, and the other means the wrapper list item, or what? In the cases above, we've switched from one to the other, but in other places the entire set uses "Element for X". Can we just use "Element for" instead of "Item for" everywhere for consistency?
Comment #133
jwilson3And yeah, this needs another re-roll now that #2033211 is back in, and now that #2227907 is in too.
Comment #134
jwilson3One more thing: Screen-readers do not read text in the title attribute aloud. Removing this text in the links actually reduces usability for sighted users who will not see any helper text appear when the links are hovered with a mouse.
Comment #135
jwilson3Found one more issue: the pager interval logic stopped working when $i > $pager_current. I propose to use absolute value.
Comment #136
jwilson3I've addressed all the issues my feedback above. I've also fixed some styles that seemed to have been inadvertently removed from some of the stylesheets in previous patches, and made some further adjustments in the Seven stylesheet which wasn't adding enough whitespace below the pager.
Also, I've finally updated the issue summary to show where we are at today, updating the code snippets and added the twig template proposal, for easier review. What started off as very streamlined "Dream Markup" flowered into let's do this Aria support thing out of the box. I don't think the two are diametrically opposed, but adding all the Aria stuff has certainly taken us away from streamlined and simple markup.
I think the goal at this point would be to provide a solid foundation from where themers can easily swap out the tags in the twig template without losing much of the aria support, and this latest round of patches from mgifford and my subsequent cleanup in this patch gets us there. I'm sorry that there is not an interdiff, but the problem was again that the patch would not apply, so I make my own improvements as I went along re-applying the patch by hand, so I didn't have somethign to base an interdiff from.
There is real tangible improvement here, notably in the css, best summarized by this part of the patch:
Comment #138
jwilson3This followup fixes a couple test case string cleanups that I missed from #136.
Comment #139
jwilson3Fixed last remaining failures from testTwoPagers() in CommentPagerTest.php where
$this->clickLink('Next page');
fails to navigate between pager links because the Anchor tags no longer have plain text links, but use HTML spans for visually-hidden text inside the links.Had to write a custom method: clickLinkWithXPath() (based on clickLink) which follows a link based on a provided xpath query that targets a specific anchor tag.
Comment #140
jwilson3Missed a minor cleanup.
Comment #143
jwilson3Hrm. I just globally searched and replaced all the tests that were referring to pagers, without realizing we haven't done any work on views mini pager here -- which is where the current errors are coming from.
Because the classes and styles for the pagers in core themes are affected by this code, I think we may need rope in the mini pager into this issue. Fun :-/
Comment #144
mgiffordThanks for tracking this down.. Another case were tests reveal something we'd overlooked..
Comment #145
adamjuran CreditAttribution: adamjuran commentedMike, I'm at Drupalaton now and was hoping to work again on this ticket at the sprints. Shall I, or do you want to keep on working on it? Thanks, Adam
Comment #146
mgiffordPlease proceed @scaragucc' and thanks for asking. Sorry I didn't get to this sooner.
Comment #147
lauriiiShould we take care of the views mini pager here or create a new issue for that? This issue is getting bigger and bigger all the time.
Comment #148
adamjuran CreditAttribution: adamjuran commentedGetting back into the mix!
Comment #149
lauriiiAfter discussion with @scaragucc' and @mortendk, I thought maybe we should create a follow-up issue for the views mini pager.
I also attached a patch where the mini pager test changes have been removed.
Comment #150
adamjuran CreditAttribution: adamjuran commentedSending to review.
Comment #151
joelpittetThis seems a bit odd to me, it's not purely presentational nor translatable. Can you explain this? I see you have hidden translations for screen readers which is good. Though if I were to translate my site to any other language those English words would have to be swapped out in the theme generate the css file on the fly? Maybe you have a work around?
Comment #152
joelpittetI also want to say, I like that template is filling out, more HTML in the template is looking great. Also love that this has more tests too. And BEMy class names too! Just because I'm against the words in CSS doesn't mean I don't like the patch. It's going in a good direction, I think just not that bit:) Nice work, keep it up!
Comment #153
lauriii@joelpittet: Im not sure if I'm missing something because I cannot find that CSS from #151 anywhere. Is that actually used somewhere?
Comment #154
joelpittet@lauriii oh my bad, I think I was reading a different patch #115, Not sure how that happened... my only guess is I took the bottom one in the IS instead of the top.
Hiding older patches.
Comment #155
mgiffordSo there is the follow-up issue with the mini pager #2318341: Views mini pager markup
I just rolled up an instance here http://s4c72eb8a63bda03.s2.simplytest.me/admin/reports/dblog
Seems RTBC to me. Here's a screenshot.
Comment #156
lauriiiMore functionality can still be moved to Twig files.
Comment #157
jwilson3@lauriii, This issue has been vetted by and has been worked on by a number of people now. The Twig file looks very complete. I'm not sure what else you would want in there that is not already there. If you can come up with a list, then we can collectively discuss and determine if any of it is valid, in order to change this back to Needs Work, or better yet, file as a followup.
Comment #158
jwilson3Whoops. I totally missed that you *assigned yourself* to keep working on this. Sorry for overstepping there. Have a blast!
A list of what you're going to move into the template would be good, particularly if its a great departure from the current patch which imho is ready to go in as is, because its very clean.
Comment #159
lauriii@jwilson3 No problem! I was thinking of moving spans for the screen readers from prerender to Twig, so it's easier to override if there's a need for that.
Comment #160
lauriiiOk here's my patch. What do you think? Is this change good or should we go with the more preprocess driven solution?
Comment #162
jwilson3Overall, I like this approach! Nice work!
At least some of the failures have to do with these lines:
They are missing
'rel' => 'prev'
and'rel' => 'next'
attributes.Comment #163
jwilson3One more thing, obviously we're not using a render function for the links here anymore, so the question is what, if anything, was using this hook_link_alter information, and why was that code added in the first place? You can probably check with git blame to figure out where/when it was introduced.
Comment #164
jamesquinton CreditAttribution: jamesquinton commentedComment #165
jamesquinton CreditAttribution: jamesquinton commentedAdded the rel attributes - test now passing locally.
Comment #166
jamesquinton CreditAttribution: jamesquinton commentedComment #167
jamesquinton CreditAttribution: jamesquinton commentedSwapped 'previous' to 'prev'.
Comment #168
jamesquinton CreditAttribution: jamesquinton commentedRe #163 - I don't think we need that anymore, as a themer can now easily override the markup using a template (unless I'm misunderstanding).
It looks like this was originally added here: https://www.drupal.org/node/1898474
Comment #169
jwilson3@jamesquinton, you're exactly right thanks for looking that up. I even commented a bit on that issue, and particularly comment #77 from Issue #1898474 is relevant here. Quoting myself, because I can:
with this patch, ideal world is now the real world :D.
-- FEEDBACK REMOVED --
Comment #170
jwilson3I edited my previous post to remove some feedback.... I had been thinking it might make sense to also move the title text and rel attributes straight into the template, and not even use the Attributes object, but I changed my mind about that because it reduces the flexibility, and is inconsistent with other templates. RTBC.
Comment #171
jwilson3Core reviewers, please also see #2318341: Views mini pager markup, which goes hand in hand with this issue.
Comment #172
jwilson3Please split these onto multiple lines. The text goes over 80 characters, and doing this will also be more consistent with the patch on comment #15 of the mini pager issue.
Comment #173
jwilson3Comment #174
lauriiiThank you for your comments @jwilson3!
I uploaded a patch where I split the attributes to multiple lines.
Comment #175
jwilson3Thanks for the fix @lauriii; back to RTBC.
Comment #176
jwilson3I spoke too soon. We still need to improve the Twig template documentation for all of the available variables. (This is one of the few last outstanding tasks mentioned in issue summary).
I'm adding Novice tags, in case someone wants to help out to write the twig documentation.
Comment #177
jwilson3Comment #178
jwilson3This needs to read "Will click the first link found with the given xpath query by default, or a later one if an index is given."
Comment #179
joelpittet@jamesquinton re: #167 I didn't see an interdiff for your patches so it's hard to see what you changed between the patches and just going on your comment, why is Previous becoming prev? prev isn't a word, which makes it tricky to translate.
Why is this prev?
Comment #180
joelpittetHere's the documentation on interdiffs for anybody looking: https://drupal.org/documentation/git/interdiff
It's the diff between the last two commits. The short hand is
git show > interdiff.txt
And I have a simpler workflow http://pittet.ca/drupal/sprint/patch if that helps.
Comment #181
jamesquinton CreditAttribution: jamesquinton commentedHi Joel,
I was referring to:
I'm not sure where the other 'prev' comes from. But yes, not very clear without an interdiff - sorry!
Comment #182
jwilson3It looks like"‹ prev'" was introduced between #115 and #117 when first/next/last/previous links were moved from CSS back to the PHP side, and my guess is that it was just t a copy/paste mistake. This patch removes that, and also addresses #176 and #178.
As a courtesy, I've also created an interdiff between the patches since #160 that were missing.
Comment #183
jwilson3Comment #184
jwilson3A couple issues and questions came up while writing the documentation in #182:
1) The
items.current
item is a magical unicorn special case, because it is the only one in the list that is a simple integer. I'm on the fence about even bringing this up, or if its worth fixing at all, but it definitely makes the documentation less clear.2) Similarly
items.ellipsis
is a special cases, because it also does not follow the structure of the other items. When you actually think about the semantics of the structure, the the proper name for the element should be "ellipses" since it is an array with two sub-elements. This works nicely for the for loop in our template, but it just doesnt seem clean. Dunno... since this is really debatable, again, perhaps better to leave it alone.3) Should other defined variables such as
element
,parameters
,quantity
, ortags
be mentioned in the template documentation if they are not used there? These four variables are defined but are primarily used in preprocess and are documented there as well. What is the rest of Drupal doing in this case?4) The preprocess structure creates many (needless?) temporary variables that refer to template implementation. Looking at you
$li_first, $li_last, $li_previous, $li_next
. This could be simplified, by just directly working on the$items
array, eg$items['first']['href'] = url($current_path, $options);
5) The preprocess code logic gate
if ($pager_total[$element] > 1) {
seems unnecessary because there is an earlier statement that breaks preprocessing if$pager_total[$element] <= 1
. I might be reading this wrong, so I'd appreciate another set of eyes on this.6) The
$pager_total[$element]
is used throughout the template_preprocess_pager function, even when we've already set the value to a temporary variable$pager_max
. It doesnt seem like the value of $pager_total[$element] ever changes through the flow of the code, so we could just use the$pager_max
everywhere for consistency and readability.Comment #185
jwilson3This patch addresses items 4,5, and 6 on #184... let's see what testbot turns up.
Items 1, 2, and 3, are just observations and questions, not really actionable without another dev's feedback.
Comment #186
lauriiiVery good clean up at #185! I looked the
template_preprocess_pager()
and it looks a lot cleaner now!I changed 1 and 2 to be own standalone variables because I was thinking about that few weeks ago also. I also wasn't sure if it would be worth fixing but probably it makes it at least a bit more cleaner.
I'm not sure what is the policy for 3 but I looked
pager.html.twig
and it has all the available variables listed in documentation which kind of makes sense.Edit: In my patch I also changed all the quotes to be single quotes.
Comment #187
jwilson3Ellipses sub-items need documentation (fixed in patch below).
Two issues here:
1) Seems out of place b/c the logic for setting titles for all other items is in preprocess. However, it is stupid to separate the "Current Page" string in two different places (preprocess for title, and template for visually hidden text) so I'm on the fence about what to do. Should we bring the title text into the template for next/previous/first/last too, or move this back to preprocess?
2) Whitespace around "Go to page X" is visible when you hover the links see attached screenshot (https://www.drupal.org/files/issues/pager-item-title-whitespace.png).
Leaving this in needs review to trigger test bot, but really its CNW for these two issues ^
Comment #188
jwilson3NR to trigger testbot.
Comment #189
lauriii1) The reason why I left those in preprocess is that its possible to override those values e.g. from Views UI. We could implement that logic also in Twig but for me it made more sense to leave them into preprocess.
2) I applied a fix for that. Do you think using trim is good solution or not because
{% spaceless %}
doesn't seem to work in that case.Comment #190
lauriiiFor some reason the patch didn't make it through. Uploading it now.
Comment #191
joelpittetJust realized this little bug it seems. Did you mean to Title Case the item attributes?
@see http://twig.sensiolabs.org/doc/filters/title.html
Trim filter is fine, but you can also use the whitespace modifiers as well like {%-
@see http://twig.sensiolabs.org/doc/templates.html#whitespace-control
I agree with @jwilson3 in #187.1 It should be consistent all in preprocess for titles or all in template. You can use the default filter if you want to allow variable overrides in the template with sane defaults... consider
{{ item.title|default('Current Page'|t) }}
@see http://twig.sensiolabs.org/doc/filters/default.html
Comment #192
lauriii1) I don't actually even know where that came from :D
2) I changed for those whitespace modifiers because its cleaner.
3) I moved those default link texts to template and thought why do we have any attributes in preprocess and moved them also to template.
Comment #193
ckrinaStarting with that
Comment #194
mortendk CreditAttribution: mortendk commentedComment #195
rteijeiro CreditAttribution: rteijeiro commentedIt seems official tag is FUDK (kinda weird, BTW)
Comment #196
ckrinaThere's a patch adding some comments in pager.html.twig file.
Comment #197
ckrinaUploaded correct patch.
Comment #199
mortendk CreditAttribution: mortendk commentedlooks good i found a little thing with the class naming where it dosnt follow the css documentation its the use of modiefier classes (.foo--modifier)
sorry settings it back to needs work
if we uses bem naming: pager__item-first should be pager__item--first as its a modifer for pager__item
should use the modifier "--" so: pager__item--previes
pager__item--ellipsis
pager__item--next
pager__item--last
Comment #200
lauriiiFixed the classes to follow css documentation.
Comment #201
lauriiiComment #202
mortendk CreditAttribution: mortendk commentedupdates the tags: we needs screenshots & issue summary update (and change notice when we get there)
Comment #203
lauriiiComment #204
lauriiiComment #205
lauriiiComment #206
lauriiiScreenshots:
Before:
Seven:
Bartik:
After:
Seven:
Bartik:
Comment #207
star-szrThis is a review of most of the patch, I didn't look too long at the CSS changes. Not my strong point anyway :)
I mostly found minor documentation issues. This patch is looking great overall and I think template_preprocess_pager() is much easier to follow now.
We should document the data types for the @params and @return: https://www.drupal.org/node/1354#types
s/numer/number/
I think documentation standards wise there are a few issues here:
a. I don't think the sub-sub list can have blank lines around it according to https://www.drupal.org/node/1354#lists.
b. The list items are indented by two spaces too many.
c. (minor) There should be an (Oxford) comma after items.last.
s/visibile/visible/
To avoid extra whitespace being printed, put the
{{
right next topager__item
and use' is-active'
to insert the additional class.Comment #208
star-szr(sorry to add yet another comment for this…)
After a tiny bit of manual testing it appears we have an issue. Or maybe two issues (one of them being that this happens whether twig_debug is on or off). This isn't really the fault of this patch but likely needs to be fixed before this can get in.
Comment #209
lauriiiThanks @cottser for a review! Fixed points from #207. Is there already issue for the issue on #208.
Comment #210
star-szrI am not aware of an issue for #208, I think part of the problem is just in the way that the translation debug info is printed that may need to be changed. But it's weird that it shows even when twig_debug is off unless I was doing something weird. But all the other twig_debug info. was gone.
Interdiff looks good!
Comment #211
mgifford@lauriii pointed out this related link. I'm just connecting it here. It looks like making the active link item on pager a link actually simplifies the code too....
Still it should be done in consideration with this larger patch (or incorporated).
Comment #212
star-szrI think it'd be nice for this one to go in first if possible, either way we can reroll them. But I don't think we should smoosh that issue into this one, things are already complex enough here.
Comment #213
lauriiiAfter discussion on IRC we found workaround with @Cottser for #208. Patch is attached here and I filed a issue for that: #2332991: Twig debug and trans fails on HTML attributes.
For #210 @Cottser also filed a new issue and it can be found here: #2332989: Twig trans tag debug is still hooked up to Settings.
Comment #214
star-szrI suppose you could also do
{% set title = 'Go to page @key'|t({'@key': key}) %}
to avoid the set block + whitespace modifiers.Comment #215
lauriiiTrue that!
Comment #216
lauriiiReroll
Comment #221
mgiffordComment #222
lauriiiRerolled
Comment #223
lauriiiComment #224
star-szrI went through everything again, I think this is looking really really good. However there may be too many visual changes, I think the CSS could probably use some more work since this issue should be about changing the markup. Not saying it needs to be pixel perfect but I think it's probably changed too much and the text underline in Stark looks a bit weird in particular.
Here are some screenshots:
Bartik before/after:
Stark before/after:
Seven before/after:
Comment #225
star-szrHo hum, accidentally hit submit. Attaching screenshots to this comment to embed into my last comment.
Comment #226
star-szrNot that it was really a goal here but I'm happy to report that it looks like this is quite a decent improvement for backend performance :)
Scenario: Default frontpage view displaying 10 nodes and pager like:
1 2 3 4 5 6 7 8 9 … next › last »
http://www.lionsad.de/xhprof-kit/xhprof/xhprof_html/?run1=541de429e5ab1&...
http://www.lionsad.de/xhprof-kit/xhprof/xhprof_html/?run1=541de429e5ab1&...
Comment #227
joelpittetI'd agree with @Cottser.
The name changes for the CSS are fine with me, just the margin/padding/bold changes help a great deal and may bikeshed. Maybe just pair those back a bit so there is less visual regression?
Also yes my site will be 7-9ms faster! woot:P But seriously anything that isn't a regression in performance is awesome in my books:)
Comment #228
lauriiiI fixed visual changes on Bartik, Seven and Stark
Comment #229
star-szrThat looks much better, thanks @lauriii! Re-tested this on all three core themes, screenshots at the end of my comment. Stark changes a bit but I think that's fine (it should have minimal CSS after all), and is actually an improvement IMO :)
I noticed this comment in Seven's pager.css that should be removed since we're now using nicer selectors so I made that minor change here. From my standpoint this is ready and RTBC!
Bartik before/after:
Stark before/after:
Seven before/after:
Comment #230
star-szrWas trying a new technique for taking the screenshots, sorry for the bad quality. Anyway you get the idea :)
Comment #231
mgiffordComment #232
mgiffordWhy on focus/over is there an underline on the numbers, but not in the first/previous in
« first ‹ previous 1 2
It's not a big deal, but a bit of a anomaly I'd think.
Comment #233
lauriiiFixed one very small CSS issue with Bartik. As you can see from the screenshot, the pager has moved a bit right and is not centered anymore. This patch fixes this.
I needed to use pretty strong selector since there is styles attached for
.region-content ul
. Since this is a very minor change, I'll leave this to RTBC.Comment #234
webchickWow, thanks so much for all of the thorough testing on this!
Committed and pushed to 8.x. Thanks!
Comment #236
star-szrComment #238
andrewmacpherson CreditAttribution: andrewmacpherson as a volunteer and at Annertech commentedThis is something we're visiting again. WAI-ARIA 1.1 introduces
aria-current="page"
, so there's an issue to use that, when there's enough browser/AT support.Comment #239
mgiffordFixing the accessibility tag.