Adding in a Responsive HTML Logo/Image Header via the Customizer for Genesis

This tutorial looks at replacing the CSS background technique used to display a logo/image in the Genesis framework header with an actual HTML markup inline image tag, which is better for responsive design across all devices.  This can be achieved in a couple of ways, one with a filter and one with an action. But first some general info…

Genesis Sample Theme

The header image/logo placement and technique used in the Genesis Sample Theme depends on whether you have ‘Dynamic Text‘ or Image ‘Logo‘ selected in Genesis Settings > Header.

genesis-header-settings

If ‘Dynamic text‘ is selected the ‘Site Title‘ and ‘Tagline‘ are used as set in the WordPress > Settings fields. If ‘Image Logo‘ is selected an image is referenced in the images directory of your theme named logo.png and there is a default one in place at 360x164px. This has been removed in the latest Genesis Sample theme from 2.2.3 onwards.

default genesis logo

360px * 154px default

 

The image is place as a CSS background rather than a HTML marked up image tag.

genesis-logo-background css

In the code you can see that the image is a CSS background of the link inside the H1 of the .title-area

This works for the most part but has responsive issues and is not really appropriate for a sites main corporate branding either semantically or for SEO. The responsive issues can be dealt with by using the background-size CSS rule. However I feel that that an image HTML mark up should really be used in this area.

The CSS is different from Genesis Sample theme from 2.2.3 onwards whereby there is no background pointing to a default logo in images.

Genesis Custom Headers

Outside of the Genesis Sample Theme most of the StudioPress themes add support for Custom Headers something similar to the below (taken from News Pro) which you’ll find in the theme’s functions.php.

<?php
//* Add support for custom header
add_theme_support( 'custom-header', array(
'header_image' => '',
'header-selector' => '.site-title a',
'header-text' => false,
'height' => 90,
'width' => 260
'header-text' => false,
) );
view raw custom-headers.php hosted with ❤ by GitHub

With Custom Headers enabled you add the image/logo via Appearance > Header and you are put into the Customizer which makes it easier for a non technical user to change the main image.

genesis header via customizer

 

In terms of the image size which is defined inside the array of values of the Custom Header just change them to what you need but also adjust the surrounding elements in the CSS mark up to make sure they all play nicely.

The Custom Header support is not specific to Genesis it is a WordPress feature that can be used in any themes. One of the Genesis specific adjustments is the use of header-selector which is used to target the HTML element which will have the CSS background image applied to it.

This is coded in at genesis/header.php in the genesis_custom_header and genesis_custom_header_style functions, the genesis_custom_header_style is really controlling the output here and can be removed.

Alternative ways…

Using an action, genesis_site_title

Using an Image instead of a CSS background – borrowing from _s

So instead of using a CSS background lets use some HTML markup which contains the image element. We can pinch the mark up from Underscores.

In _s/inc/custom-header.php lines 7-11

<?php //<~ don't add me
<?php if ( get_header_image() ) : ?>
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home">
<img src="<?php header_image(); ?>" width="<?php echo esc_attr( get_custom_header()->width ); ?>" height="<?php echo esc_attr( get_custom_header()->height ); ?>" alt="">
</a>
<?php endif; // End header image check. ?>

So we can add our own custom header theme support, remove the genesis_custom_header_style action and hook in our _s header mark up. To be added in functions.php

<?php //<~ don't add me
//add in custom header support
//parameters - https://codex.wordpress.org/Custom_Headers
add_theme_support( 'custom-header', array(
'width' => 400,
'height' => 150,
'header-text' => false,
'flex-height' => true,
'flex-width' => true,
) );
remove_action( 'wp_head', 'genesis_custom_header_style'); //remove custom genesis custom header style
add_action('genesis_site_title','wpb_image_header', 5);//add in custom header markup via genesis_site_title hook
function wpb_image_header() {
?>
<?php if ( get_header_image() ) : ?>
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home">
<img src="<?php header_image(); ?>" width="<?php echo esc_attr( get_custom_header()->width ); ?>" height="<?php echo esc_attr( get_custom_header()->height ); ?>" alt="<?php echo esc_attr( get_bloginfo( 'name' ) ); ?>">
</a>
<?php endif; // End header image check. ?>
<?php
}
view raw new-header.php hosted with ❤ by GitHub

