CSS Specificity - Defining Classes & IDs - css

I've been reading up on specificity and, quite frankly, I'm surprised that I didn't know about this properly before, since I've witnessed the very issues that specificity can give if CSS is declared in the wrong manner.
So, I've been doing a little research on the subject, and I now understand the rule for calculating specificity. However, during my findings, I've been left with three questions which I was hoping you guys could help me out with.
Firstly, when relating to CSS specificity, I've noticed that one source includes pseudo elements in the calculation, while another tells you to leave them out of the calculation. Is this purely an optional thing, or should I include them?
Secondly, is there any specific reason why I should declare classes above identifiers? For instance, I've already sectioned my development CSS file, and in the 'footer' section, I have #footer, #footer-container, .grid and .one-third, declared in this order. Is this perfectly fine, or should I switch them around? The defined rules are below, to show that both classes don't contain any conflicting properties:
#footer {
background: #e4e4e4;
border-top: 1px solid #eeeeee;
border-bottom: 1px solid #666666;
overflow: hidden;
padding-bottom: 1em;
width: 100%;
}
#footer-container {
margin: 0 auto;
width: 100%;
min-width: 1000px;
}
.grid {
margin-right: 2.1%;
float: left;
display: inline;
position: relative;
}
.one-third {
width: 31.9%;
}
Lastly, just a quick question about listing CSS properties in alphabetical order. I fully understand that this is optional, but using my declaration for #footer above as an example, is there any preference for border, margin or padding, as in alphabetical (bottom; left; right; top), or declared as written in shorthand (top; right; bottom; left)?
Thank you very much!

