Simplify css selectors with the same parent - css

.content p, .content ul, .content h1 {
text-indent: 35px;
}
Are there any shortcuts for this selector, like .content p, ul, h1 {}?
                                                           
                                     

With normal CSS you do not have a choice.
With CSS compilers like SASS or LESS you can write something like that:
.content {
.p, ul, h1 {
text-indent: 35px;
}
}
I nowadays highly recommend using Compass which makes writing CSS so much more fun.

There is a :matches() functional pseudo-class in Selectors Level 4 (aka CSS 4):
.content :matches(p, ul, h1) {
text-indent: 25px;
}
However, it isn't supported by any browser yet. But there are :-webkit-any() and :-moz-any() that bring the same functionality to Chrome and Firefox respectively.

Related

Foundation font sizing in lists

I'm using Foundation. I've got a dropdown menu structured like so:
<div class="dropdown"><ul><li>...
I want to change the font size of all the elements in this menu. However, when I try to target them with .dropdown { font-size: 0.5em; }, I get overridden by this rule from the Foundation styles: ul, ol, dl { font-size: 1rem; }.
Is my only recourse to target the list elements specifically? i.e. .dropdown ul { font-size: 0.5em; }. This introduces a lot of unwanted specificity. To make matters worse, there's a second font-size rule for nested lists, so I would have to account for that as well with even more specific selectors. Seems like I'll trip over this a lot.
Am I missing something? How do I make this not such an annoyance?
You will need to either make your styles more specific or alter the default size for all lists.
The reason being ul, ol, dl { font-size: 1rem }. If it had been using em or % instead, then it would have happily taken its context from the ancestor element (.dropdown in this case, which is .5em).
So, you could either do this:
ul, ol, dl {
font-size: 1em; // or 100%
}
Or
.dropdown ul, .dropdown ol, .dropdown dl {
font-size: 1em; // or 100%
}
They'll both do what you're looking for without the side effects that would come along with your proposed styles when there's nesting involved (.dropdown ul { font-size: .5em }). The second option I've provided should be specific enough to override styles for nested lists.

SASS Replicating nested selector

I'm using SASS for a project and so far I'm pretty satisfied with it.
However I have some code that should only be presented for IE 7 and below, using the class name .ie-lt8 for that. But when i extend that selector in SASS, with a nested selector i create multiple selectors.
Example (extending a display: inline-block code for IE):
SASS
/* My extension code */
.ie-lt8 %ie-inline-block {
display: inline;
zoom: 1;
}
/* I want the li to be inline-block */
#my-ul li {
display: inline-block;
#extend %ie-inline-block;
}
CSS produced
/* My extension code */
.ie-lt8 #my-ul, #my-ul .ie-lt8 li {
display: inline;
zoom: 1;
}
/* I want the li to be inline-block */
#my-ul li {
display: inline-block;
}
Generally this is just fine, but the #my-ul .ie-lt8 li worries me a little. In this example it's ok as the code works fine with both selector (the mentioned selector just doesn't exists). But what if i have another code where the selector DOES matter, then this would cause a problem.
A thought example:
SASS
/* I want the div to get a red border,
but the div inside .container to have a green border */
#myid .container div { border: 5px dotted green; }
#myid div {
#extend %red-border;
}
/* My extension code */
.container %red-border {
border: 1px solid red;
}
CSS it would produce
/* I want the div to get a red border,
but the div inside .container to have a green border */
#myid .container div { border: 5px dotted green; }
/* My extension code */
.container #myid div, #myid .container div {
border: 1px solid red; /* [OVERRIDE OF THE BORDER] */
}
My question is then; is there a way to make SASS only take the initial selector, without creating multiple selectors from a nested selector (a lot of selectors in one sentence)?
I tried gooling for this issue, but i find it hard to find any articles/blogs/etc. regarding this issue.
UPDATE
I'm aware of various workarounds, such as using #mixin's instead. I was just wondering whether there was something i missed regardig SASS, or if someone could tell me why this is? Cause it seems to me like it's kind of a bug.
My answer is in SCSS - not SASS so you'll have to convert...
For browser targeting like this, I would recommend using mixins, and furthermore - #content within a #mixin to achieve your desired results. It also sets up a much more understandable set of rules with context.
For your specific example, it's as simple as moving your inline-block fix into a mixin instead of declaring only as a class.
#mixin ie7-inline-block {
display: inline;
zoom: 1;
}
#my-ul li {
display: inline-block;
.ie-lt8 & {
#include ie7-inline-block;
}
}
Even better than that though, by using #content, you can always ensure that your style is prefixed with .ie-lt8 by making a mixin like so:
#mixin ie7 {
.ie-lt8 & {
#content;
}
}
#my-ul li {
display: inline-block;
#include ie7 {
display: inline;
zoom: 1;
}
}
Which will output the same css, but allows your IE7-Specific styles to be wrapped each time in some context that makes sense to anyone who reads your code.

IE6 css hacks and their standard css equivalence?

in the following there are some IE6 css hacks I need their standard equivalence.
.header {
zoom: expression(runtimeStyle.zoom=1);
z-index: 1;
}
.hmenu ul li {
float: left !important;
}
ul.hmenu li {
margin-left: expression(this.previousSibling==null?'0':'1px');
}
.nav {
position: expression(runtimeStyle.position='relative');
}
ul.hmenu li {
margin-left:expression(this.previousSibling==null?'0':'1px');
}
This is equivalent to li { margin-left: 1px; } and li:first-child { margin-left: 0; }.
I don't see the point of the other expressions, other than to set the properties in an IE<9-only way.
zoom: expression(runtimeStyle.zoom=1);
is setting zoom:1 so you can achieve hasLayout
float: left !important;
!important is supported in all browser and simply adds another layer of specificity to your declaration. i am quite positive that !important is not important in the above css...no pun intended :)
position: expression(runtimeStyle.position='relative');
runtimeStyle object represents the style of the object, which overrides the format and style specified in global style sheets, inline styles, as well as HTML attributes.
in this case, on pageload, .nav's position is set to relative