In the snippet of code we are adding in custom header support for our theme, removing the default Genesis header behaviour and hooking in our new header mark up.

The mark up is hooked in with the genesis_site_title hook with a high priority (5) to make sure it executes early and sits above the title.

Change the size to suit your needs and now you can add the image via the Customizer or Appearance > Header.

genesis-new-mark-up

What’s good about this is that…

  • It is an image and more controllable
  • The image can be easily changed via the customiser
  • If no image is selected then the Site title and description are displayed, if you want both the logo and site title and site description to show change the value of header-text in the custom header support to be true.

CSS Clean Up

Also we will need to remove some CSS associated the background CSS for .header-image .site-title > a, remove or comment out

.header-image .site-title > a {
 float: left;
 min-height: 150px;
 width: 100%;
}

Using a filter, genesis_seo_title (better way!)

Genesis come with a filter that you can change the content without changing the markup layout, the filter in question is genesis_seo_title, which you can see in genesis/header.php from line 932

<?php //<~ Don't add me
// Add in custom header support.
// Parameters - https://codex.wordpress.org/Custom_Headers
// Need to add in flex-height and flex-width to be able to skip cropping in the Customizer.
add_theme_support( 'custom-header', array(
'width' => 400,
'height' => 150,
'flex-height' => true,
'flex-width' => true,
'header-text' => false,
) );
//// Remove Genesis header style so we can use the customiser and header function genesischild_swap_header to add our header logo.
remove_action( 'wp_head', 'genesis_custom_header_style' );
/**
* Add an image tag inline in the site title element for the main logo
*
* The header logo is then added via the Customiser
*
* @param string $title All the mark up title.
* @param string $inside Mark up inside the title.
* @param string $wrap Mark up on the title.
* @author @_AlphaBlossom
* @author @_neilgee
*/
function genesischild_swap_header( $title, $inside, $wrap ) {
// Set what goes inside the wrapping tags.
if ( get_header_image() ) :
$logo = '<img src="' . get_header_image() . '" width="' . esc_attr( get_custom_header()->width ) . '" height="' . esc_attr( get_custom_header()->height ) . '" alt="' . esc_attr( get_bloginfo( 'name' ) ) . '">';
else :
$logo = get_bloginfo( 'name' );
endif;
$inside = sprintf( '<a href="%s" title="%s">%s</a>', trailingslashit( home_url() ), esc_attr( get_bloginfo( 'name' ) ), $logo );
// Determine which wrapping tags to use - changed is_home to is_front_page to fix Genesis bug.
$wrap = is_front_page() && 'title' === genesis_get_seo_option( 'home_h1_on' ) ? 'h1' : 'p';
// A little fallback, in case an SEO plugin is active - changed is_home to is_front_page to fix Genesis bug.
$wrap = is_front_page() && ! genesis_get_seo_option( 'home_h1_on' ) ? 'h1' : $wrap;
// And finally, $wrap in h1 if HTML5 & semantic headings enabled.
$wrap = genesis_html5() && genesis_get_seo_option( 'semantic_headings' ) ? 'h1' : $wrap;
$title = sprintf( '<%1$s %2$s>%3$s</%1$s>', $wrap, genesis_attr( 'site-title' ), $inside );
return $title;
}
add_filter( 'genesis_seo_title','genesischild_swap_header', 10, 3 );
/**
* Add class for screen readers to site description.
* This will keep the site description mark up but will not have any visual presence on the page
* This runs if their is a header image set in the Customiser.
*
* @param string $attributes Add screen reader class.
* @author @_AlphaBlossom
* @author @_neilgee
*/
function genesischild_add_site_description_class( $attributes ) {
if ( get_header_image() ) :
$attributes['class'] .= ' screen-reader-text';
return $attributes;
endif;
return $attributes;
}
add_filter( 'genesis_attr_site-description', 'genesischild_add_site_description_class' );

So in the above I am still using the Underscores header code and outputting the logo if the header is set, if it is not set I am outputting the Site Name. The remainder of the code is an improved output from Tony Eppright published here.

What I wanted to differently (from Tonys method) was to have the image handled by the Appearance > Header option. Also I add the .screen-reader class to the site-description if the image is set in Customizer so its output on the page is invisible – but visible to screen readers. However the Site Description will display normally if the image is not set in Customizer.

filter-image-output

Now the image is positioned in the layout without adding to and altering the default layout. Making the filter option a better one.

