CSS selector for first heading of the highest level? - html

How can I select the first of the highest h* elements present in a DOM?
Something like
(h1, h2, h3, h4, h5, h6):first-of-ordered-set
I.e. if a DOM tree has, in this order, h2, h3, h1, h2, h1, it would select the first h1;
and if the DOM has h3, h3, h2, h2, h4, it would select the first h2.
Let's assume h* elements are not nested.
I suspect CSS doesn't have that power, right?
Somethink potentially usable: https://css-tricks.com/extremely-handy-nth-child-recipes-sass-mixins/
Edit: Why I want it: A CMS system takes this "first top heading" as a title of the document (post, page, ...). But it leaves it in the page. And then it shows the title twice - once as the post title and once in the body. JavaScript is removed. The top h* level may differ.

I found something. CSS can't do it. Yet.
W3C is drafting new features:
.post-content:has(h1, h2, h3, h4, h5, h6)
Together with :not(), this will allow what I need:
.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 catch - the :not() currently can only have a single "simple selector". If it supported more, then it would be achievable even without :has.
Greetings to the future readers, I hope it worked out.
For now, I am leaving this open, maybe someone will figure out with CSS 3.1.

The main issue is that we don't have previous selector in CSS. For example, we can get the first h2 but if later we find a h1 we cannot have a selector to go backwards.
Here is the best you can do with CSS. You can hide all the elements after the needed one (so the element you want is the last visible one) but you cannot do the same with the previous elements.
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>
You may then combine with a small JS code to keep only the needed 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>
I used to make the element hidden but you can do the same with other styles:
$('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>

Related

Select first element in div

Is it possible to address the first element in a div when you don't know what the first element is.
I have for example two different divs
<div class="templateOne">
<h1>Header 1</h1>
</div>
<div class="templateOne">
<h2>Header 2</h2>
</div>
That I can then say
.templateOne > * {
margin-top: 0em;
}
or something like that.
If you want to use adress the first child element, you can use the :first-child or the :nth-child(1) pseudo-selector.
.templateOne :first-child {
color: red;
}
<div class="templateOne">
<h1>Header 1</h1>
<p>Content 1</p>
</div>
<div class="templateOne">
<h2>Header 2</h2>
<p>Content 2</p>
</div>
If you want to address only the first element with a specific class name you can use :first-of-type or nth-of-type(1):
.templateOne:first-of-type {
color: red;
}
<div class="templateOne">
<h1>Header 1</h1>
<p>Content 1</p>
</div>
<div class="templateOne">
<h2>Header 2</h2>
<p>Content 2</p>
</div>
> child combinator
* universal selector
:first-child
.templateOne > *:first-child {
margin-top: 0em;
}

Conditional CSS Selector by referencing neighbor section [duplicate]

This question already has answers here:
Is there a CSS parent selector?
(33 answers)
Closed 1 year ago.
I have the following css which works well, however, it executes all over my site which uses a CMS, so I'm trying to write a selector that only executes on example-widget when example-content is present. As you can see they are in two separate sections.
The widget works well everywhere on the site except one page where the above example-content is present, so I was just trying to fix this one page
#media(max-width: 767.5px) {
#content > div > div.row.component.column-split .example-content {
padding-left: 30px;
}
#content > div > div.row.component.column-split .example-widget{
margin-left: 30px;
}
}
<div class="row component column-split">
<div class="col-sm-8">
<div class="row">
<div class="component rich-text">
<div class="component-content">
<section class="example-content">
<p>Lorem Ipsum</p>
<br>
<p>Lorem Ipsum</p>
<br>
<span>Lorem Ipsum</span><br>
<span>Lorem Ipsum</span>
</section>
</div>
</div>
<section class="example-widget" id="example-widget">
<div class="widget-title">
<h3>Lorem Ipsum</h3>
</div>
</section>
</div>
</div>
<div class="col-xl-4">
<div class="row"></div>
</div>
</div>
There's still no parent selector in CSS, so you'll need to use javascript to check if the example-content element is present.
Here's a quick example using jQuery:
if ( $('.component-content').length > 0) $('.example-widget').addClass('highlight');
#media(max-width: 767.5px) {
#content > div > div.row.component.column-split .example-content {
padding-left: 30px;
}
#content > div > div.row.component.column-split .example-widget{
margin-left: 30px;
}
.highlight {
color: red;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row component column-split">
<div class="col-sm-8">
<div class="row">
<div class="component rich-text">
<div class="component-content">
<section class="example-content">
<p>Example content</p>
<br>
<p>Example content</p>
<br>
<span>Example content</span><br>
<span>Example content</span>
</section>
</div>
</div>
<section class="example-widget" id="example-widget">
<div class="widget-title">
<h3>Example widget</h3>
</div>
</section>
</div>
</div>
<div class="col-xl-4">
<div class="row"></div>
</div>
</div>

Target specific h2 on a page

I have some HTML like this.
<div class="platform-content">
<div class="content-wrapper">
<section class="entry">
<article class="post-type-page id123 page type-page status-private hentry" id="id123">
<section class="entry-header">
<h2 class="entry-title">Heading Text</h2>
</section>
I need to target just that one h2 element in order to change its color with css. I've tried doing the following.
#id123 h2 {
color: red;
}
It works, except every h2 on the page changes to red. I also can't just target h2 directly either as then it affects other pages as well. I can't seam to figure out how to target just that one specific h2 on that page only and not every one of them on the page.
Further down the page I have some form fields that have h2 elements in them like this. I don't want these to change to red.
<li id='field_18_75' class='gfield gsection field_sublabel_below field_description_below gfield_visibility_visible'>
<h2 class='gsection_title'>Title Text</h2>
</li>
The trouble is, all of this html is generated and I don't have any control over that. So I can't add a custom id to the element for example.
You should be able to capture only the elements with nth-child(n)
#id123 section h2:nth-child(1) {
color: orange;
}
<div class="content-wrapper">
<section class="entry">
<article class="post-type-page id123 page type-page status-private hentry" id="id123">
<section class="entry-header">
<h2 class="entry-title">Heading Text</h2><h2 class="entry-title">Heading Text</h2>
</section>
</article>
</section>
</div>
If you want a particular tag to be of red color, then give it a unique id and then set it's color as red.
#uniqueId {
color : red
}
<h2 id = "uniqueId">Heading Text</h2>
Give id to that particular h2 element:
<h2 class="entry-title" id="my-id">Heading Text</h2>
then in css:
#my-id {
color: red;
}
<h2 id="idA" class="entry-title">Heading Text</h2>
Put specific id on h2 tag.
#idA{
color : red
}
Use :nth-child for achieve this.. Like this check my answer..
.entry-header h2:nth-child(1){
color:red;
}
.entry-header h2:nth-child(2){
color:blue
}
.entry-header h2:nth-child(3){
color:yellow
}
<div class="platform-content">
<div class="content-wrapper">
<section class="entry">
<article class="post-type-page id123 page type-page status-private hentry" id="id123">
<section class="entry-header">
<h2 class="entry-title">Heading Text1</h2>
<h2 class="entry-title">Heading Text2</h2>
<h2 class="entry-title">Heading Text3</h2>
<h2 class="entry-title">Heading Text4</h2>
</section>
David Angulo - If entry-title is unique then you can use #id123 h2.entry-title instead.
Since you specified an id on the <h2> element, the code you specified should work. Keep in mind that ids on each page should be unique so the CSS instruction #id123 h2 { color: red; } should affect only the <h2 id="id123"></h2> element.
Example:
h2 {
color: blue;
}
#id123 h2 {
color: red;
}
<div class="platform-content">
<div class="content-wrapper">
<section class="entry">
<article class="post-type-page id123 page type-page status-private hentry" id="id123">
<section class="entry-header">
<h2 class="entry-title">Heading Text</h2>
</section>
</article
</section>
</div>
</div>
<div class="platform-content">
<div class="content-wrapper">
<section class="entry">
<article class="post-type-page id123 page type-page status-private hentry" id="id124">
<section class="entry-header">
<h2 class="entry-title">Heading Text</h2>
</section>
</article
</section>
</div>
</div>

