I would like to add padding-top: 20px; between h3 and body but not if h3 is preceded by another element (e.g., h2). Is this possible?
Adding padding-top to all headings gives the desired padding when a heading is preceded by body text but an undesired padding between headlines:
Note that this document is Rmarkdown created using knitr, so I don't have full control over all the html. A pure CSS-solution would be preferred.
UPDATE:
To anyone also using knitr for Rmarkdown, the solution turned out to be a rather complex targeting:
/* First h2 following h1 */
.level1 > .level2:nth-child(3) > h2 {
padding-top: 0px;
}
/* First h3 following h2 */
.level2 > .level3:nth-child(3) > h3 {
padding-top: 0px;
}
Looking at the generated HTML, I learned that the first h2 after a h1 was in the third element in level1 and that that element was called level2. Similarly for the first h3. This is what is targeted above. The structure is probably different in other documents so take a look yourself.
How about
body > h3:first-child {
padding-top: 20px;
}
That will affect only immediate child of body with a header3, with nothing in between.
Thanks to #Oram, for pointing out missing :first-child
You can use the > selector plus :first-child to target only a direct h3 child.
* {
margin: 0;
padding: 0;
}
.test {
background-color: #cccccc;
margin: 10px;
padding: 10px;
}
.test > h3:first-child { color: red; }
<div class="test">
<h3>Targeted h3</h3>
<p>Paragraph</p>
<h3>h3 not targeted</h3>
</div>
<div class="test">
<p>Paragraph</p>
<h3>h3 not targeted because of the p tag</h3>
<h3>h3 not targeted</h3>
</div>
Try this:
body > h3:first-child {
padding-top: 20px;
}
It will only apply the CSS to the first direct child of the body which is a h3.
Related
I am trying to replicate an navigation bar based off an example I saw. If someone could explain what it does that would be great.
https://i.stack.imgur.com/3WB0Y.png
.topnav a {
float: left;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
It is an 'Descendant Selector', meaning it whatever is inside of 'topnav' class with the tag 'a' will be affected by the written css rules. You can refer to https://www.w3schools.com/css/css_combinators.asp for more information
It targets the anchor inside the topnav element
.topnav a {
color: red;
}
<div class='topnav'>
<a>I am the link</a>
</div>
It's basically the tag inside a HTML element with the class name topnav. Here's an example :
<div class="topnav">
About
</div>
You can see the " < a > " there, in your CSS code we use .topnav a, it's not the best term to use but we can say that the .topnav a just grabs the childs of the class topnav.
I have an H1 inside an article element.
My h1 is styled something like this:
h1 {
&:extend(.display1);
border-bottom:solid 0.1rem #divider;
color:#primaryText;
margin-bottom:2.4rem;
padding-bottom:0.7rem;
}
However, I only want to apply this styling when the H1 isn't inside an article. I thought it would be a simple addition to the CSS like this:
*:not(article) h1 {
}
However, this doesn't seem to work for me and I've been left scratching my head. Is it possible? Have I got the syntax right? Is there something else lurking in the CSS?
Any help appreciated.
Yes, you can use this:
h1 {
color:blue;
margin-bottom:2.4rem;
padding-bottom:0.7rem;
}
:not(article) > h1{
color: green
}
http://codepen.io/anon/pen/zvKKqE?editors=110
Have you tried the 'old fashioned way'?
.article h1{ /* insert styling for h1 inside article */ }
h1 { /* insert styling for h1 outside article */}
Please note that .article h1 takes all elements from h1. So make sure you override the different styles (e.g. with !important).
--EDIT--
If you want to use :not() I can't see something wrong with your lines of code.
How does the HTML looks like? I got this example in JSFiddle:
https://jsfiddle.net/2aruu0Lr/1/
It doesn't work if there is no parent tag for h1, it does if there is one like a <span> or in my case a <strong>
Hope this helps you!
Solution:
body *:not(article) h1
Does this the trick for you?
#primaryText: #000000;
#divider: lime;
.display1 {
padding: 15px;
}
h1 {
&:extend(.display1);
:not(article) > & {
border-bottom:solid 0.1rem #divider;
color:#primaryText;
margin-bottom:2.4rem;
padding-bottom:0.7rem;
}
}
Output:
.display1,
h1 {
padding: 15px;
}
:not(article) > h1 {
border-bottom: solid 0.1rem lime;
color: #000000;
margin-bottom: 2.4rem;
padding-bottom: 0.7rem;
}
I am needing to indent all elements after headings to give a visual structured layout.
I have seen that this is possible in the this question :
Indent all tags following h2 until next h2 is hit using CSS
However, I am unable to "reset" when going back a level.
To be more clear, I need to have progressive indents which cancel when moving back.
So
H1
H2
.....
H2
.....
H3
....
H2
.....
H1
....
If possible, I would prefer to not use enclosing DIV's but rather pure CSS.
Is this possible ?
Here is a code snippet for indenting. I hope I understand what you want correctly.
* {
margin: 0;
}
h1 ~ *:not(h1) {
margin-left: 1em;
}
h2 ~ *:not(h1):not(h2) {
margin-left: 2em;
}
h3 ~ *:not(h1):not(h2):not(.h2):not(h3) {
margin-left: 3em;
}
h4 ~ *:not(h1):not(h2):not(.h2):not(h3):not(.h3):not(h4) {
margin-left: 4em;
}
<h1>H1</h1>
<h2>H2</h2>
<h2>H2</h2>
<p class="h2">test</p>
<h3>H3</h3>
<p class="h3">test</p>
<h4>H4</h4>
<p class="h4">test</p>
<h2>H2</h2>
<p class="h2">test</p>
<h1>H1</h1>
<h2>H2</h2>
<h2>H2</h2>
<h1>H1</h1>
UPD:
Oh, I see about other elements - sorry didn't get it. Maybe somehow like this?
You can use the CSS text-indent property.
h2, h2 + * {
text-indent: 50px;
}
h3, h3 + * {
text-indent: 100px;
}
Ok, here is the solution which works for me :
h1 + *:not(h1)
{
margin-left: 0em;
}
h2 + *:not(h2), h2
{
margin-left: 20px;
}
h3 + *:not(h3), h3
{
margin-left: 40px;
}
The key is to use the plus sign (+) as opposed to the tilde sign (~).
Hope this helps others also.
Edit : Ok, spoke too soon. This will successfully indent and outdent, but only for the first sibling element. If there are multiple sibling elements, it will fail.
Any ideas ?
i have a main "div" with multiple divs and "a" tags and i wanted to set a "template like" css to make them all look the same, but some of the A tags need to be different so i thought about making it like this:
<div class="main">
CLick A
<br/>
CLick B
<br/>
CLick C
....
</div>
and on the css:
.main a{
/* Links Scheme */
}
.exception{
/* particular link css */
}
But the browser gives preference to my "template" instead of the particular class. shouldn't the class be the most important or am i missing something?
FIDDLE Link
PS: without the use of "!important" tag please
This is an issue of specificity. Since .main a includes a class and a tag name, it is more specific, and thus gets higher precedence than just a class name.
So, to solve it, use .main .exception for your exception.
.main a is more specific then .exception. I think what you are going for is:
.main a{
/* Links Scheme */
}
.main a.exception{
/* particular link css */
}
In css, orders are also determined by how specific the selector is, so try changing .exception to .main a.exception.
jsFiddle: http://jsfiddle.net/jdwire/DFNyW/2/
you can use :not() pseudo-class, The :not() CSS pseudo-class represents elements that do not match a list of selectors. Since it prevents specific items from being selected, it is known as the negation pseudo-class. so you can fix code like this:
.main a:not(.exception){
color: #3b5998;
outline-style: none;
text-decoration: none;
font-size: 11px;
font-weight: bold;
text-decoration: none;
}
.exception{
color: #0498ba;
font-family: Verdana, sans-serif;
font-size: 30px;
letter-spacing: 2px;
margin: 0 0 0;
padding: 0;
font-weight: bold;
text-decoration: none;
}
<div class="main">
CLickA
<br/>
CLickB
<br/>
CLickC
</div>
I want to put a space after all the headers using CSS. Like this:
if h1 = add a space after
else if h1 + h2 = add a space after also but no space in between
This is my HTML code
<article>
<h1>Title 1</h1>
...
</article>
<article>
<h1>Title 1</h1>
<h2>Title 2</h2>
...
</article>
For the CSS
h1, h2 { padding-bottom: 20px; }
The problem is, there is a space also between h1 and h2. I tried this code below but only those articles with h1 and h2 have a space after.
h1 + h2 { padding-bottom: 20px;}
Is there a way to do this? Or I should just use the h1 + h2 in CSS and add < br > for h1 only?
There's a few ways to do this, none pretty.
/* #1 */
h1 + *:not(h2),
h2 + *:not(h3) { /* etc */
padding-top: 20px;
}
/* #2 */
h1, h2 {
padding-bottom: 20px;
}
h1 + h2 {
margin-top: -20px;
}
(and variations of these.)
The problem is there is currently no way to select "backward," i.e. apply styles to an element based on what appears after it. There is only the ability to select "forward," using the + or ~ sibling combinators. So you can't override the style on an <h1> based on the existence of a subsequent <h2>.
In the CSS4 selectors draft, there is a method of specifying the subject of the selector, using the $ sign. In that case the code would look like:
h1, h2 {
padding-bottom: 20px;
}
$h1 + h2 {
padding-bottom: 0;
}
/* or even */
h1:not($h1 + h2), h2 {
padding-bottom: 20px;
}
This isn't currently available in any browsers, however.
Is there no way to know when generating the HTML if the h2 is following the h1? That seems like the best way to handle this. Then you can make a simple css rule for h2.follows_h1 { margin-top: -5px } or whatever fits exactly what you need.