Add CSS to head depending on nav menu walker

I have a custom walker for a navigation menu on my website, and within it I have some custom CSS that I want to apply to each menu, however, I cannot simply echo it there because even though it works fine, it is invalid code according to W3 validator. The solution is to send that css code to the Head section, but I am stumped how.

Note: The css code is dynamic and will change, so hardcoding the css into the stylesheet won’t work.

Read More

I have all the css stored in an array as such.

class Special_Walker extends Walker_Nav_Menu
{ 
    function start_el(&$output, $item, $depth, $args) {

        //menu generation code

        $css_code[] = //store css code in array 

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );

        }
    }
}

How can I extract the $css_code to echo it into the head section? Is there a way to do it using the wp_head function + action?

Related posts

Leave a Reply

1 comment

  1. Call wp_nav_menu() before wp_head() is called, and store the result for later usage:

    <head>
    <?php
    $menu = wp_nav_menu( 
        array( 
            'echo'           => FALSE, 
            'theme_location' => 'primary', 
            'walker'         => new Special_Walker 
        ) 
    );
    wp_head();
    ?>
    </head>
    <body>
    <?php
    echo $menu;
    

    Now you can enqueue the CSS from your custom walker.

    In your walker collect all CSS rules and add a callback to wp_head to print them out:

    class Special_Walker extends Walker_Nav_Menu
    {
        protected $custom_css = array();
    
        function start_el(&$output, $item, $depth, $args) {
    
            add_action( 'wp_head', array( $this, 'head_css' ) );
    
            //menu generation code
    
            $this->custom_css[] = 'some css';//store css code in array
    
            $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    
        }
    
        public function head_css()
        {
            print '<style>' . join( "n", $this->custom_css ) . '</style>';
        }
    }