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;
}
}