Militant Moderates CSS Parent Selector Plugin for WordPress™

Building the proper “Look and Feel” into your WordPress™ Theme often requires some complicated CSS gymnastics. There are times when what you want is either incredibly difficult or even impossible using standard CSS. A common roadblock for designers is the limitation in “Standard” CSS that applies the Style Declarations only to the last element matched by the CSS Style Selector.

The Militant Moderates CSS Parent Selector Plugin (or MMPS) breaks that limitation and allows you to apply the desired styling to any Element in the entire tree matched by the Selector. Simply put, if your Selector matches a sub-tree of four elements, the desired styling can be applied to any of those four elements and not just the last (child) element in the tree.


Basic CSS Syntax

CSS consists of a series of Styles. Each Style has a Selector and the Declarations. Elements on the web page that match the Selector are styled according to the Declarations. Here is a generic CSS Style:

div p { padding-bottom: 0px; }

This Style causes every <p> inside a <div> to have its bottom padding set to 0px. In this simple example, the Selector is ‘div p‘ and the Declaration is ‘padding-bottom: 0px;‘. The elements on the page that match the Selector are the <p> paragraph elements contained within <div> elements. The Selected Element is the element that will be styled according to the Declaration.

The tree of elements starting with the first element matched by the Selector and ending with the last element matched is called the Selector Tree. The Selector Tree may contain many nested levels of elements depending on how the CSS Selector is written.

But what if you need to apply the Style Declarations to another element in the Selector Tree other than the Selected Element? Standard CSS does not provide a way to do that, and even the W3C Draft for Selectors Level 4 does not easily address the feature. What is really needed is a way to easily apply styling to an element matched by the CSS Selector other than the last element.

Using the MMPS Parent Selector Syntax

The Militant Moderates CSS Parent Selector Plugin adds a simple enhancement to the standard CSS Selector syntax that allows you to specify which element in the Selector Tree will be styled. This frees you to apply styling to any element within the Selector Tree but only when the entire Selector Tree is matched.

For example, suppose we have the following HTML snippet:

<p>Text goes here. A link to the 'foo' anchor is <a href="#foo">HERE</a>. End text is here.</p>

It’s just a simple paragraph with an embedded link. It looks like this:

Text goes here. A link to the ‘foo’ anchor is HERE. End text is here.

Now suppose we want to apply special styling for every paragraph on the page that contains a link to the #foo on-page anchor. You might try the following CSS Style:

p a[href="#foo"] { background-color: #eee; }

The Selector portion of the CSS Style ‘p a[href=”#foo”]‘ selects all <a> Elements with an href attribute of #foo that are also contained within a <p> Element. The Style Declaration ‘background-color: #eee;‘ is applied to the Selected Element.

The problem is that the <a> Element is the Selected Element because it comes at the end of the Selector. The result is that the background color of the Link is changed, not that of the Paragraph. It winds up looking like this:

Text goes here. A link to the ‘foo’ anchor is HERE. End text is here.

Changing a Standard Selector to a Parent Selector

What we need is a way to apply the styling to a Parent of the Selected Element, in this case the paragraph that contains the link. Standard CSS does not allow this, but the Militant Moderates CSS Parent Selector Plugin adds additional capabilities that make it easy. With the MMPS plugin you can write specially formatted CSS Selectors that apply the styling to a Parent element instead of just to the Selected element.

The Parent element that will receive the styling is designated in the CSS Selector by adding a single exclamation mark (‘!‘) to the end of its element selector. Using our example from above, we can rewrite the CSS Style as follows:

p! a[href="#foo"] { background-color: #eee; }

The exclamation mark after the ‘p‘ selector indicates the element that will receive the styling when the entire Selector matches. Basically this means that when a <p> element contains an <a> element with an href attribute of #foo, apply the styling to the <p> element. The result looks like this:

Text goes here. A link to the ‘foo’ anchor is HERE. End text is here.

Using Pseudo Classes with MMPS

One of the neatest features of CSS is its ability to make styling changes based on various events. The W3 Schools website contains a tutorial on Pseudo Classes and an overview can be found on the W3.org web siteMMPS extends the use of Pseudo Classes to either the Parent or the Selected elements. The example Test Table 5 below shows how Pseudo Classes work when applied to the Selected element. The Test Table 6 example explains further how Pseudo Classes work when they are applied to either the Parent or Selected element in a Selector.

Using Pseudo Elements with MMPS

Pseudo Elements in CSS allow you to do such things as insert content before or after the Selected element, but also limit styling to parts of the Selected element (such as the first line or first character). Here is an overview of the existing Pseudo Elements on the W3.org web site and the always beneficial Tutorial on Pseudo Elements at W3 Schools.

MMPS fully supports all the existing Pseudo Elements but also allows them to be applied to the designated Parent element, not just the Selected element. The example Test Paragraph 8 below shows how the Pseudo Element ::before works when applied to the Parent element. The example Test Paragraph 9 below demonstrates the use of both Pseudo Elements on the Parent and Pseudo Classes on the Selected element.


Examples and Samples

The following Test Tables all use the same basic Table but have unique CSS styling rules to alter their appearance and behavior. The center cell in each table is called the Test Cell. It is marked by having a special test Class ‘mmps_here’ attached to it. Some of the CSS styling rules used depend on the other Classes used to mark Row and Column indices.

Below each table is the CSS code used. Depending on the example shown, the CSS may contain straight CSS syntax or the special Parent Selector syntax supported by this plugin. If you are not seeing the proper styling effects, make sure you have enabled the Militant Moderates CSS Parent Selector Plugin.

Test Table 1 : Clean Table with Test Cell Styling

All examples below use this same basic table structure.

Table 1 : Row 1 : Col 1 Table 1 : Row 1 : Col 2 Table 1 : Row 1 : Col 3
Table 1 : Row 2 : Col 1 Table 1 : Row 2 : Col 2 Table 1 : Row 2 : Col 3
Table 1 : Row 3 : Col 1 Table 1 : Row 3 : Col 2 Table 1 : Row 3 : Col 3

Basic table used for every example
CSS: Set font-weight to bold for the Test Cell

.mmps_here { font-weight: bold; }

Test Table 2 : Highlight Test Cell – Standard CSS

This example uses standard CSS to set the background color of the entire table and also give the Test Cell a separate background color.

Table 2 : Row 1 : Col 1 Table 2 : Row 1 : Col 2 Table 2 : Row 1 : Col 3
Table 2 : Row 2 : Col 1 Table 2 : Row 2 : Col 2 Table 2 : Row 2 : Col 3
Table 2 : Row 3 : Col 1 Table 2 : Row 3 : Col 2 Table 2 : Row 3 : Col 3

CSS: Set the background color of the table to AliceBlue.
CSS: Set the background color of the Test Cell to #ccc

table.ps-table2 { background-color: AliceBlue; }
table.ps-table2 tr td.mmps_here { background-color: #ccc; }

Test Table 3 : Highlight Row 2 using Wildcard ‘*’ Parent Selector

This example shows the basic syntax to apply style declarations to a Parent element based on a Selector that includes Child elements. The rightmost element in the Selector is called the “Target” element. The desired element that will be styled is indicated by adding an exclamation mark ‘!’ to the end of its element selector.

This example shows the use of the ‘*’ wildcard element selector. CSS Selector rules are parsed from right to left. When an asterisk element is found in the Selector chain, it specifies the Parent element of the element directly to its right. The wildcard element selector can be very useful when the first and last elements in the full Selector are the same but the intervening elements may vary AND you need to apply the specified styling to one of the unknown middle elements.

The second example Style shown here contains the Selector ‘table.ps-table3 *! td.mmps_here‘. Parsing from right to left yields a series of Elements as follows:

  • td.mmps_here : Select the TD (table cell) Element with class ‘mmps_here
  • *! : Select any element that is the direct Parent of the matched TD Element
  • table.ps-table3 : Select the TABLE Element with class ‘ps-table3

Notice that the wildcard selector is also designated as the parent element that will be styled. This is indicated by the ‘!’ exclamation mark added to the end of the selector, yielding ‘*!‘ in this example.

Table 3 : Row 1 : Col 1 Table 3 : Row 1 : Col 2 Table 3 : Row 1 : Col 3
Table 3 : Row 2 : Col 1 Table 3 : Row 2 : Col 2 Table 3 : Row 2 : Col 3
Table 3 : Row 3 : Col 1 Table 3 : Row 3 : Col 2 Table 3 : Row 3 : Col 3

CSS: Set the background color of the table to Aquamarine
MMPS: Set the background color of the Parent containing the Test Cell to #ccc

table.ps-table3 { background-color: Aquamarine; }
table.ps-table3 *! td.mmps_here { background-color: #ccc; }

Test Table 4 : Highlight Col 2 – Standard CSS

This example again uses basic CSS syntax to color the entire table and specially color Row 2.

Table 4 : Row 1 : Col 1 Table 4 : Row 1 : Col 2 Table 4 : Row 1 : Col 3
Table 4 : Row 2 : Col 1 Table 4 : Row 2 : Col 2 Table 4 : Row 2 : Col 3
Table 4 : Row 3 : Col 1 Table 4 : Row 3 : Col 2 Table 4 : Row 3 : Col 3

CSS: Set the background color of the table to Cornsilk
CSS: Set the background color for all elements in the table with class ‘ps-col2’ to #ccc

table.ps-table4 { background-color: Cornsilk; }
table.ps-table4 tr td.ps-col2 { background-color: #ccc; }

Test Table 5 : Highlight Table when Target Pseudo Class is triggered

This example uses a variant of the Parent Selector syntax that includes a CSS Pseudo Class on the Target Element. Styling changes to the Parent element only occur when the Pseudo Class is triggered on the Target element. For this example, one cell has a Pseudo Class of ‘click’, three other cells have a Pseudo Class of ‘hover’. All of them set the background color of the entire table when triggered. Their order of appearance determines how they interact and override each other.

Table 5 : Row 1 : Col 1 Table 5 : Row 1 : Col 2 Table 5 : Row 1 : Col 3
Table 5 : Row 2 : Col 1 Table 5 : Row 2 : Col 2 Table 5 : Row 2 : Col 3
Table 5 : Row 3 : Col 1 Table 5 : Row 3 : Col 2 Table 5 : Row 3 : Col 3

CSS: Set the background color of the table to Fuchsia
MMPS: Set the background color of the table to Red when the cell at Row 3 : Col 1 is ‘clicked’
MMPS: Set the background color of the table to #ccc when the Test Cell is ‘hovered’
MMPS: Set the background color of the table to Blue when the cell at Row 1 : Col 1 is ‘hovered’
MMPS: Set the background color of the table to Green when the cell at Row 3 : Col 3 is ‘hovered’

table.ps-table5 { background-color: Fuchsia; }
table.ps-table5! tr td.ps-row3.ps-col1:click { background-color: red; }
table.ps-table5! tr td.mmps_here:hover { background-color: #ccc; }
table.ps-table5! tr td.ps-row1.ps-col1:hover { background-color: blue; }
table.ps-table5! tr td.ps-row3.ps-col3:hover { background-color: green; }

Test Table 6 : Parent and Target Pseudo Class Events

This example shows how to use the Parent Selector syntax to style a Parent element based on Pseudo Class events on either the Parent or Target elements. If the Pseudo Class is defined on the Parent element then styling occurs when the event is triggered for the Parent element. However if the Pseudo Class is defined on the Target element instead then styling occurs when the event is triggered on the Target.

The first example Parent Selector style below uses a Parent Pseudo Class event of ‘hover’; the Parent element is styled when the ‘hover’ event is triggered on the Parent element. The second example style uses the same ‘hover’ event but triggered on the Target instead.

Table 6 : Row 1 : Col 1 Table 6 : Row 1 : Col 2 Table 6 : Row 1 : Col 3
Table 6 : Row 2 : Col 1 Table 6 : Row 2 : Col 2 Table 6 : Row 2 : Col 3
Table 6 : Row 3 : Col 1 Table 6 : Row 3 : Col 2 Table 6 : Row 3 : Col 3

CSS: Set the background color of the table to Khaki
MMPS: Set the background color of the row containing the Test Cell to Yellow when the row is ‘hovered’
MMPS: Set the background color of the row containing the Test Cell to Lime when the Test Cell is ‘hovered’

table.ps-table6 { background-color: Khaki; }
table.ps-table6 tr:hover! td.mmps_here { background-color: Yellow; }
table.ps-table6 tr! td.mmps_here:hover { background-color: Lime; }

Test Table 7 : Paired vs. Single Events

This example shows the difference between Paired events (such as ‘mousedown/mouseup’ and ‘mouseover/mouseout’) and Single events (such as ‘mouseup’ and ‘mouseout’). Note that some of the common Pseudo Class Events are actually Paired Events. For example the ‘hover’ event is actually a ‘mouseover/mouseout’ event pair.

Paired Pseudo Class events always set the Style upon the first event, then clear the Style upon the second event. In constrast, Single Pseudo Class events toggle the Style on and off with each trigger.

The first example uses a Single Pseudo Class event ‘mouseout’ to set the Style on the Parent. The Parent element’s Style is toggled each time the ‘mouseout’ event triggers on the Target.

The second example uses a Paired Pseudo Class event ‘mousedown/mouseup’. The Parent element’s style is set by the ‘mousedown’ event, then cleared by the Paired ‘mouseup’ event. Note that the second event is implied by the first event; you cannot specify it explicitly.

Table 7 : Row 1 : Col 1 Table 7 : Row 1 : Col 2 Table 7 : Row 1 : Col 3
Table 7 : Row 2 : Col 1 Table 7 : Row 2 : Col 2 Table 7 : Row 2 : Col 3
Table 7 : Row 3 : Col 1 Table 7 : Row 3 : Col 2 Table 7 : Row 3 : Col 3
CSS: Set the background color of the table to #eee
MMPS: Set the background color of the row to Salmon on the mouseout* event for cell at Row 3 : Col 3
MMPS: Set the background color of the row to PeachPuff on the mousedown** event for cell at Row 3 : Col 1

* – The styling set by the Single event is toggled with each trigger
** – The styling set by the first event of a Paired event is removed when the second event triggers
Note: The order of the last two styles is important for proper function.

table.ps-table7 { background-color: #eee; }
table.ps-table7 tr! td.ps-row3.ps-col3:mouseout { background-color: Salmon; }
table.ps-table7 tr! td.ps-row3.ps-col1:mousedown { background-color: PeachPuff; }

Test Paragraph 8 – Styling a Parent with Pseudo Elements

Two of the most frequently used Pseudo Elements are ::before and ::after. They allow you to insert content either before or after the styled element. Basic CSS only allows them to be used on the Selected element. The Parent Selector syntax allows us to extend that to the Parent element, not just the Selected element.

This example uses the Parent Selector syntax to modify the content of the paragraph, but only if the paragraph contains at least one element with one of our special Test Classes. The paragraphs below each contain an element with one of the Test Classes. The Class used determines how the Parent (the paragraph) will be styled.

This is a standard paragraph without Pseudo Element usage because it does not contain any special mmps_* Classes.

<p class="ps-para8">This is a standard paragraph without Pseudo Element usage because it does not contain any special <span style="font-family: 'courier new', courier, monospace;">mmps_*</span> Classes.</p>

This is a standard paragraph with the ::before Pseudo Element applied because it contains the special mmps_before Class.

<p class="ps-para8">This is a standard paragraph with the <span style="font-family: 'courier new', courier, monospace;">::before</span> Pseudo Element applied because it contains the special <span class="mmps_before" style="font-family: 'courier new', courier, monospace;">mmps_before</span> Class.</p>

This is a standard paragraph with the ::after Pseudo Element applied because it contains the special mmps_after Class.

<p class="ps-para8">This is a standard paragraph with the <span style="font-family: 'courier new', courier, monospace;">::after</span> Pseudo Element applied because it contains the special <span class="mmps_after" style="font-family: 'courier new', courier, monospace;">mmps_after</span> Class.</p>

This is a standard paragraph with the ::first-line Pseudo Element applied because it contains the special mmps_first_line Class.

<p class="ps-para8">This is a standard paragraph with the <span style="font-family: 'courier new', courier, monospace;">::first-line</span> Pseudo Element applied because it contains the special <span class="mmps_first_line" style="font-family: 'courier new', courier, monospace;">mmps_first_line</span> Class.</p>

This is a standard paragraph with the ::first-letter Pseudo Element applied because it contains the special mmps_first_letter Class.

<p class="ps-para8">This is a standard paragraph with the <span style="font-family: 'courier new', courier, monospace;">::first-letter</span> Pseudo Element applied because it contains the special <span class="mmps_first_letter" style="font-family: 'courier new', courier, monospace;">mmps_first_letter</span> Class.</p>

This is a standard paragraph with both the ::after and ::first-letter Pseudo Elements applied because it contains both the mmps_after and mmps_first_letter Classes.

<p class="ps-para8">This is a standard paragraph with both the <span style="font-family: 'courier new', courier, monospace;">::after</span> and <span style="font-family: 'courier new', courier, monospace;">::first-letter</span> Pseudo Elements applied because it contains both the <span class="mmps_after" style="font-family: 'courier new', courier, monospace;">mmps_after</span> and <span class="mmps_first_letter" style="font-family: 'courier new', courier, monospace;">mmps_first_letter</span> Classes.</p>

CSS: Set the background for elements with one of the example Classes to #f0fff0
MMPS: Put an image before any Paragraph that contains an Element with the ‘mmps_before’ Class
MMPS: Put an image after any Paragraph that contains an Element with the ‘mmps_after’ Class
MMPS: Boldface the first line of any Paragraph that contains an Element with the ‘mmps_first_line’ Class
MMPS: Boldface and enlarge the first letter of any Paragraph that contains an Element with the ‘mmps_first_letter’ Class

.mmps_before,
.mmps_after,
.mmps_first_line,
.mmps_first_letter { background-color: #f0fff0; }
p.ps-para8::before! .mmps_before {
 content: url('http://www.militantmoderates.org/wp-content/uploads/2015/06/bluearrow-16x14.jpg');
}
p.ps-para8::after! .mmps_after {
 content: url('http://www.militantmoderates.org/wp-content/uploads/2015/06/redarrow-16x14.jpg');
}
p.ps-para8::first-line! .mmps_first_line { font-weight: bold; }
p.ps-para8::first-letter! .mmps_first_letter { font-weight: bold; font-size: 20pt; }

Test Paragraph 9 – Styling a Parent with Pseudo Elements Part II

There are times when you want to apply one of the Pseudo Elements to a container element, but only based on events that happen to one or more elements within the container. For example you might want to display an image after a paragraph, updating it as the mouse hovers over different parts of the paragraph.

This might seem rather tough with normal CSS, but with Parent Selector syntax it is very easy. We simply define a Selector that applies the Pseudo Element (for example ::after) to the Parent element, and uses a Pseudo Class on the Selected element (such as :hover).

This example uses the Parent Selector syntax to insert images at the end of the Paragraph, but only as the mouse hovers over specific sections of the paragraph. The specific image is defined by one of the special Test Classes.

Hover the mouse over the Blue Arrow to display a blue arrow at the end of this paragraph, or hover over the Red Arrow to display a red arrow. The images only display while the mouse is over the highlighted areas.

<p class="ps-para9">Hover the mouse over the <span class="mmps_blue_arrow">Blue Arrow</span> to display a blue arrow at the end of this paragraph, or hover over the <span class="mmps_red_arrow">Red Arrow</span> to display a red arrow. The images only display while the mouse is over the highlighted areas.</p>

CSS: Set the background for elements with one of the example Classes to #f0f0ff
MMPS: Put a blue arrow after any Paragraph when it contains an Element with the ‘mmps_blue_arrow’ Class that is ‘hovered’
MMPS: Put a red arrow after any Paragraph when it contains an Element with the ‘mmps_red_arrow’ Class that is ‘hovered’

This second example uses the Parent Selector syntax to insert images at the end of the Paragraph, but only when the mouse clicks on specific sections of the paragraph. The specific image is defined by one of the special Test Classes.

Click the mouse on the Blue Arrow to display a blue arrow at the end of this paragraph, or click on the Red Arrow to display a red arrow. Also see the Note below to understand why this example sometimes seems “broken”.

<p class="ps-para9c">Click the mouse on the <span class="mmps_blue_arrow">Blue Arrow</span> to display a blue arrow at the end of this paragraph, or click on the <span class="mmps_red_arrow">Red Arrow</span> to display a red arrow. Also see the <strong>Note</strong> below to understand why this example sometimes seems "broken".</p>
CSS: Set the background for elements with one of the example Classes to #f0f0ff
MMPS: Put a blue arrow after any Paragraph when it contains an Element with the ‘mmps_blue_arrow’ Class that is ‘clicked’
MMPS: Put a red arrow after any Paragraph when it contains an Element with the ‘mmps_red_arrow’ Class that is ‘clicked’

Note: The order of the last two styles determines how they will interact. The red arrow style has higher precedence because it comes after the blue arrow style in the CSS. When the red arrow image is visible, it will override the blue arrow image. This makes it appear that the blue arrow style is “broken” when it is simply being overridden by the red arrow style.

.mmps_blue_arrow,.mmps_red_arrow { background-color: #f0f0ff; }
p.ps-para9::after! .mmps_blue_arrow:hover {
 content: url('http://www.militantmoderates.org/wp-content/uploads/2015/06/bluearrow-16x14.jpg');
}
p.ps-para9::after! .mmps_red_arrow:hover {
 content: url('http://www.militantmoderates.org/wp-content/uploads/2015/06/redarrow-16x14.jpg');
}
p.ps-para9c::after! .mmps_blue_arrow:click {
 content: url('http://www.militantmoderates.org/wp-content/uploads/2015/06/bluearrow-16x14.jpg');
}
p.ps-para9c::after! .mmps_red_arrow:click {
 content: url('http://www.militantmoderates.org/wp-content/uploads/2015/06/redarrow-16x14.jpg');
}

Test Paragraph 10 – Styling a Parent with Anchor Pseudo Classes

When you really want to get fancy with Parent Selector syntax, you can do some fun things based on the various Anchor Pseudo Classes. These are generally used to color an Anchor Link to indicate its state: Unvisited, Visited, FocusHovered and Active. (In CSS these are known as: link, visited, focus, hover and active.)

Parent Selector allows us to have a slightly more “enthusiastic” response to each of the Anchor States. We can wrap a descriptive title and the anchor inside a suitable container (for example <span>) then change its styling based on the state of the anchor it contains.

It sounds complicated, so lets just do it and see how it turns out.

Hover the mouse over the Link that follows HERE to highlight up through here with a special background color.

<p class="ps-para10">Hover the mouse over the <span class="mmps_link_box">Link that follows <a class="mmps_link_anchor" href="#test-paragraph-10">HERE</a> to highlight up through here</span> with a special background color.</p>

In this paragraph the Link goes to Google’s Home Page and the highlight goes to here with a special background color.

<p class="ps-para10">In this paragraph the <span class="mmps_link_box">Link goes to <a class="mmps_link_anchor" href="https://www.google.com" target="_blank">Google's Home Page</a> and the highlight goes to here</span> with a special background color.</p>

MMPS: Set the background color of the Parent element when the contained Anchor is ‘unvisited’ to #a0e0a0
MMPS: Set the background color of the Parent element when the contained Anchor is ‘visited’ to #fff0ff
MMPS: Set the background color of the Parent element when the contained Anchor has ‘focus’ to #efe0e0
MMPS: Set the background color of the Parent element when the contained Anchor is ‘hovered’ to #fff0f0
MMPS: Set the background color of the Parent element when the contained Anchor is ‘active’ to #f0ffff

.ps-para10 *! a:link { background-color: #a0e0a0; }
.ps-para10 *! a:visited { background-color: #fff0ff; }
.ps-para10 *! a:focus { background-color: #efe0e0; }
.ps-para10 *! a:hover { background-color: #fff0f0; }
.ps-para10 *! a:active { background-color: #f0ffff; }

Where to next?

We’ve provided a couple of pages with various examples of MMPS in action.