CSS Clean Up

Also we will need to remove some CSS associated with hiding the title

.header-image .site-description,
.header-image .site-title {
 display: block;
 text-indent: -9999px;
}

to this

.header-image .site-description { 
 display: block; 
 text-indent: -9999px; 
}

and still remove..

.header-image .site-title > a {
 float: left;
 min-height: 150px;
 width: 100%;
}

And if you have a legacy build which uses a logo.png filed in your themes image folder – remove the CSS

.title-area {
 background: url(images/logo.png) no-repeat center;
 padding: 0;
}

You should also be moving towards svg format for things such as logos as browser support is widespread, the great thing about SVG is it is a resolution independent format and will look great on any screen and you just need the one version. Fallbacks are also still achievable.

6th March 2016 Update – As an addition to this, there was a small issue whereby if the header was set in Customizer, the .site-description markup was being output – I have tweaked @alphablossom code to hide it if the header is picked in Customiser, if it isn’t picked in Customizer the description will display.

15 Comments

  1. Randall on June 15, 2016 at 5:16 am

    Hey Neil:

    Thanks for sharing. The responsive image is the way to go in my opinion too.

    I am wondering how we get the responsive image to float more to the left of the screen than center left. By removing the CSS, it seems that a prominent “left float” is partially compromised?

    Would we simply edit .site-header widget-area by increasing its width?

    • Neil Gowran on June 15, 2016 at 11:20 pm

      Depends on your theme, probably address it with CSS positioning

  2. Maira on March 3, 2016 at 12:15 am

    Hi, sorry to bother you again!

    Is it possible to add a hover effect to the logo image? I’d like to display my logo with a different color on hover, I tried to add an onmouseover effect, but I’m sure I’m not doing it correctly.

    I appreciate any suggestion, thanks!

    • Neil Gowran on March 7, 2016 at 5:40 am

      You could do an opacity setting on hover using the image or you could revert to background images in CSS and use a different image for the logo on hover

      • Maira on March 26, 2016 at 3:26 pm

        Thanks for the tips Neil!

  3. Cara C. on January 8, 2016 at 11:18 pm

    AWESOME!!! Thank you so much for posting this! It is greatly appreciate!

  4. B on January 4, 2016 at 3:56 am

    Found the problem! I’m so sorry! It was a caching problem.

    Thank you so much for your code.

    Also, to pay it forward a bit, perhaps I can be of some small help. I don’t actually know much about php, but I noticed that when I put your code on my site, the alt tag for the logo was still empty. I looked around a bit and added an “echo” after the alt=”<?php part of the code and it seemed to successfully input my site name as the alt tag. I don't know if that helps at all or if I did it correctly, but thank you again for your generosity. I truly appreciate it.

    • Neil Gowran on January 4, 2016 at 7:36 am

      No worries glad it helped – good catch on the alt tag – it was missing an echo, code now updated.

  5. B on January 4, 2016 at 3:36 am

    Hello,

    Thank you for the code. I tried the first one (with the action) so that I could have the logo, site title, and site description all showing. I had to play with css to make it look how I wanted, but it worked great.

    Unfortunately, my css changes to the header area of the site only show up on the homepage. All other pages of the site show the header-area looking funny as if I made no css changes at all. The logo, title, and description are all there, but not like the way I’ve coded it in my style.css file and not like it’s shown on the homepage. The homepage reflects the css changes and looks fine.

    Does adding this code (the first one) to functions.php somehow take away the ability of other pages on the site to inherit changes made to the child theme’s style.css file? Do I need to do something else to gain that ability back? FYI: I am using the Genesis Sample theme.

    Please help! Thank you very much in advance for your time and response.

    • Neil Gowran on January 4, 2016 at 7:39 am

      The code affects the header globally across all pages, so you may be having a caching issue.

      • Neil Gowran on January 4, 2016 at 7:40 am

        Ah ha – see you worked that out!

  6. Maira on December 18, 2015 at 8:52 pm

    Thanks, I will try with the retina option!

  7. Maira on December 17, 2015 at 5:22 pm

    Hey there, thanks for this tutorial, I applied it with success in my Sample theme. The downside is that the logo looks blurry on my phone, I have a Galaxy S5 and the logo is 300px x 200px, any ideas?

Leave a Comment





%d bloggers like this: