Use "li" or "li a" for styling "a" inside "li" - css

Suppose the following HTML:
<li>
Link
</li>
Which one of the CSS styles is correct to set the font-size?
li {
font-size: 12px;
}
li a {
font-size: 12px;
}

Many CSS styles are inherited from a parent to its children, font-size included.
If you imagine this hierarchy as a tree, the general rule is to apply styles as high (parent) as possible but as low (children) as necessary. Styles should also be as general as possible (meaning low selector count).
In your case this means that if you only want to select the ‘a’s inside ‘li’s you should use the second rule. If you want the font-size of all ‘li’s to be 12px you may apply the style to the li or ul, ol or even the body or an outer container.

For your simplified example, either one will work. The first would affect all list items, though, whereas the second would only affect links within list items. Which one is appropriate depends on whether/how you're using list items elsewhere in the code.

Related

CSS get attribute of other element

I have a very simple question:
Is there a pure-CSS way to
get the attribute (value) of a different element or attribute?
(And yes, I know that CSS isn't an actual programming language - but there could be a feature)
Every now and then i stumble upon new possible (very different!) use cases but here two that come to my mind at this moment:
(1) ONE example OF MANY:
1.p and div are "sibling"Elements.
2.div is supposed to take up the rest of the space, their parent provides
3.To calculate the div's size, one (div) needs the other (p)'s height. When the rule is e.g. generally used for several elements, no matter p's content size.
(2) ANOTHER example:
Orienting the height of a child's element at it's parent's width or a structurally unconnected element. Not the window's width (vw).
The general goal is to not use javascript or wangle with html for styling, since only css should be used for that, that's it's point.
PS:THE ORIGINAL QUESTION HAD A WORSE EXAMPLE, HENCE SOME ANSWERS MAY NOT ENTIRELY FIT THE NEW QUESTION
With what you've described in your question, the basic nature of CSS will fit what you're asking.
H6 and button are siblings.
H6 and button are separate by the nature of HTML.
You will need to find the font-family of h6, and manually apply it to the button, using a css rule.
Unless of course you are asking if CSS can dynamically read an elements attributes after page load, and copy it's attributes over on it's own, in real time, then no.
h6 {
font-family times;
color: purple;
font-size: 1rem;
margin: 0;
font-weight: normal;
}
h6, button {
font-family: arial;
color: orange;
font-size: 2rem;
}
<div class="container">
<h6>TITLE</h6>
<button>BUTTON</button>
</div>
You can ensure two or more elements share a font-family without using combinators (+, , >, etc.) by using CSS custom variables. You cannot make one element directly refer to another element this way.
First, add a variable as follows to a globally-accessible selector like the root pseudo-class:
:root {
--main-font-family: times;
}
Now, you can refer to the above value by using the syntax var(--[var-name]):
h6 {
font-family: var(--main-font-family);
...
}
button {
font-family: var(--main-font-family);
...
}
This approach can be helpful with more complex applications, and in my opinion can be more clear than having multiple selectors with varying specificities overriding one another.
The only information you can "get" in CSS are the elements themselves through tags, classes, ids, attributes, etc.
You may however style elements and their siblings using the sibling selector.
h6, h6 + button {
font-family: value;
}
You may then have separate codeblocks for the specified selectors
h6 {
property: value;
}
button {
property: value;
}
If you'd like to learn more about the CSS adjacent and general selectors, I would refer to this link: W3Schools Combination Selectors

Difference between element#id-name and #id-name in css

In CSS what is is the difference between element#id-name and #id-name for the same element.Since id's are unique, then why are there the two forms given before used. For eg: Difference between div#para and #para.
element#id-name is "stronger" than #id-name and if there are multiple reference to one element, the stronger is the one applied to the element
see fiddle http://jsfiddle.net/kJrCT/
div#para only applies to divs with id "para", while #para applies to all element types with that id. Consider the fact that on another page you could have a span with id "para". You could use div#para to style only the div, span#para to style only the span, and #para to apply css styling to all #para elements throughout the website.
There are a number of reasons you might like to use the same id for different elements depending on the page being viewed. Also, being more or less specific affects the priority of the style being applied.
You can use the same css on multiple pages and if you use the same id-name but with different element you can use some common rules.
Example:
#title{
color: red;
}
h2#title{
font-size: 16pt;
}
h1#title{
font-size: 22pt;
}
So, your h1 with title id-name will be red and with size 22pt and your h2 with id-name (on other page) will be red too but with 16pt size.
In your case, Both are exactly the same. They refer to the same element.
Its just for readabilty, so that the person looking # the css can know which element has the id "para".
But Generally this is useful when you apply the same[generic] class to many elements at the same time, and you want to refer to only one specific element, having that class.
Eg:
.pull-left{
float:left;
}
// This applies to all the elements with this class
This can be given to a 'p' or a 'div' or any element. but if you want to refer to a div with the class pull-left, then you can use
div.pull-left /// refers only to the <div>'s having class pull-left

