I'm using css2 to implement some fixes for IE7 on a website.
So I have to put margin-top:30px and margin-bottom:-30px a <h2> title but I dind't find right selector.
<div class="ui-content">
<h2>Text</h2>
<ul class="ui-listview">
List Items
</ul>
</div>
The fact is that Everytime there is a H2 followed by a UL, I must put those two properties, so I wanted to do a selector with h2 and ul, but I don't know wich ones...
Thanks to help me
You can't select h2s followed by uls but you can do it the other way round. E.g.
h2 + ul { /*your css to style the ul*/ }
So you could put fixes/negative margins or whatever on the ul?
This is a only-ie-7 selector:
IE 7 only
*:first-child+html h2 {}
Anyhow, I don't recommend it because almost no one uses this browser anymore, so neither should you program specially for it.
Everytime there is a H2 followed by a UL, I must put those two properties, so I wanted to do a selector with h2 and ul
As stated by #Spudley and #Coop, you can't select an element that is followed by another element (except rare cases with series of li or td or th and :nth-last-child() but it's more of a trick).
The closest thing you can do in pure CSS is testing if h2 is followed by (an)other element(s) or not, i.e. if it's not alone with :only-child pseudo.
From MDN:
The :only-child CSS pseudo-class represents any element which is the only child of its parent. This is the same as :first-child:last-child or :nth-child(1):nth-last-child(1), but with a lower specificity.
Support is IE9+ so if you want to style this element in IE7 and IE8 too (or in the precise case where it's followed by ul but not p or h3...), you'll need JavaScript or to add a class server-side and style this class.
.ui-content > h2:not(:only-child) {
margin-top: 30px;
margin-bottom: -30px;
}
EDIT:
You can also test if H2 is both the :first-child and the second-to-last child of its parent so it'll be styled if it's followed by whatever element but not if this second element has other siblings (third, fourth one, etc)
.ui-content > h2:first-child:nth-last-of-type(2) {
margin-top: 30px;
margin-bottom: -30px;
}
Simplest code would be ;)
<div class="ui-content">
<h2 class="followed-by-list">Text</h2>
<ul class="ui-listview">
List Items
</ul>
</div>
.followed-by-list {
margin-top: 30px;
margin-bottom: -30px;
}
Other trick that'd mean a complete overhaul of your project (say, for next project ;) ): never set a single margin-bottom to content elements (I mean h2, ul, p, etc. It's OK for div and below "blocks") and always set a margin-top to:
an element (general case) ex: p
if needed, an element coming after another like elt1 + p would have a certain margin-top, elt2 + p another one, etc
Related
I have defined two <ul> classes, px_p and px_s. Now I want to style all <li> elements that are contained within either <ul class="px_p"> or <ul class="px_s"> elements.
I had thought that ul.px_p, ul.px_s li {} would work, but no dice. I tried ul.px_p li, ul.px_s li {} as well.
The issue is that the <li> styling is
ul.px_p, ul.px_s li {
margin: 0.1em;
}
and .1em is being applied to the whole <ul> element, as well as the nested <li> elements. I just want the <li> elements, as the <ul> has a much larger bottom margin to graphically separate it from the following elements. The difference between px_p and px_s is _p is Primary, and has a bullet, while _s is secondary and has no bullet, it just indents more.
The selector should be like this:
ul.px_p > li,
ul.px_s > li {
...
}
Using the > selector will only match li elements whose parent elements are ul.px_p or ul.px_s.
This is important, given that ul.px_p li will match any descendednt li element ul.px_s. This will include nested elements which the style should not apply to.
As an side note, sometimes when working in browsers, a cached version of CSS is used and changes you have made may not be reflected. Force a full refresh of the browser page which should reload the full content using CTRL+F5.
I was wondering how this can be done.
Under each paragraph I want a 30px margin bottom, but only on articles with more then one paragraphs. How can I fix this?
I look out to your advice :)
Casper
If you're talking about <p> tags, using the following css selector:
p + p {
margin-top: 30px;
}
Would add a top margin of 30px to every paragraph that follows another paragraph... Would be the same effect as you asked.
http://jsfiddle.net/g91afp8z/
Actually it depends on your markup, however you may be able to target the <p> elements which are not the only of their type in their parent - the article - as follows:
EXAMPLE HERE
article > p:not(:only-of-type) {
margin-bottom: 30px;
}
If you want to exclude the last paragraph, add :not(:last-of-type) as well:
EXAMPLE HERE
article > p:not(:only-of-type):not(:last-of-type) {
margin-bottom: 30px;
}
It's worth noting that :not, :only-of-type and :last-of-type pseudo classes are not supported in IE 8 and below.
You could also fake the effect by adding margin-top to the 2nd, 3rd, 4th, ... paragraphs instead, by using General sibling selector p ~ p which is supported in IE7+ as well.
EXAMPLE HERE
article > p ~ p {
margin-top: 30px;
}
Is it possible with CSS and the latest Chrome or Firefox to automatically remove the top margin from the first <h1> tag, or do I have still have to use jQuery?
You just need h1:first-child { margin-top: 0px; } DEMO
There's no :first-of-page selector so no, you can't use CSS for sure. No way in CSS to extract all h1 from a page whatever their parents and preceding siblings and only take the first one.
You need to know a little bit more about your h1 elements.
Examples:
you can select the first h1 if it's also the (first and or only) child of body > header (or #header in HTML 4.01)
if all h1 are siblings, then h1:first-of-type is the first one for sure
if the first h1 is right after your main nav in a section, then body > nav + section > h1 would select it. Or maybe body > header > nav + section > h1:first-of-type
div#content h1:first-child { margin-top:0; }
AFAIK This won't work in IE6 and may be buggy in IE7.
Pseudo selectors.
h1:first-child {
margin-top: 0;
}
Note that those aren't supported in Failbrowsers (IE 7 and previous), so you may still need a jQuery backup solution.
Add a class to the h1 tag, like:
<h1 class="first">Your text</h1>
Then in the css:
.first
{
margin-top: 0;
}
I want to override another style sheet and set the float for all elements to none. If I use 'div, span, a' as the selectors or even 'body div, body span, body a', it doesn't override the previous class selector. I could use !important but this isnt great for obvious reasons.
.class {
float: left;
}
/* my overide */
div, span, a {
float: none;
}
Note- in the code ive only shown the class of 'class', but actaully their are many classes and id's.
Is there a way to do this without using !important? The reason im doing this is im mobile optimizing my site with media queries. I need to remove absolute positioning, floats, etc for all elements, but then i will want to add some of these styles to specific elements.
Thanks
As I wrote in my comment above:
Using the * selector is generally ill-advised. Selectors focus on the
key selector first (the right most selector) and so using the *
selector means that the browser must find all elements on the page.
This is a huge performance issue.
You can read more in this answer: (why) is the CSS star selector considered harmful?
Rather than using the * selector as you have, I'd stick with targetting the elements you want to affect, specifically.
Chances are, there will only be a few types of elements in your page that are floating.
These are usually some divs, perhaps some images, a list or two?
div, img, ul, ol{
float:none;
}
If there's a few more you can include them also.
#jdin; for overide the .class float just write like this:
div.class, span.class, a.class {
float: none;
}
EDIT:
Define an ID in your body tag like this
HTML:
<body id="home">
<div>Tag</div>
<span class="class">Class</span>
<div id="id">ID</div>
</body>
CSS:
body#home *{background:pink;border:1px solid #000}
Check this example http://jsfiddle.net/sandeep/D7Sg6/2/
Users can enter descriptions which may include paragraphs or lists. Or they may just enter text without any enclosing <p> or <ul> elements. What I need to do is remove most of the padding and margin above the first element and below the last element so that the user entered content has a nice tight border around it. So I could do one of the following:
Use a css rule I was unaware of to target only the first and last elements
Use css3 or html5 (I assume there's something within these to easily do what I want) and hope everyone upgrades their browsers asap while the older browsers just get a slightly uglier version of the page
Find the first and last elements with Javascript and modify accordingly
Modify the html to add a class like <p class="first">
Ideally the 1st solution exists, does it? I'm ok with the 2nd solution though if not, does it exist? The last 2 I don't care for...
UPDATE: don't care about IE6. But I do need to deal with the situation that if there's just text to begin with, without any <p> or <ul> or other elements, then actually nothing special needs to be done for the top margin/padding.
Use :first-child and :last-child like this. Note that > and :first-child (CSS2) doesn't work in IE6 and below, and :last-child (CSS3) doesn't work in IE8 and below. The only real workaround to both is to use a .first and .last class respectively (you can add them dynamically with JavaScript as Phrogz says).
.description > p, .description > ul {
margin: 1.5em 0;
}
.description > :first-child {
margin-top: 0;
}
.description > :last-child {
margin-bottom: 0;
}
I added the > combinator to prevent elements like strong or li getting selected. What does it mean?
Something like this?
.container * + p, .container * + ul
{
margin: 1em 0 0;
}
.container p, .container ul
{
margin: 0;
}
BoltClock's answer works great in most cases, but IE8 and earlier ignores the :...-child pseudo-selectors.
You can use jQuery to accomplish the same thing, while targetting more browsers.
//On ready...
$(function(){
//Update styles dynamically
$('ul:last').css({'margin-bottom':0,'padding-bottom':0});
$('ul:first').css({'margin-top':0,'padding-top':0});
});
Have you considered wrapping the content in a container with a negative margin? It requires the content to at least be wrapped in a single p element (not hard to test/add melodramatically).
CSS:
.container {border:1px solid black;}
.container .subcontainer {margin:-1em 0;}
.container p {margin:1em 0;}
HTML:
<div class="container"><div class="subcontainer">
<p>My first paragraph.</p>
<p>My second paragraph.</p>
</div></div>