Firstly, when relating to CSS specificity, I've noticed that one source includes pseudo elements in the calculation, while another tells you to leave them out of the calculation. Is this purely an optional thing, or should I include them?
This is news to me; it looks like pre-CSS2.1 pseudo-elements were originally supposed to be ignored when calculating selector specificity. The article that says to leave them out of the calculation was published almost a decade ago, right in the middle of CSS level 2's refactoring. Here's what the 1998 CSS2 recommendation says (which, for reference, is also quoted in that article, but the URL that it links to redirects to the latest revision of the spec where it's changed):
A selector's specificity is calculated as follows:
count the number of ID attributes in the selector (= a)
count the number of other attributes and pseudo-classes in the selector (= b)
count the number of element names in the selector (= c)
ignore pseudo-elements.
In CSS2.1, as well as the latest Selectors standard, pseudo-elements must be counted like normal type selectors when calculating specificity.
Perhaps what's even more curious is that CSS1 had the same rule for pseudo-elements in terms of specificity as the current standard:
Pseudo-elements and pseudo-classes are counted as normal elements and classes, respectively.
This leads me to believe that the change in CSS2.0 was ultimately reversed in CSS2.1 so it wouldn't break existing (legacy) stylesheets that happened to rely on the behavior, and/or because it simply didn't make sense not to include pseudo-elements since you apply styles to them like you do with actual elements.
Secondly, is there any specific reason why I should declare classes above identifiers? For instance, I've already sectioned my development CSS file, and in the 'footer' section, I have #footer, #footer-container, .grid and .one-third, declared in this order. Is this perfectly fine, or should I switch them around?
There should be no difference whether you place your classes before your IDs, as long as your two classes follow the order they are in and your two IDs, likewise. Even assuming that all of these rules happen to match the same element, the IDs should take precedence over the classes for any properties that need to be overridden.
Lastly, just a quick question about listing CSS properties in alphabetical order. I fully understand that this is optional, but using my declaration for #footer above as an example, is there any preference for border, margin or padding, as in alphabetical (bottom; left; right; top), or declared as written in shorthand (top; right; bottom; left)?
If you are declaring the longhand properties separately, then it's entirely up to you how you want to order them. I would certainly follow the order already laid out by the shorthands for the sake of simplicity.
FYI, the order in the shorthands is laid out the way it is because if you literally connect the dots, the order is actually clockwise starting from the top.

Many would argue not to use IDs at all for styling to avoid issues with specificity. You CAN use classes over and over or you can just use them for one element like an ID. I agree that it is an unnecessary issue to battle with when its just as easy to use a class. And before you say "but sometimes I cant change the markup." let me just say attribute selector. These may be a little more to type but to avoid problems with specificity I think its worth it. So
div[id='yourID'] {
}
and you dont have to worry about not being able to overwrite this later. This is especially helpful when you work on a team.

Related

Best practices for styling an element that can be positioned anywhere in a page

I wanted to know if there were a best practice for styling any element that in turn could be placed anywhere in a page and retain its margin.
For example:
An <h1> tag with a ruleset of margin-bottom: 2rem; and a <p> tag with a ruleset of margin-top: 2rem.
Now these elements can be used anywhere within a webpage. But we the <h1> is placed before the <p> tag we will be encountered with a spacing of 4rem, now the behavior that I'd like to have is to maintain the space of one or the other. As a reminder this is a small example, a web page may contain all sorts of html elements as well as buttons and other components. To create a ruleset for each instance and combination is super time consuming and cumbersome, is there a better way?
if you know margin collepsing so its help you understand that margin remaining between <h1> and p is only 2rem not 4rem and here a stackoverflow answerlink for your question... hope you got help form this
Most elements (such as <h1> and <p>) have in-built default vertical margins. These are the 'generally accepted' guidelines, and you shouldn't explicitly need to overwrite them. You can, however, and if you want to set your own 'generic' margins that can be used anywhere, the best approach would be to use classes. For example:
.margin-top {
margin-top: 15px;
}
Any element with this class (such as <h1 class="margin-top">) will have this rule overwrite their default. Naturally, you could apply the rule to h1 directly,
Yes, you will encounter situations where you have both a top and bottom margin sitting next to one another, but you will need to work out when this sort of behaviour is acceptable, and when it is not. One way to avoid this is to make use of adjacent sibling combinators:
h1 + p {
margin-bottom: 0;
}
Because the above rule has more specificity than the generic h1 selector, it will take priority.
Yes, it will be a pain to work out all of the possible combinations that you may encounter, and you will have to write rules for each scenario. But you can make use of the class-driven approach above in combination with adjacent sibling combinators to significantly help eliminate this problem:
.margin-top {
margin-top: 15px;
}
.margin-bottom + .margin-top {
margin-top: 0;
}
This will completely prevent any element with the class margin-top from applying its margin only if it follows a class with margin-bottom set.
Note that many other approaches exist to already, and one such approach makes use of a Lego analogy to suggest simply making use of a padding on each element that is equal to half of the gutter:
$gutter: 20px;
.element {
padding: $gutter / 2;
}
Which is illustrated in a complete proof-of-concept code example here.

semantic !important modifier interfering with styling

Is there any way to disable all these !important options in semantic-ui?
I keep running into issues with things like:
.ui.right.sidebar {
right: 0!important; /* why is this important */
left: auto!important; /* why is this important */
-webkit-transform: translate3d(100%,0,0); /* why is this NOT important */
transform: translate3d(100%,0,0); /* why is this NOT important */
}
Why does almost every positioning property have !important? Is there a way to compile semantic omitting the !important modifiers? It is interfering with my custom styling, and I have to do extra work that feels hacky (like countering margin: 0!important; with padding-top: NNpx and just hope that at least one isn't marked as !important in any of the states it could be in)
Disabling !important in semantic-ui is a bad idea as it may lead to unpredictable results. To understand more about why there are !important keywords in the framework, here are some statements made by Jack Lukic, the author of SUI:
..CSS should have a specificity property for defining priority (it was
part of the original discussion when creating css), however they left
us with automatic weight calculations from an arbitrary point system.
This is pretty terrible when you run into something that happens to be
classified less ".ui.button" lets say, having to override '.ui.menu
.ui.button' , there are only two solutions, arbitrarily increasing
weight by repeating class names in selectors, or using important...
Source 1
And also here (among other places):
...CSS specificity has always been a terrible sort spot of the
standard, instead of giving developers a way to assign priority to
rules we have to with two options, increase rule specificity or 'drop
the hammer' with !important.
A lot of css rules in semantic aren't able to increase specificity beyond a certain point. The only assumption we can make about a red ui
button is that it will have classes .ui.red.button, no greater
specificity can be gained by altering the selector. If we then have a
rule that appears later with the same or greater specificity we're
stuck without important.
I'm positive that each decision to use important in semantic was after dealing with no other option. This happens a bit more than other
libraries because the specificity is so granular in the library.
If you want to override the behavior, you can do two things:
Use one of the 3000 theming CSS variables in SUI
OR
Override the behavior by using more specific selectors
See this
One way to make your custom CSS more specific is to use an id in the
body tag of your page and use the following selector:
#bodyid .create-new-menu-btn {
//Properties }

Is it proper syntax to "nest" id declarations inside other id declarations in CSS?

So, I'm not sure what I've stumbled upon here. I'm working with some CSS and I know it is common place to do something like this:
#content{
/* Style the content div. */
}
#content p{
/* Style all p elements in the content div. */
}
I'd like to give one specific p element a float:right style. Only one such p element will occur in the content element. Naturally, I'd just give this element an id, but then I had the idea to do it this way:
#content #right_floating_p{
float:right;
}
This works when I run the code, but I was wondering about best practice and whether or not this actually does anything scope wise. I could just as easily define a separate id for right_floating_p, but to me it feels natural that it should be defined with the content id because it will be used only on one p element inside the content element.
If anyone has any information about this syntax, please let me know. Thanks!
My recommendation is to only include the last ID. This is fairly standard separation of concerns. What if you want to change the first ID #content, but the last one #right_floating_p still makes sense and shouldn't change? There is more room for error if you specify something unnecessarily.
Other reasons this is good:
Smaller, faster (but barely) download size for your users.
More readable, in my opinion.
Faster (but barely) performance.
Over-qualifying tags is bad practice in general, as far as performance goes. Browsers read your selectors from right-to-left, by the time it interprets your #content selector, that information is pointless. My advice is to not trust that the browser will optimize for this.
Alvaro nailed it in his comment above.
The id must be unique on the page, but not necessarily across the whole site. So, for instance, if you had the #right_floating_p element on every page, but it had a #content element as an ancestor only on a certain page where you wanted it styled differently, then you'd want to use the #content #right_floating_p selector to apply the context-specific style.
I would suggest only using the most precise selector as you can, not only for readability and file size, but also for specificity.
CSS selectors have a specificity to them, so if you were to override it later (such as with a media query), the more specific selector will override the less specific one.
#content #right_floating_p {
color: red;
}
div #right_floating_p {
color: green; /* Will not apply, as it's less specific */
}
p {
color: black; /* Even less specific */
}
It will work having the first selector, but it's not necessary.