Overriding a class in CSS

There are already many questions related to this. But I'm still not clear. Also not sure if the title of the question is correct. Here's my problem:
What the below CSS code means?
#nav li { /*some cssA*/ }
#nav li.over { /*some cssB*/ }
#nav li a { /*some cssC*/ }
#nav li a:hover { /*some cssD*/ }
#nav li ul a span { /*some cssE*/ }
As per my understanding, please correct me if I am wrong:
Line 1: every li element within any element with id="nav" will have styling cssA
Line 2: When I put my cursor over every li element within any element with id="nav" will have styling cssB
Line 3: every a element within every li element within any element with id="nav" will have styling cssC
Line 4: When I hover every a element within every li element within any element with id="nav" will have styling cssD
Line 5: Every span element within every a element within every ul element within every li element within any element with id="nav" will have styling cssE. Also anyother ul or a element will not have this style untill unless the parent element has id="nav"
You are correct on all except .over, The "." represents a class. and "#" represents ID. But yeah, you've got the concept down.
Also, if you want to "Override" as the title says, you'll add
!important
to the end of any rules you want to take precedence over the others.
you can override the css by giving !important or you can give inline style.
priority of inline css is high then external css
All of the existing answers are correct, but there is a bit more to it than has been given already.
As has already been said, "li.over" is a combined selector - it will selector li elements that also have a class of "over". If you wanted to use different CSS properties or property values whilst the mouse is over (hovering over) the element then you use the pseudo class selector "li:hover". These are called pseudo class as you aren't selecting something that is part of the document, but based on the state of an element. There are also pseudo elements which again aren't in the document directly, but logical extensions of the document structure - for example first-child, first-of-type, fifth-of-type, odd items etc.
"#nav li ul a span" is a descendant selector, as you say it will select elements that are children (at any level) of each parent, so "#nav li" selects "li" elements contained within an item with ID "nav" - even several levels down.
If you want to select items that are direct children of the parent then you can use the ">" symbol. I.e. "#nav > li" will select li elements that are directly below any item with an ID of "nav", but not any li elements that are children of that element, or indeed elements below that.
Incidentally "#nav" is exactly equivalent to "*#nav" as it selects any element with the ID, you could also write "ul#nav" if you only wanted to select ul elements with the ID. This could in turn be combined with a class "ul#nav.bar" or even multiple classes "ul#nav.bar.touch".
Removing the space between the selectors like this combines them, so in the last case instead of looking for an item with class "touch" inside an item with class "bar" inside an item with ID "nav" inside a "ul" element, you are selecting a "ul" element with an ID of "nav" and both the classes "bar" and touch". An element like this-
<ul class="bar touch" id="nav">...</ul>
It is also possible to use attribute selectors, so if you wanted to select links which will open in a new window you could use "a[target=_blank]" - which selects based both on the presence of the attribute and the value - or if you wanted to select links with any href value you could use "a[href]". This simply selects all elements with this attribute.
On top of that you can even select items which are adjacent (next to) another element, if you wanted to select all paragraphs directly following an image then you would use "img + p" in your selector, or "p + img" if you wanted to select images directly following a paragraph. As always the last item in the selector is the one the styles are applied to.
It is generally considered good practice not to be overly specific with CSS selectors, as it makes your code much less re-usable. Unless you need to write "div.widget" just write ".widget" as the otherwise you'd not be able to create a "widget" using other elements, and it makes it much harder to override these properties later on in those cases you might need to.
To wrap up selectors, there's a good introduction to CSS selectors on MDN and Code School (paid course provider) also have a excellent online foundation course on CSS available for a very reasonable price which will go through selectors in some detail.
With regard to overriding classes, there are two further concepts you should understand - cascade order and specificity.
Given a HTML snippet of-
<div class="widget">
<p>
Some text you want to style
</p>
</div>
And the following CSS-
#widget p { color: yellow; }
p { color: blue; }
The color of the text would be yellow and not blue because the specificity of the first selector is greater (more specific) than the second. To understand this I suggest you have a play with a Specificity calculator and have a read of the Smashing Magazine tutorial on the subject.
In short though, inline styles trump all, and the more specific a selector the more likely it is to be applied in place of other selectors that would otherwise apply different property values. The value in the selector with the highest specificity score "wins", but other property values from selectors with lower specificity that do not clash will also still be applied to the element.
For example, altering our earlier CSS-
#widget p { color: yellow; }
p {
color: blue;
font-weight: bold;
}
The text will still be yellow, but will also be bold as there is no font-weight property given in the selector with higher specificity.
The last concept you should understand is what happens when two or more rules have identical specificity.
#widget p { color: yellow; }
#widget p {
color: blue;
font-weight: bold;
}
In this case our text is now blue as the second rule appears later in the stylesheet and thus overrides the first. If you have multiple stylesheets then the rules from the last stylesheet to appear in the document head will override rules with identical specificity.
In almost all cases you should use a more specific or the order of the selectors within the stylesheet in order to apply the right styles to the right element, and absolutely should not be routinely using the !important flag to achieve this unless absolutely necessary. See http://james.padolsey.com/usability/dont-use-important/ for a fuller explanation than I give here, but it rapidly becomes unmaintainable (what do you do when everything is "important") and it is also not accessible for users who may wish to override your styles in their user agent stylesheet (local to their browser) in order to help them read or use the page (increasing font size, contrast with background colour etc.)

