What is the CSS selector for the top-level heading?

Is there a way to target the first occurrence of the highest heading element (h*) in a DOM structure?

Perhaps something along the lines of

(h1, h2, h3, h4, h5, h6):first-of-ordered-set

For example, if the DOM contains h2, h3, h1, h2, h1, it should select the first h1;
and if there is h3, h3, h2, h2, h4, it should pick the first h2.
Assuming that the h* elements are not nested.

Do you think CSS has this capability?

Here's a resource that might be helpful: https://css-tricks.com/extremely-handy-nth-child-recipes-sass-mixins/

Edit: Reason for wanting this functionality: In a CMS system, the "top heading" is used as the document title (post, page, etc.). However, it remains visible on the page, causing the title to appear twice - once as the post title and once in the body. JavaScript cannot be used. The top level of the h* may vary.

Answer №1

I stumbled upon something interesting that CSS cannot currently achieve. But maybe in the near future.

The W3C is working on new features:

.post-content:has(h1, h2, h3, h4, h5, h6)

By combining this with :not(), it will allow for the functionality I am looking for:

.post-content:has(h1) h1:first-of-kind,
.post-content:not(:has(h1)) h2:first-of-kind,
.post-content:not(:has(h1,h2)) h3:first-of-kind,
...

There's a limitation though - the :not() currently can only have a single "simple selector". If it had more support, then achieving this without :has would be possible.

To all the future readers, I hope this eventually gets resolved. As of now, I'll keep this open, hoping that someone can crack the code with CSS 3.1.

Answer №2

The primary challenge we face is the lack of a previous selector in CSS. For instance, while we can target the first h2, there is no straightforward way to select elements that precede it, like a h1.

The workaround involves hiding all elements after the desired element, ensuring it remains the last visible one. However, achieving the same effect with preceding elements is not feasible using CSS alone.

h1:first-of-type,
h2:first-of-type,
h3:first-of-type,
h4:first-of-type {
  color:red;
}


h1:first-of-type ~ * {
  display:none;
}
h2:first-of-type ~ *:not(h1) {
  display:none;
}
h3:first-of-type ~ h4 {
  display:none;
}


.container {
 border:1px solid;
}
<div class="container">
  <h3>text 3</h3>
  <h1>text 1*</h1>
  <h2>text 2</h2>
  <h1>text 1</h1>
</div>
<div class="container">
  <h3>text 3</h3>
  <h2>text 2*</h2>
  <h2>text 2</h2>
  <h4>text 1</h4>
</div>
<div class="container">
  <h3>text 3</h3>
  <h3>text 2</h3>
  <h2>text 2*</h2>
  <h4>text 1</h4>
</div>
<div class="container">
  <h1>text 3*</h1>
  <h3>text 2</h3>
  <h2>text 2</h2>
  <h4>text 1</h4>
</div>

To further refine this approach, a small JS script can be used to isolate the necessary element:

$('h3:first-of-type').prevAll('h4').hide();
$('h2:first-of-type').prevAll('*:not(h1)').hide();
$('h1:first-of-type').prevAll('*').hide();
h1:first-of-type,
h2:first-of-type,
h3:first-of-type,
h4:first-of-type {
  color:red;
}


h1:first-of-type ~ * {
  display:none;
}
h2:first-of-type ~ *:not(h1) {
  display:none;
}
h3:first-of-type ~ h4 {
  display:none;
}

