#21562 closed defect (bug) (fixed)
Twenty Twelve: improve navigation to be mobile-first and not rely on jQuery for hiding and showing
Reported by: | cfinke | Owned by: | lancewillett |
---|---|---|---|
Milestone: | 3.5 | Priority: | normal |
Severity: | normal | Version: | |
Component: | Bundled Theme | Keywords: | has-patch |
Focuses: | Cc: |
Description
When loading Twenty Twelve on an iPhone, the "Show navigation" button is visible even when tapping it will have no effect. It should be hidden (or never output) if it will be impotent.
Attachments (15)
Change History (58)
#1
@
12 years ago
Correction: This applies to all small screens (not just iPhones), including narrow browser windows on full size screens.
#4
@
12 years ago
This is so lame in so many ways.
A user should be able to "remove" the menu by assigning an empty one to it. With no menu items, we are left with some margin and borders and the mentioned button on screens < 600px.
Unless I'm missing something big, there is no way to address it with CSS. Removing it with JS, leaves us with a button/border flash on pageload though. Did I say it was lame?
#5
follow-up:
↓ 6
@
12 years ago
After spending like 3h trying to find the best way to fix this issue, 21562.2.diff and #21576 are what I came up with.
We can loose the functions.php
callback once #21576 is in core. Until then, this is the only possibility I could think of, to prevent a markup flash and not have the margin and the menu borders collapse on the empty menu.
In theme.js
I just wrapped most of the JS with the menu-item-check from @cfinke and changed the window check to check for true instead of not false.
#6
in reply to:
↑ 5
@
12 years ago
- Milestone changed from Awaiting Review to 3.5
- Severity changed from minor to normal
Replying to obenland:
I think going with cfinke's patch will work short-term. Just making sure the button isn't there. Yes, the empty menu assigned case is possible, but so is someone forking the theme and not showing a menu output at all (or a plugin doing that for some reason).
So the JS fix makes sense to avoid showing the button.
Let's wait until #21576 is fixed until worrying about the extra markup in the source.
#8
@
12 years ago
With r21520 I also committed the JS fix props cfinke. Forgot to note that in the commit message.
#9
@
12 years ago
@cfinke A note on core patches, they should be made from WP root -- not the theme directory. Thanks. :)
#10
@
12 years ago
Patch by obenland - 21562.css-menu-switch.diff - takes out most of the JS for the navigation handling and puts it into CSS with the display depending on screen size via media queries.
#11
@
12 years ago
@obenland One thing I noticed right away -- the small menu styles are broken. Previously since the class changed to "main-small-navigation" the smaller menu did not inherit and need to override any of the "main-navigation" styles.
Small menu is lowercase, underlined, much less space in between, centered, and no sub-level menus at all (just top level).
It's all doable, just makes the small menu CSS rules a bit more complex since they have to override the larger styles. Which brings up something -- this theme is all mobile first, so we should really do it the other way around:
- Outside media queries put small menu styles
- Inside min-width of 600px put the larger menu styles
That takes care of the overrides and also works with how Drew built the stylesheet.
#13
follow-up:
↓ 14
@
12 years ago
21562.css-menu-switch.2.diff moves the menu-switch logic from JS to CSS. It maintains the mobile-first approach by moving the menu styles for larger screens in the >600px media query.
Renamed theme.js
to navigation.js
, as discussed with @lancewillett in IRC, since it is solely about the main navigation.
#14
in reply to:
↑ 13
@
12 years ago
Replying to obenland:
21562.css-menu-switch.2.diff moves the menu-switch logic from JS to CSS. It maintains the mobile-first approach by moving the menu styles for larger screens in the >600px media query.
Looks much better -- thank you for the updated patch. Will get it in soon, after more testing.
#15
@
12 years ago
- Summary changed from Twenty Twelve: Hide the "Show navigation" button when there is no navigation to show. to Twenty Twelve: improve navigation to be mobile-first and not rely on JS for hiding and showing
Renaming ticket for accuracy, the main thrust of this ticket is the JS -> CSS rework for hiding and showing and making the styles mobile first.
#17
@
12 years ago
- Keywords has-patch removed
This needs some more testing in all devices and browsers before closing.
#22
follow-up:
↓ 23
@
12 years ago
Is it possible to change 'Show Menu' to 'Hide Menu' when the menu is visible?
#23
in reply to:
↑ 22
;
follow-up:
↓ 24
@
12 years ago
Replying to spencerdahl:
Is it possible to change 'Show Menu' to 'Hide Menu' when the menu is visible?
I'd prefer not to change the text label because the general use case is:
- Click it to view menu
- Click a link
- Go to new page, menu is closed again
Rarely would you need to open, then close it again (other than in testing).
#24
in reply to:
↑ 23
@
12 years ago
Replying to lancewillett:
Replying to spencerdahl:
Is it possible to change 'Show Menu' to 'Hide Menu' when the menu is visible?
I'd prefer not to change the text label
+1
#25
follow-ups:
↓ 26
↓ 29
@
12 years ago
@lancewillett:
In 21562.no-jQuery.diff the toggling works but currently without transition effects.
CSS transitions do not work with the display
property, which is why I went with height
and overflow:hidden;
. But they also need a specific hight value for them to work. It does not work with height:auto;
(or height:100%;
for that matter).
Which brings us back to: ...calculating the height??
#26
in reply to:
↑ 25
;
follow-up:
↓ 27
@
12 years ago
Replying to obenland:
@lancewillett:
In 21562.no-jQuery.diff the toggling works but currently without transition effects.
I think we can remove the entire JS file now.
- Use hover style to reveal the menu when you mouse over the button, just like core menus work.
- Use transition to make the reveal be slower, if desired (might not even be necessary).
#27
in reply to:
↑ 26
@
12 years ago
Replying to lancewillett:
Replying to obenland:
@lancewillett:
In 21562.no-jQuery.diff the toggling works but currently without transition effects.
I think we can remove the entire JS file now.
Scratch that idea, we can't rely on :hover pseudo element support in touch devices. The click to show still needs to happen.
#28
follow-up:
↓ 31
@
12 years ago
What it comes down to is having the transition effect or not, right?
#29
in reply to:
↑ 25
;
follow-up:
↓ 30
@
12 years ago
Replying to obenland:
In 21562.no-jQuery.diff the toggling works but currently without transition effects.
Doesn't that patch assume that the ID of the menu is menu-menu
(var menu = document.getElementById( 'menu-menu' )
)?
That is not always the case. If I call my menu foo
, the ID will be menu-foo
#30
in reply to:
↑ 29
@
12 years ago
Replying to Jayjdk:
Doesn't that patch assume that the ID of the menu is
menu-menu
(var menu = document.getElementById( 'menu-menu' )
)?
That is not always the case. If I call my menu
foo
, the ID will bemenu-foo
That's right. The patch is a work in progress, as it also lacks support for wp_page_menu()
.
Which brings up a whole different topic of having to add a callback to 'wp_page_menu'
to wrap it with an element with an id, to be able to target it with JS.
#31
in reply to:
↑ 28
@
12 years ago
Replying to obenland:
What it comes down to is having the transition effect or not, right?
Yep. I think for older browsers no effect is fine — just hide and show it with CSS when they hover or click on the menu-toggle button.
For selecting the menu by ID without jQuery, something like this might work:
var menu = document.getElementById( 'masthead' ).getElementsByTagName( 'ul' )[0];
Or target an ID value of "site-navigation" and change line 38 in header.php to:
<nav id="site-navigation" class="main-navigation" role="navigation">
We probably don't need both classes there, it was a hold-out from the JS changing the class to "main-small-navigation".
#32
@
12 years ago
- Keywords has-patch added
This ticket is getting crazy. :)
I think our best option for v 1.0 launch is to use this non-jQuery technique without the CSS transition. It works in all browsers and mobile devices, and gets the job done without loading jQuery.
The CSS transitions would be a nice enhancement, but could be added post-launch without adverse effect on anyone.
#33
@
12 years ago
@obenland Note for once we have this part done: check IE9, the menu isn't showing up at all. Best to debug after we finalize the menu markup and CSS, though.
#34
follow-up:
↓ 39
@
12 years ago
For the JS addClass and removeClass:
function removeClass(element, name) { element.className = element.className.replace( new RegExp('\\b'+name+'\\b', 'g'), '') .replace(/^ | $/, '').replace(/ +/g, ' '); // trim spaces } function addClass(element, name) { removeClass(element, name); // avoid duplicates element.className += ' ' + name; }
Perhaps consider making the menu fully accessible, instead of using display: none
and display: block
, much better to use top: -10000em
to hide from the viewport but not from screen readers and top: 0
to show (the submenus are already position: absolute
anyway). Then use :focus as well as :hover to show them.
This makes the sub-menus fully accessible when "tabbing" too. Changed that on the admin menu and it works a lot better now.
@
12 years ago
Simpler regex check for class value, add back in the empty menu check, can remove once core fix is in
#38
@
12 years ago
Note from Koop from a JS code review in IRC yesterday, in navigation.js we should check the existence of the button and menu elements before operating on them (exit the function early if null or empty, etc).
#39
in reply to:
↑ 34
;
follow-up:
↓ 43
@
12 years ago
Replying to azaozz:
For the JS addClass and removeClass:
function removeClass(element, name) {
function addClass(element, name) {
I think that's probably overkill. Might as well just go back to using jQuery methods at that point. :)
Perhaps consider making the menu fully accessible, instead of using
display: none
anddisplay: block
, much better to usetop: -10000em
to hide from the viewport but not from screen readers andtop: 0
to show (the submenus are alreadyposition: absolute
anyway). Then use :focus as well as :hover to show them.
I like this—but in the case of the small mobile menu the hover and focus pseudo classes don't apply since this display mode is for touch devices primarily. The submenus are not positioned in this display (they are in > 600 pixels only).
In the "large" display of the menu the top-level is always visible.
#40
@
12 years ago
For new topic of small navigation menu layout, please see #21678 so we can keep this ticket focused on the JS hide/show behavior.
#41
@
12 years ago
- Summary changed from Twenty Twelve: improve navigation to be mobile-first and not rely on JS for hiding and showing to Twenty Twelve: improve navigation to be mobile-first and not rely on jQuery for hiding and showing
#42
@
12 years ago
- Owner set to lancewillett
- Resolution set to fixed
- Status changed from new to closed
In [21611]:
#43
in reply to:
↑ 39
@
12 years ago
Replying to lancewillett:
...
function removeClass(element, name)
function addClass(element, name)
I think that's probably overkill. Might as well just go back to using jQuery methods at that point. :)
Right. These are generic replacements that would work well anywhere and for any class. When this is only needed for a specific class, it can be hard-coded and the code will be shorter.
Hides the 'Show navigation' button if there are no navigation menu items.