Header setup
How to do a hero with full height less menu header height. This takes into account the WordPress admin bar when logged in.
There are three states of the admin bar:
- (max-width: 600px) has a height of 46px, bar scrolls away
- (max-width: 782px) has a height of 46px, bar is fixed at top of screen
- (min-width: 783px) has a height of 32px, bar is fixed at top of screen
The header (which will typically contain the logo and menu) will have a fixed height which is set with the custom property --header-height
. Breakpoints can also be added if the height changes, for example smaller screens will often have a smaller header.
The header uses .sticky
now that IE is not supported. The advantage is that you don't need to worry about adding a top margin to the main
element.
/*--------------------------------------------------------------
# Header
--------------------------------------------------------------*/
:root {
--header-height: 88px; /* Mobile height */
@media screen(menu) {
--header-height: 80px; /* Desktop height */
}
@media screen(3xl) {
--header-height: 160px; /* Desktop height */
}
}
.site-header {
height: var(--header-height);
.admin-bar & {
top: 32px;
@media screen and (max-width: 782px) {
top: 46px;
}
}
}
/* Break point at which WP header scrolls away */
@media screen and (max-width: 600px) {
.admin-bar {
/* starts off static */
.site-header {
position: static;
}
/* sticky-admin class is added with js */
&.sticky-admin .site-header {
top: 0;
position: fixed;
}
}
}
Html in header.php
.
<header class="sticky flex items-center justify-between bg-slate-500 px-7 xl:px-14 2xl:px-36 site-header">
<div class="">
<!-- Logo -->
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home">
<?php
$custom_logo_id = get_theme_mod( 'custom_logo' );
$image_path = get_attached_file( $custom_logo_id );
if ( $image_path ) {
echo file_get_contents( $image_path );
}
?>
</a>
</div>
<nav class="main-navigation">
<button class="menu-toggle" aria-controls="menu-modal" aria-expanded="false">
<?php
wp_nav_menu(
array(
'theme_location' => 'main_menu',
'menu_class' => 'main-menu',
'container' => false
)
);
?>
</button>
</nav>
</header>
Sticky admin bar
We need to handles the case where up to a max-width of 600px the admin bar scrolls away. To manage this, add a file /js/admin.js
that will add the class sticky-admin
to the body
element when the page has scrolled 46px (the height of the admin bar).
function makeStickyOnScroll() {
// set container to make sticky.
var stickyContainerAdmin = document.querySelector("body");
// set scroll distance, 46 is the height of the wordpress mobile navbar
var scrollDistanceAdmin = 46;
// Listen for scroll
function handleScroll() {
if (window.pageYOffset > scrollDistanceAdmin) {
stickyContainerAdmin.classList.add("sticky-admin");
} else {
stickyContainerAdmin.classList.remove("sticky-admin");
}
});
// Initial call on page load
handleScroll();
// Listen for scroll
window.addEventListener("scroll", handleScroll);
}
document.addEventListener("DOMContentLoaded", makeStickyOnScroll);
Then add to functions.php
with the rest of the wp_enqueue_scripts
.
if( is_user_logged_in() ) {
wp_enqueue_script( 'projectX-admin', get_template_directory_uri() . '/js/admin.js', array(), false, true );
}
Skip link
Uses the built-in sr-only
and not-sr-only
from Tailwind CSS with some minor additional styling for the focused state. The z-[99999]
ensures the link is shown above the WordPress admin bar.
<a class="sr-only focus:not-sr-only bg-white z-[99999] rounded outline-none focus:px-4 focus:py-3 focus:absolute focus:ring-2 focus:ring-black focus:top-1 focus:left-1" href="#main">
Skip to content
</a>
Alternate Colour Header
When some pages have a dark header while others have a light header.
Add to functions.php
so all pages with a dark header will have a class of dark-header
added to the body
element.
/**
* Add body class for dark / light header
*/
add_filter('body_class', 'my_body_classes');
function my_body_classes($classes) {
if (
is_page_template('page-templates/home.php') or
is_page_template('page-templates/about.php') or
is_page_template('page-templates/contact.php')
) {
$classes[] = 'dark-header';
}
return $classes;
}
Change :root to body so css custom properties can be overridden correctly.
Example css.
.site-header {
@apply bg-white;
.dark-header & {
@apply bg-black;
}
}