CSS Comparison Operators

I need to target divs that takes up more than 80% of their parent div, for a progress bar. Considering that we can target a specific width with CSS:
[data-width=80]
How might we target a comparison? This did not work in Firefox or Chrome:
[data-width>=80]
A google search for css comparison operators surprisingly did not turn up anything useful or relevant.
Note that I am targeting a data-* property, which I set together when setting the width in Javascript. Obviously I could just have the Javascript write an over80 class and target that, but there are additional concerns for which I need the targeting done in CSS. For one reason, it is the designer's job to decide at which width the change occurs. For another reason, we are targeting multiple devices, not just desktop web browsers.
Here is the target HTML and the CSS:
<div id='progress-bar-outer'>
<div id='progress-bar-inner'><span id='percent-indicator'>60%</span></div>
</div>
#progress-bar-outer {
overflow-y: auto;
height: auto;
border: #2072a7 solid 3px;
position: relative;
}
#progress-bar-inner {
float: left;
height: 25px;
background-color: #2072a7;
width: 60%;
}
#progress-bar-inner[data-width<80] {
position: relative;
}
#percent-indicator {
position: absolute;
top: 5px;
right: 10px;
}
This is a frequently-asked question, but the answer remains the same: CSS does not provide attribute selectors with numeric operations.
None of the existing attribute selectors work with any sort of value semantic; they only look at values as raw strings, and so only rudimentary string-matching attribute selectors exist at most. The next Selectors specification, Selectors 4, does not appear to introduce any numeric value attribute selectors either, but since it's still in its early stages of development, you could propose this feature if you're able to provide some good use case examples.
On a somewhat related note, the given example [data-width=80] is invalid precisely because tokens starting with a digit are interpreted in CSS as either numeric values or dimensions, and CSS attribute selectors only accept either a string or an identifier in the value component, not a number or dimension. If such a feature makes it to Selectors 4, this restriction may be lifted.
And if we're going to talk about separation of concerns, one could argue that setting a data attribute for a presentational value such as width, especially for the sake of RWD, is questionable in itself. The most sensible solution to this problem would be element queries, which don't exist as yet (as far as I've heard, it's primarily because they're difficult to implement correctly).
At this point, your best bet is in JavaScript, really.

CSS Best Practices: Classes for all elements or styling by parent class?

So, I was wondering about the following: I have some main content div and a sidebar div and the CSS looks as follows:
.main{
width: 400px;
height: 300px
}
.sidebar{
width: 100px;
height: 300px;
}
I will not include now all the floating properties, since I am only interested in the following:
If I have a p element in both of them and I want them to have different styles, shall I give the paragraphs different classes or shall I define the style for them like this:
.main p{
color: blue;
text-align: right;
font-family: ...
}
And then for .sidebar p I would define something else...
The alternative would be to define a class p.myclass and define the style there.
I am trying to understand what a better practice is. Obviously I need less markup if I have 30 p elements in one of the elements with the first method, since I would have to give them all a class. On the other hand, I create CSS that I can only "use" for that parent element, instead of having a general definition that I can apply in more places in the site...
I noticed that in a lot of "big" websites, almost every single html element has its own class...
Any ideas?
I would definitely go ahead with the containment selector in the case you give. Fewer spurious classes in the markup is easier to maintain, and the rule ‘.main p’ says clearly what it does. Use your judgement to whether more complicated cases are still clear.
Note that ‘.main p’ selects all descendent paragraphs and not just direct children, which may or may not be what you want; accidentally-nested descendant matches are a potential source of bugs (especially for cumulative properties like relative font size). If you want only children to be selected you need ‘.main>p’, which unfortunately does not work in IE6.
This is one reason why many sites go crazy with the classnames: the more involved selectors that could otherwise be used to pick out elements without a classname, tend not to work in IE.
I vote for .main p and .sidebar p because:
It most clearly expresses your intention, as you're expressing it in English
It reduces the number of explicit classes you need in your HTML
If you change your mind later and want an explicit paragraph class with that style you can just add it: .main p, p.foo
In my opinion using nested selectors [ parent child relations ] will be harder to read and maintainable.
Evdn if the design changes in a frequent manner CSS should be less affected by that. So styling individual element will be easier in the case of maintainability.
If the element is going to exist in a predictable location then you can style it based on a parent element.
The major drawback of styling by class on each individual element is the bloat: If you have many of these elements, the CSS attributes will become a noticeable percentage of the transferred bytes. Especially for large documents, saving a couple of KB in the download can count. Even more so with AJAX requests or IE where parsing innerHTML is extremely slow.

Resources