Does the order in css file play a role?

In my case I have, simplified a nested list and enclosing div, i cant change it, it's created by drupal menu.
I want to clone the menu of a hardcoded site (edit removed link)
How would i "embed" the boxes ( ul li ul li items ) in the submenu, is it possible in just a list in block display? Do i need a z-index for them? Or float? Is float even possible on list items?
In general i understand the cascading thing but still do hard in writing css with few repeates. Some tips for shortening would be nice.
My primary question for now is why the style of the last entry (marked) is overwritten. Does the order in file play a role?
#block-system-main-menu .content {
font-size: 17px;
font-weight: bold;
}
#block-system-main-menu div ul li {
width: 207px;
margin: 4px 0px;
}
#block-system-main-menu div ul li {
display: block;
height: 38px;
background: url(/sites/all/themes/schott/menuitembg.gif);
}
#block-system-main-menu div ul li .active-trail {
display: block;
height: 60px;
background: url(/sites/all/themes/schott/menuitembg_p.png);
}
div ul li ul li.leaf { /* both styles are overwritten */
display: inline-block;
background: url(/sites/all/themes/schott/subitem_passive.gif);
}
The last CSS rule written is the one that is used, but specificity takes priority over cascading.
An article on specificity: http://css-tricks.com/specifics-on-css-specificity/
So #block-system-main-menu div ul li .active-trail is the most specific and will overwrite other rules.
yes, the order of CSS definitely plays a role. Anything declared after a style overwrites the previous one. Also, if you want to overwrite default styles of some sort, include them after the default ones (whether you write them in the same file, or just do a meta link to your own stylesheet).
Change it to:
#block-system-main-menu div ul li ul li.leaf {
I'm slightly confused by what you're asking, but in general, if you have two identical rules, the later will be applied. However, if rules are not identical, the more specific rule will take precedence.
Edit: sorry, I can see you just figured that out

Can I override a #id ul li behaviour with a class definition

I have an area that is identified by a #id and there is a CSS like:
#id ul li {
margin:0;
}
can I, for a specific UL in that area, override the margin-setting? I understand that #id creates very high priority in evaluating the formatting.
I have tried:
.myclass ul li {
margin-left: 20px;
}
and
#id ul.myclass {
as well as
#id li.myclass {
Is it even possible?
I agree with SWilk, avoid !important if possible (and it is possible here). Some other solutions that SWilk did not offer is:
#id ul.myclass li {
or...
#id ul li.myclass {
The key is increasing the specificity of the selector, which the above, and SWilk's solutions do. The reason your original solutions did not work is that you did not include the other tag (ul or li) nor the #id with your addition of the .myclass.
Added after your comment that showed structure:
If your html is this (as you stated in your comment):
<div id="ja-col2">
<div>....
<ul class="latestnews">
<li class="latestnews">
And your current css is (as stated in another comment):
#ja-col1 ul li,
#ja-col2 ul li {
margin:0; padding-left:15px;
}
#ja-col2 .latestnews ul li, /*does not exist*/
.latestnews #ja-col2 ul li, /*does not exist*/
.latestnews ul li, /*does not exist*/
ul.latestnews li.latestnews {
list-style:disc outside url("../images/bullet.gif");
margin-left:15px; padding-left:15px;
}
ul li { line-height:180%; margin-left:30px; }
The reason you are not seeing any change is because three of your selector paths do not exist in your html structure, and the one that wins by specificity is the very first group. You need:
#ja-col2 ul.latestnews li
To override the #ja-col2 ul li.
.myclass ul li {
margin-left: 20px !important;
}
Should do the trick :)
Use pseudo fake :not ID
.myclass:not(#f) ul li {
margin-left: 20px;
}
#hello .hello-in{
color:red;
}
.hello-in:not(#f){
color:blue;
}
<div id="hello">
<div class="hello-in">
Hello I am red
</div>
</div>
you can even use :not(#♥) or any html4/5 ( depends on page type ) character
Avoid using !important. This is hard to debug and is very probable, that it will interfere with other selectors. Especially if you will try to change css in few months from now, when you will forget there was an !important clause in some place.
You need to put more specific selector than the previous one. Just use the class and id parts in one selector.
Try using either
#id .myclass ul li {
margin-left: 20px;
}
or
.myclass #id ul li {
margin-left: 20px;
}
depending on where the element with "myclass" class is located in the DOM tree - if it is the parent of the #id element use first example, otherwise the second.
If you want to be independent of the #id element, try to use:
#id .myclass ul li,
.myclass #id ul li,
.myclass ul li {
margin-left: 20px;
}
This will work for all li's inside ul inside .myclass element, and it will not matter whether there is any #id element in the tree.
Best regards,
SWilk
http://www.w3.org/TR/WCAG10-CSS-TECHS/#user-override
In order to ensure that users can control styles, CSS2 changes the semantics of the "!important" operator defined in CSS1. In CSS1, authors always had final say over styles. In CSS2, if a user's style sheet contains "!important", it takes precedence over any applicable rule in an author's style sheet. This is an important feature to users who require or must avoid certain color combinations or contrasts, users who require large fonts, etc. For instance, the following rule specifies a large font size for paragraph text and would override an author rule of equal weight:
P { font-size: 24pt ! important }

Resources