.container {
 border:1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <h3>text 3</h3>
  <h1>text 1*</h1>
  <h2>text 2</h2>
  <h1>text 1</h1>
</div>
<div class="container">
  <h3>text 3</h3>
  <h2>text 2*</h2>
  <h2>text 2</h2>
  <h4>text 1</h4>
</div>
<div class="container">
  <h3>text 3</h3>
  <h3>text 2</h3>
  <h2>text 2*</h2>
  <h4>text 1</h4>
</div>
<div class="container">
  <h1>text 1*</h1>
  <h3>text 2</h3>
  <h2>text 2</h2>
  <h4>text 1</h4>
</div>

Instead of just hiding the elements, you can apply different styles by utilizing CSS classes:

$('h3:first-of-type').prevAll('h4').addClass('initial');
$('h2:first-of-type').prevAll('*:not(h1)').addClass('initial');
$('h1:first-of-type').prevAll('*').addClass('initial');
h1:first-of-type,
h2:first-of-type,
h3:first-of-type,
h4:first-of-type {
  color:red;
  font-family:cursive;
  font-style:italic;
}


h1:first-of-type ~ *,
h2:first-of-type ~ *:not(h1),
h3:first-of-type ~ h4,
h1.initial,h2.initial,h3.initial,h4.initial{
  color:initial;
  font-family:initial;
  font-style:initial;
}

.container {
 border:1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <h3>text 3</h3>
  <h1>text 1*</h1>
  <h2>text 2</h2>
  <h1>text 1</h1>
</div>
<div class="container">
  <h3>text 3</h3>
  <h2>text 2*</h2>
  <h2>text 2</h2>
  <h4>text 1</h4>
</div>
<div class="container">
  <h3>text 3</h3>
  <h3>text 2</h3>
  <h2>text 2*</h2>
  <h4>text 1</h4>
</div>
<div class="container">
  <h1>text 1*</h1>
  <h3>text 2</h3>
  <h2>text 2</h2>
  <h4>text 1</h4>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using a jQuery event to apply styles with CSS

Hello, I am using jQuery Easy UI on my webpage but feeling a bit confused. I want to create an input field that looks like a tagging field - meaning when the user types a separator character (let's say a comma), the word being typed will have its CSS ...

When the collapse button is clicked, I aim to increase the top value by 100. Subsequently, upon a second click, the top value should

https://i.stack.imgur.com/p9owU.jpghttps://i.stack.imgur.com/Kwtnh.jpg I attempted to utilize jQuery toggle, but unfortunately, it is not functioning as expected. <script> $(document).ready(function () { $(".sidebar ul li&quo ...

Sending data through forms

I'm having trouble storing values input through a dropdown menu in variables event1 and event2, despite trying global declarations. How can I successfully store a value to both variables and pass it to the JavaScript code? Thank you. <!DOCTYPE HT ...

What steps are necessary to alter the background color of a jumbotron?

Can someone help me figure out how to change the background-color of the 'jumbotron' class in Bootstrap? The default color set in bootstrap.css is #eee. I've tried various methods like replacing it with none, none !important, or transparent ...

Utilizing HTML and JavaScript to add grayscale effect to images within a table, with the ability to revert to the colored version upon mouseover

Seeking advice on utilizing the mouseover / mouseout event in javascript to implement grayscale on a table. The challenge requires creating a gray image grid (table) using HTML and then incorporating Javascript so that hovering over an image triggers it to ...

Unable to eliminate the default styling of Material UI table using an external CSS file

Currently, I am incorporating a Material Ui table into my project. My goal is to eliminate the border and adjust the padding of the table. Upon investigation, I came across a default className for material ui table known as MuiTableCell-root-40. Below is t ...

Utilizing Selenium for automating button clicks

When attempting to click a button represented by the following HTML code: <a href="javascript:submitPage('V','All Notes','');" class="viewFilter">All Notes</a> I have made multiple attempts to ...

The function iframe.scrollTo() is not effective for scrolling through Excel or PowerPoint documents on an iPad

I am trying to create a custom scrolling feature for iframe content specifically for iPad. Currently, I have set up my iframe like this: <div id="scroller" style="height: 300px; width: 100%; overflow: auto;"> <iframe height="100%" id="iframe" ...

Guide on integrating materialize-css npm package into webpack

I'm currently developing a client-side application with Webpack and facing challenges when trying to incorporate the materialize-css package. Using Henrik Joreteg's hjs-webpack package, I was able to include the yeticss npm package by importing i ...

Modify the CSS class by adding attributes dynamically instead of directly to the element

I encountered a situation where I needed to apply a css property to a class rather than an element. For example: $('.class_with_css').css({display:'none'}); This code would add the style "display:none" to all elements with the cl ...

Utilize Jquery to hide radio buttons, while allowing users to click on an image to display a larger version

My current HTML structure is restricted to SAAS, so I only have control over jQuery implementation. https://i.stack.imgur.com/OHB9K.jpg I am attempting to achieve a similar layout as shown in the image below. The main issue lies in how to (1) conceal ...

iOS is not receiving JSON data in the response headers

I am currently utilizing the CocoaHTTPServer for establishing my server connection. However, I encountered an issue with retrieving JSON data in the header file of my HTML page (web client). Here is the code snippet : HTML Page : endAPSession: funct ...

Ways to prevent a div containing a lengthy content string from extending beyond other divs

Check out my Codepen project here Here is the HTML code for my personal website: <div id="splash" class="divider"> <h1 class="text-center text-uppercase">vincent/rodomista</h1> <p class="text-center text uppercase">Full Stack ...

JavaScript | Calculating total and separate scores by moving one div onto another div

I have a fun project in progress involving HTML and Javascript. It's a virtual zoo where you can drag and drop different animals into their designated cages. As you move the animals, the total count of animals in the zoo updates automatically with the ...

JavaScript struggles when dealing with dynamically loaded tables

I am currently working on integrating the javascript widget from addtocalendar.com into my website. The code example provided by them is displayed below. Everything functions as expected when I place it on a regular page. However, I am facing an issue wher ...

Troubleshooting Bootstrap 4 problem with varying sizes of div content

I have encountered a problem with the script below, where the content in a div is of variable size and does not always occupy the entire horizontal space allotted by the col-6 class from one row to the next: <div class="card-body " > <div c ...

Remove the image from the container in Bootstrap

I'm looking to position an image outside the container so that the right margin remains within the default container width (responsive) while keeping the image aligned with a button consistently. Please refer to the image below for clarification: ht ...

CSS - Struggling to identify the source of unwanted horizontal scrolling?

Recently, I've been attempting to make adjustments to a responsive website that utilizes media queries. Despite my efforts, whenever the site is viewed on a mobile-sized screen, it consistently requires horizontal scrolling regardless of the screen&a ...

Changing a button to text with PHP upon clicking

I am looking to create a button that, upon being clicked, will show a simple "X" on the website in the same location as the button itself. Essentially, the button will vanish and be replaced by an "X". The current code for my button is straightforward: &l ...

In the event that the final calculated total is a negative number, reset it to zero. Inform the user of an error through the use of a prompt dialog box

I'm having trouble getting the grand total to display as 0 when I enter all amounts in positive values and then change the unit prices to negative values. However, it works fine when I only enter negative values throughout. Can someone please help me ...