Blank spaces randomly appearing at different places between divs

So I'm having a problem that randomly just started happening. I mean that it wasn't a problem yesterday, and today it is.
So, there are blank spaces appearing at random places in my page every time I reload it. There are 3 specific places the blank space happens, but they alternate every time. Note that this doesn't seem to happen on IE, it only happens on Chrome as far as I can tell. Also, when I resize the page even a single pixel, the blank spaces disappear, even if I set it to the original size where the spaces were appearing.
I have already set * { margin: 0; padding: 0;} at the start of my CSS file and it doesn't seem to have any effect. The blank spaces still appear.
My CSS file is very long, so I don't think pasting everything here will be useful. But my initial lines look like this:
* {margin:0;padding:0;}
html, body {height:100%}
#content {min-height:100%}
#content-inside {padding-bottom:135px}
#footer {height:250px;margin-top:-125px}]
* {font-family:arial;color:#555}
body {background-color: #CDE6BC}
p, h3, h4 {margin-bottom:6px}
h1 {font-size:32px;color:#57783F}
h2 {font-size:24px}
h3 {font-size:19px; font-weight: bold}
h4 {font-size:16px}
p, label, input {font-size:14px}
h2 {color:#57783F}
label {display:block;font-weight:bold}
input {padding:2px}
input[type="text"] {
background-repeat: repeat-x;
background-image: url(/cocamar/imagens/fundoCampo.png);
border: 1px solid rgb(119, 119, 119);
color: rgb(0, 0, 0);
}
br {clear:both}
/*a {color:blue;text-decoration:none}
a:hover {color:red;text-decoration:underline}*/
#header {background:#fff;padding:10px;padding-bottom:0px;text-align:center}
#footer {background:#57783F;padding:10px}
#footer * {color:white}
#footer-inside {text-align:center}
.card {padding:10px; position: relative;}
.sub {padding-top:20px;padding-left:10px}
.card {box-shadow:1px 1px 1px 0px rgba(0, 0, 0, 0.3), 1px 2px 5px 0px rgba(0, 0, 0, 0.3);margin:5px;background:white;min-height: 275px;}
/* responsive starts here */
* {box-sizing:border-box;margin:0;padding:0}
.row::after {content:"";clear:both;display:table}
[class*="col-"] {float:left}
[class*="col-"] {width:100%}
#media only screen and (min-width: 768px) {
.col-1 {width:8.33%}
.col-2 {width:16.66%}
.col-3 {width:25%}
.col-4 {width:33.33%}
.col-5 {width:41.66%}
.col-6 {width:50%}
.col-7 {width:58.33%}
.col-8 {width:66.66%}
.col-9 {width:75%}
.col-10 {width:83.33%}
.col-11 {width:91.66%}
.col-12 {width:100%}
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, maximum-scale=1, user-scalable=no" />
<meta http-equiv='Content-Type' content='text/html; charset=ISO-8859-1' />
</head>
<body>
<div id="content">
<div id="header">
<div id="header-inside">
<h1>Some Text Here</h1>
<br>
</div>
</div>
<div id="content-inside">
<div class='sub'>
<h2>Some Text Here</h2>
</div>
<br>
<div class='col-4'>
<div class='card'>
<h3>Some Text Here</h3>
<p>Some Text Here</p>
</div>
</div>
<div class='col-4'>
<div class='card'>
<h3>Some Text Here</h3>
<p>Some Text Here</p>
</div>
</div>
<div class='col-4'>
<div class='card'>
<h3>Some Text Here</h3>
<p>Some Text Here</p>
</div>
</div>
</div>
<br>
<div class='sub'>
<h2>Some Text here</h2>
</div>
<div class='col-12'>
<div class='card'>
<h3>Some Text Here</h3>
<p>Some Text Here</p>
</div>
</div>
<br>
<div class='col-6'>
<div class='sub'>
<h2>Some Text Here</h2>
</div>
<div class='card'>
<h3>Some Text Here</h3>
<p>Some Text Here</p>
</div>
</div>
<div class='col-6'>
<div class='sub'>
<h2>Some Text Here</h2>
</div>
<div class='card'>
<h3>Some Text Here</h3>
<p>Some Text Here</p>
</div>
</div>
</div>
</body>
</html>
Please tell me if anything is missing so I can edit it.
The expected result looks like this:
But what I'm getting is this:
For my "sub" elements, Chrome's Inspect Element is saying this:
What could be causing this? I haven't added any code since yesterday, but this wasn't happening then, and it's happening now.
The code snippet does not replicate the issue you're having in your screenshot which makes diagnosing and helping a lot more difficult. That said, I suspect the issue is with the bar going across the SSIs box:
As your boxes are floating to the left, the box on the right will sit under whatever overflowing content is coming out of the box on the left. Perhaps add overflow:hidden to the parent div?
.card {
overflow:hidden;
}

Columns in HTML/CSS + scroll

I need to know how to display text in columns inside a horizontal scrolling box.
Basically I have a 600x300 box, and each bit of information is given inside a column, like;
Column 1... Column 2 .... Column 3
Para 1..... Para 2 ...... Para 3
Without the dots.
The thing then has to be contained within a horizontal box.
So how is this done?
I used something like the following to create the columns:
<style>
.column {
width:200px;
float:left
}
</style>
<div class="column">
<h2>header text</h2>
<p>paragraph text What if this is longer</p>
</div>
<div class="column">
<h2>header text</h2>
<p>paragraph text</p>
</div>
<div class="column">
<h2>header text</h2>
<p>paragraph text</p>
</div>
But I cant' figure out how to contain this all within a box that can scroll horizontally
Add overflow-x: scroll to your CSS definition.
Put it in a container that has white-space:nowrap and make the columns display:inline-block
.column-container{
white-space:nowrap;
}
.column {
width: 200px;
display:inline-block;
vertical-align:top;
white-space:normal;
}
<div class="column-container">
<div class="column">
<h2>header text</h2>
<p>paragraph text What if this is longer</p>
</div>
<div class="column">
<h2>header text</h2>
<p>paragraph text</p>
</div>
<div class="column">
<h2>header text</h2>
<p>paragraph text</p>
</div>
<div class="column">
<h2>header text</h2>
<p>paragraph text</p>
</div>
<div class="column">
<h2>header text</h2>
<p>paragraph text</p>
</div>
</div>