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.
Related
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.
What does the CSS standard say about unsupported expressions? How should a browser deal with them? How do actual browser implementations deal with them?
I'm implementing a CSS property optimizer (for a minifier project), and we want to leave CSS fallbacks intact. Our goal is to optimize the CSS as much as possible but in such a way that it should render exactly the same as the original.
This is why it's essential for me to understand how these things work.
Simple properties
For simple properties, it's really easy.
Let's say we have this:
div {
color: #f00;
color: rgba(1,2,3,.4);
}
In this case, if the browser doesn't support rgba then the first declaration #f00 wins. There is no question here.
Shorthands
However, how does it work with shorthand properties?
Here's some code:
div {
background: #f00;
background: rgba(1,2,3,.4);
}
How does the browser render this if it doesn't understand rgba? As you know, the syntax of background is: background: <color> <image> <repeat> <attachment> <position>; and such a shorthand declaration overrides any of the 5 fine-grained declarations that came before it; so the difficulty lies in which one of the 5 fine-grained properties the browser tries to assign the unknown token to. I have several possibilities in mind:
the browser decides it doesn't understand the latter declaration at all and drops it entirely
the browser thinks that rgba(...) represents a background-image and even though it doesn't know what to do with it, clears out the previous background-color as well
the browser thinks that rgba(...) represents a background-color and since it doesn't understand it, falls back to using #f00 instead
Let's make it even more interesting, say we have this:
div {
background: #fff url(...) no-repeat;
background: rgba(1,2,3,.4) linear-gradient(...) repeat-y;
}
How does a browser interpret this CSS snippet, ...
if the browser doesn't understand rgba?
if the browser doesn't understand linear-gradient?
if the browser doesn't understand repeat-y?
if the browser doesn't understand any two of the three?
if the browser doesn't understand any of the three?
The parsing rules in section 4.2 of the CSS2.1 spec speaks in terms of declarations, which refer to entire property-value pairs, regardless of whether the properties are shorthand or not:
Illegal values. User agents must ignore a declaration with an illegal value. For example:
img { float: left } /* correct CSS 2.1 */
img { float: left here } /* "here" is not a value of 'float' */
img { background: "red" } /* keywords cannot be quoted */
img { border-width: 3 } /* a unit must be specified for length values */
A CSS 2.1 parser would honor the first rule and ignore the rest, as if the style sheet had been:
img { float: left }
img { }
img { }
img { }
A user agent conforming to a future CSS specification may accept one or more of the other rules as well.
Notice that the third example shows the use of an illegal value for the background shorthand property resulting in the entire declaration being ignored.
Although the spec speaks of illegal values, as far as an implementation is concerned an unrecognized value and an illegal value are the same thing, since either way the implementation doesn't know what to do with such a value.
So the answer to the first part of your question is
the browser decides it doesn't understand the latter declaration at all and drops it entirely
And the answers to the second part are all the same: the latter declaration is ignored entirely.
As far as I know, if a browser cannot understand even a part of an expression, then it handles the property as syntactically wrong, and ignores the whole line.
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.
This is extremely simple but I am wondering why people write this?
div#some_id
You can only have one ID of that name "some_id" on a webpage. So why be specific with it? Is it for readability purposes?
There are a couple of possible reasons:
It is a more specific selector
It tells people reading the stylesheet that the selector is aiming at a div element
The same id could be applied to different element types on different pages that use the same stylesheet (this usually causes more confusion then benefits though, so I wouldn't advise that approach).
You're right, but this would mean a div with an ID of some_id. (More correctly, an element with an ID of some_id, which is also a div).
This grants a higher specificity value, but you're right. It's usually worthless with IDs, more useful with class names.
For example:
div.large { width: 500px; /* 500px is a large div */ }
input.large { width: 100px; /* 100px is a large input */ }
Same class name, different results.
The reason this is done is mainly for readability in the stylesheet.
As you can only have 1 id on a page it makes sense that you would not need to specify which type of element it is.
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.