Dynamic Widget Class for WordPress Sidebar Widgets

WordPress sidebar widget is Awesome. But unlike post class and body class, the widget do not have dynamic class name. For example you need to apply a certain style to every second widget in your sidebar, or to give no padding/margin to last widget in footer sidebar. There’s another alternative using css, to target first, last, or order of elements using nth-child, but i think this solution is simpler and better.

I think the first idea about this comes from Justin Tadlock, on WordPress.org forum,  Dynamic Widget Classes for use in CSS, 4 years ago. and i still wonder why this feature not yet added in Hybrid Core, But recently Theme Hybrid new community-contributed themes, Sukelius Magazine by Sinisa add this feature to style footer sidebar widget. Here’s the code i’m using in future release of my themes, it’s basicly the same with Sinisa’s code for Sukelius, with very little modification.

in theme setup function:

    /* Additional css classes for widgets */
    add_filter( 'dynamic_sidebar_params', 'genbu_widget_classes' );

the function:

/**
 * Genbu Widget Class Number
 *
 * code from Sukelius Magazine Theme
 * Adding .widget-first and .widget-last classes to widgets.
 * Class .widget-last used to reset margin-right to zero in subsidiary sidebar for the last widget.
 *
 * @since 2.1.2
 */
function genbu_widget_classes( $params ) {

    global $genbu_widget_num; // Global a counter array
    $this_id = $params[0]['id']; // Get the id for the current sidebar we're processing
    $arr_registered_widgets = wp_get_sidebars_widgets(); // Get an array of ALL registered widgets

    if ( !$genbu_widget_num ) {// If the counter array doesn't exist, create it
        $genbu_widget_num = array();
    }

    if ( !isset( $arr_registered_widgets[$this_id] ) || !is_array( $arr_registered_widgets[$this_id] ) ) { // Check if the current sidebar has no widgets
        return $params; // No widgets in this sidebar... bail early.
    }

    if ( isset($genbu_widget_num[$this_id] ) ) { // See if the counter array has an entry for this sidebar
        $genbu_widget_num[$this_id] ++;
    } else { // If not, create it starting with 1
        $genbu_widget_num[$this_id] = 1;
    }

    $class = 'class="widget widget-' . $genbu_widget_num[$this_id] . ' '; // Add a widget number class for additional styling options

    if ( $genbu_widget_num[$this_id] == 1 ) { // If this is the first widget
        $class .= 'widget widget-first ';
    } elseif( $genbu_widget_num[$this_id] == count( $arr_registered_widgets[$this_id] ) ) { // If this is the last widget
        $class .= 'widget widget-last ';
    }

    $params[0]['before_widget'] = str_replace( 'class="widget ', $class, $params[0]['before_widget'] ); // Insert our new classes into "before widget"

    return $params;

}

The code above will add dynamic class for each widget. For example you add 3 widget in your sidebar:

  1. .widget-1 .widget-first
  2. .widget-2
  3. .widget-3 .widget-last