Accessing other CSS divisions from one division

I have got a CSS division called home which has got certain attributes with an action for hover for the anchor tags inside the home division like this:
#home a:hover
{
background-image:url(images/template_03_1.png);
position:relative;
top:3.5em;
left:0.5em;
}
Now, what I want to do is access the 'home' id's attributes inside the block defined above so that I change the properties of the home division whenever some one hovers on an anchor tag inside the home division. I know this is very easily possible in JavaScript but is this possible using CSS only.
Thanks,
niting
Am I correct if I assume you want the following?
#home a:hover
{
#home.background-color: #fff;
}
If so, then: no. Not without JavaScript and not even with CSS3. You cannot edit an others rule's properties.
Recursion is also not possible, as you always style that what was selected last in the rule, so typing #home a:hover styles the anchor if hovered, #home .class styles anything that has class="class" and is a decendant of #home.
In other words, recursion with CSS-selectors is not possible (or I don't know about it...)
You could try setting the hover on #home itself, but that won't work in IE(6). Unfortunately, you can't style a parent based on a child's pseudo-class. Javascript is great for this.
If you have exactly one <A> in your <DIV> then maybe you can style your <A> to have the same dimensions like the surrounding <DIV> and give the <A> the desired background.

Styling Nested Lists in CSS

I would like to build a tree like navigation interface in pure markup (that is, without needing javascript/jquery etc.).
Unordered lists <ul> seem like the best solution, and I have found this tutorial on simplebits.com is very close to the solution I need. However, the author defines the stylesheet with the assumption that the final/max depth of any branch is already known:
#sitemap li ul li ul li {
padding-left: 16px;
background: url(bullet.gif) no-repeat 0 50%;
}
I want to know if there is way to allow the markup to descend "infinitely" and have the styling support this seamlessly.
If you need more clarification on this, please just let me know.
There are tutorials on this but there are two problems:
IE6 doesn't support :hover on tags other than anchors so you need a Javascript solution for that browser; and
It's actually really complicated to get it working consistently across the major browsers.
Consider the alternative using jQuery and the superfish (inspired by suckefish) plug-in:
<ul class="menu">
<li>...
</ul>
<script type="text/javascript">
$(function() {
$("ul.menu").superfish();
});
</script>
Done.
If you do go the (semi-)pure CSS route, I highly recommend you use one of the existing frameworks for this (like suckerfish or a derivative). Otherwise you'll just be pulling your hair out and spending a lot of time to get it to work right.
To answer your question about depth: that rule you mentioned essentially is going to infinite depth. Remember a space in CSS is a descendant selector not a child selector. The reason for the repeated groups is so that the rule only applies from (say) the third level down.
That's because the first and second levels will have special stylings. The first will be a horitzontal or vertical bar. The second will popout from that but from the third level down it will consistently popout in the same way.
the markup you supplied should work for any further elements without having to specify them directly.
for example:
#sitemap li {} -->level 1 and under
#sitemap li li {}--> level 2 and under (overrides previous rule)
#sitemap li li li {}--> level 3 and under (overrides previous rule)
so the last rule would automatically be applied to levels 4, 5, 6 and beyond.
unless you want specific styling for ALL levels, then you should be fine.
How about assigning a class to the unordered list elements?
#sitemap li.tree
{
padding-left: 16px;
}
I don't see why this would not work but correct me if I'm wrong.

Resources