I'm learning CSS and I have the result I want but only if I use the ! important; specification. I don't understand why I can't override a property inheriting one class and overriding a property.
form button.minor-action,
#profile-left a.action,
.minor-action {
display: inline-block;
background: #lightBlue;
color: white;
padding: 0 1.2em;
border-radius: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
-ms-border-radius: 4px;
text-decoration: none;
text-align: center;
font-weight: bold;
border: none;
height: 25px;
margin-top:1.0em;
line-height:25px;
white-space: nowrap;
&:visited {
color: white;
}
&:hover, &:active, &:focus {
background-color: darken(#lightBlue, 10%);
text-decoration: none;
}
&.call-to-action {
background-color: #pink;
&:hover, &:active, &:focus {
background-color: darken(#pink, 10%);
text-decoration: none;
}
}
}
.extra-questions {
margin-top: 0em !important;
}
I thought that if I use the above style for a button:
<button id="add_question" class="extra-questions minor-action">{% trans "Lägg till ny" %}</button>
then I wouldn't have to use the ! important; statement and the override would work without it, but it doesn't. What am I missing? can you please help me understand why it doesn't work without the ! important statement, or show me a way do to it without ! important; ?
Its is not entirely correct that it isnt overridden because its set in the class above, in this instance it isnt due to the order of your LESS - it isnt being overridden because you have listed your classes in the wrong order- instead of
extra-questions minor-action
You need to do
minor-action extra-questions
When denoting classes, if they share values for the same property settings- those values for the last class applied will take precedence.
Alternatively, you can add more specificity to your classes, in your LESS, nest extra-questions within minor-action and prefix with &. This will mean the order of classes in your HTML does not matter, the combination does. The output CSS will be:
.minor-action.extra-questions
Also, as I am sure you are aware, using !important should be avoided
Your example works without !important - http://jsfiddle.net/sgguap7v/
It does not work !important without that case -
1. The rule is to follow the class - .extra-questions {} .minor-action {}
2. The rule has a higher weight - button.minor-action {} It has a greater weight than .minor-action {}
The css rule are applied depending on the order you call them, and the more specific they are.
if you have 2 rules defining the margin-top The browser then have to decide which one to apply. To do that it read your css file from top to bottom and calculate the priority of each rules based on the following.
Priority 1: #id (Id are unique selector so very important)
Priority 2: .class (Then the class they are less important than ID but still )
Priority 3: element (Finally generic style that is overridden most of the time, this is your default style)
Each time you add a nested selector it add to the priority as well so:
body.class is more important than .class and body #id is more important than body.class etc...
Finally if the rules ends up with the same priority, the last one is apply.
setting the !important flag in your code is a way to artificially boost the priority to a particular rule. But if you end up having the same rule with !important then the priority rules above will apply.
Override Will Work if You Do
.minor-action{
margin-top: 0em;
}
You didn't apply any styles to .extra-questions but to .minor-action. its true you apply to a same element. but cascade just work like that.
This will help: How to override the properties of a CSS class using another CSS class
And This: http://www.w3.org/TR/CSS2/cascade.html#cascade
Because its already set in the class above .minor-action, if it's set it doesn't override unless you use !important
Your first selector is more specific, it applies to elements that are children of a form, and it just overrides the most general (the second one) which applies to any of your .yourclass regardless of its position in the document hierarchy. you can get rid of the important by selecting form .yourclass instead.
Related
Consider this:
h1 { color: red; color: blue }
Or, a more complex example (taken from a SVG file, stroke is twice):
style="fill:none;stroke:#ffffff;stroke-width:20;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke:#555555"
It seems that the answer is “it’s legal, the last assignment wins”, but I’d really like to know: Is there something written in the CSS specification about this topic?
It is valid to have multiple declarations that assign a value to a property so that the assignments apply to the same element, e.g.
h1 { color: red; }
h1 { color: blue }
Combining the declarations in the same rule does not change this.
There is no explicit statement about this in CSS specifications, so it is allowed simply because there is no rule that forbids it. Multiple declarations are very common, though mostly so that they are in different rules, often even in distinct style sheets. But they can also be used within a rule. A common technique is
p { max-width: 25em; max-width: 60ch }
which means that older browsers that do not recognize the ch unit will use the setting max-width: 25em, whereas in newer browsers, the latter declaration takes effect.
A general rule in CSS is that all other things being equal, latter declaration wins; this is part of the cascade rules. In the case of h1 { color: red; color: blue }, all other things are equal. But in h1 { color: red !important; color: blue }, the first declaration would win.
It is COMPLETELY VALID, h1 { color: red; color: blue } here color will simply be overridden by the next property value i.e blue
Even I use that while my website is in development mode, I often use border: 1px solid #f00; to create a blueprint of the page.
I'm trying to override a particular widget's style using UiBinder. What am I overlooking?
<ui:style>
/*************
* Note #1
*************/
.btnVote {
display: inline-block;
width: 50px;
height: 50px;
background: #fff;
margin: 5px;
text-align: center;
outline: none;
cursor: pointer;
}
/*************
* Note #2
*************/
.btnVote-up-hovering, .btnVote-down-hovering {
background: #ddd;
}
.btnVote-up-disabled, .btnVote-down-disabled {
border-shadow: inset 0 1px 3px #aaa;
}
.lblName {
line-height: 50px;
font-size: 40px;
padding: 5px 10px;
}
.clear {
clear: both;
overflow: auto;
}
.floatLeft {
float: left;
}
</ui:style>
<g:HTMLPanel styleName="{style.clear}">
<g:FlowPanel styleName="{style.floatLeft}">
/*************
* Note #3
*************/
<g:PushButton ui:field="btnVoteUp" stylePrimaryName="{style.btnVote}">
(+)
</g:PushButton>
<g:PushButton ui:field="btnVoteDown" stylePrimaryName="{style.btnVote}">
(-)
</g:PushButton>
</g:FlowPanel>
<g:FlowPanel styleName="{style.floatLeft}">
<g:Label ui:field="lblName" stylePrimaryName="{style.lblName}"/>
</g:FlowPanel>
</g:HTMLPanel>
Note 1: This rule is being applied and works fine
Note 2: This other rules seem to be getting ignored (they don't take effect)
Note 3: The default naming for the widget is being reset, hence Note 1 works fine. The base class is set to GOGXR1SCFI instead of gwt-PushButton
Why aren't they other rules working? When I hover the widget, the class GOGXR1SCFI-up-hovering is indeed set to the widget, but no accompanying CSS.
Thanks for your help.
Update
Something I ran into that gave me a hard time for a while: when you use the #external keyword, you must place a semi-column at the end of the #external statement, as in:
<ui:style>
#external .btnVote;
.btnVote {
...
}
</ui:style>
<g:FlowPanel styleName="{style.btnVote}"/>
One thing you could do is to create your CSS using ClientBundle, define all the different states there, then handle the various states manually. This way you don't need to define classes as #external, and GWT will optimize the CSS for you (shorten the names, only ship what gets used, etc.). This is especially beneficial for custom widgets and such.
The easiest way to deal with this is to write #external .btnVote, .btnVote-up-hovering, .btnVote-down-hovering, .btnVote-up-disabled, .btnVote-down-disabled at the top of your <style> section.
The original GWT widgets do not work well with CSS resources (like the one you have in your UiBinder). They depend on a primary style name that they append things like "up-hovering" to. This is terrible for CSS resources and UiBinders because when you type "up-hovering" it becomes things like SDLFJKS.
The button styles do NOT get obfuscated (so you can read "up-hovering"). Your UiBinder styles DO get obfuscated. You can never make them match as long as obfuscation is going on.
So, the #external keyword tells UiBinder and CssResource not to obfuscate certain styles. Now, when you use {style.btnVote-up-hovering}, that will actually come through to the final HTML, which is where these old-fashioned GWT styles will be applied.
I suspect you have CSS stylenames being obfuscated by GWT in your UIBinder. Reference - garbled css name when styling within UiBinder
Chose the approach you find easier to integrate in your proces. Cheers :)
I'm trying to update a website. There's a label element I want to style. It looks like:
#foo {
font-size: 9px;
}
<label id="foo"></label>
but it looks like a css definition for the "label" element is overriding the more specific style I'm setting. I'm seeing this in firebug
label {
font-size: 16px;
}
.foo {
font-size: 9px; /* strikethrough on my font-size declaration here */
}
so is there a way to override the default label font-size setting without modifying it for everything? (I thought my more specific definition would do that by default)
Thanks
You've mixed up the syntax for id with the one for class:
#foo { /* # = id, . = class */
font-size: 9px;
}
Keep in mind that ids are supposed to be unique for the entire document
or switch your label to using a class instead:
<label class="foo"></label>
You could always use the !important indicator to give precedence to the rule.
font-size: 9px !important;
Is there a way to simplify the following css rule so that .x-grid-row selector won't have to be repeated?
#OpenRequestListGrid .x-grid-row, #MyRequestListGrid .x-grid-row {
line-height: 13px;
padding: 0 1px;
vertical-align: top;
background-color: #BBB;
}
Important issue here is that I don't want to specify .x-grid-row by itself as this rule is from a larger library.
Note: maybe I wasn't clear the first time but I don't want to use .x-grid-row as this will effect other grids that I want to leave alone. I would like to target just my two grids. What I am aiming for is not repeating the same config twice one for each grid ID.
HTML sample :
<div id="dontChangeMe" class="x-grid-row">
<div id="OpenRequestListGrid" class="x-grid-row">
<div id="MyRequestListGrid" class="x-grid-row">
CSS doesn't have variables, but when you want to select all elements .x-grid-row in your document, you should simplify it to:
.x-grid-row {
line-height: 13px;
padding: 0 1px;
vertical-align: top;
background-color: #BBB;
}
Or just search for a common parent of your .x-grid-row when talking about a partial scope and use it like:
#common-parent .x-grid-row {
...
}
or
.common-parent .x-grid-row {
...
}
or any other css selectors ;)
EDIT
I just reread your question and you could also use a global selector like .x-grid-row {...} when you want to address a lot of elements and just specify more selectors like #inner-box .x-grid-row { ... } to change values back to default for only few elements.
How about just using .x-grid-row or using a selector which is a parent to both #OpenRequestListGrid and #OpenRequestListGrid.
So the Answer is there really isn't another way. Repeating element id and then the same selector is necessary. Thanks to all those who replied.
I've been educating myself. Reading this:
The engine evaluates each rule from right to left, starting from the rightmost selector (called the "key") and moving through each selector until it finds a match or discards the rule. (The "selector" is the document element to which the rule should apply.)
For example:
ul li a {...}
#footer h3 {...}
* html #atticPromo ul li a {...]
Now, some example code SASS outputs for me:
#content #blog {
/* ... */
}
/* line 85, ../sass/screen.scss */
#content #flickr {
/* ... */
}
#content #flickr div p {
/* ... */
}
This seems a bit awkward.. am I doing something wrong? Is this a communication problem between me and Sass? Are we losing it?
Edit:
Some SCSS code:
#flickr {
#include columns(5,8);
background: url('../img/ipadbg.png') no-repeat;
#ipod-gloss {
z-index: 999;
position: relative;
}
div {
margin-top: -80px;
margin-right: 20px;
h2 {
color: $white;
font-size: 24px;
}
p {
margin-top: 40px;
}
}
}
Side Bonus!: The article says browsers (or at least Firefox) search the selectors from right to left. I couldn't understand why this is a more efficient why. Any clues?
You have to find your compromise between maintainability (nesting makes it easier to find your way around in the stylesheet) and rendering performance.
A rule of thumb says you should try to restrict yourself to a three-level nesting and you should avoid to nest IDs if it's not necessary.
However, I think nesting too much is not the biggest issue. As soon as I became aware of the power of mixins, I used them a lot.
For example, this is my often used button mixin:
#mixin small-button($active-color: $active-color, $hover-color: $button-hover-color, $shadow: true)
display: inline-block
padding: 4px 10px
margin:
right: 10px
bottom: 10px
border: none
background-color: $button-color
color: $font-color-inv
+sans-serif-font(9px, 700)
text-align: center
text-transform: uppercase
cursor: pointer
#if $shadow
+light-shadow
&:hover
text-decoration: none
background-color: $hover-color
&:last-child
margin-right: 0
a
color: $font-color-inv
&, &:hover
text-decoration: none
&.disabled
+opacity(0.75)
&:hover
background-color: $button-color
&.active
background-color: $active-color
&.disabled:hover
background-color: $active-color
You see, quite a bit code. Applying such mixins to many elements on your page will result in a big CSS file which takes longer to be interpreted.
In the old fashioned CSS-way you would give each button element e.g. the class .small-button. But this method pollutes your markup with unsemantic classes.
Sass provides a solution though: selector inheritance via the #extend directive.
If you set defaults for your parameter of the mixin, you can also provide a simple class, which uses the mixins with your default:
// Use this mixin via #extend if you are fine with the parameter defaults
.small-button
+small-button
And then you can just inherit from this class in various contexts:
#admin-interface
input[type=submit]
#extend .small-button
The resulting CSS statement aggregates all usages of .small button into one rule with comma-separated selectors:
.small-button, #admin-interface input[type=submit] {
display: inline-block;
...
}
Concluding, a naive usage of Sass can effect your CSS performance. Used wisely, however, it is maintainable thanks to well-structured and DRY code, it leads to proper separation of markup and styling (semantic classes only) and allows for smart and performant CSS code.
SASS is only a language that compiles down to CSS. If you're concerned with SASS' performance in terms of how it runs in the browser, then SASS doesn't enter the equation -- it'll be compiled and served to the browser as regular CSS.
From what I can see of your usage of SASS, there's a couple of things I could suggest:
You don't have to nest everything.
The ability to nest rules inside each-other in SASS is a language feature, but you don't have to do it if it doesn't make sense to do so.
In terms of your general CSS usage:
If the nesting gets too severe/unwieldly, consider using classes where it makes sense.
When it's necessary to use the hierarchy of DOM elements, consider using the [child combinator]: .foo > .bar.
IDs are meant to be unique, thus should always only reference a single element. Most of the time, they can be CSS rules unto themselves -- #content #flickr would become just #flickr, for instance -- and browsers will optimise the lookup for a single ID. The only time you would need something like #id1 #id2 is if #id2 needs to appear in different contexts on different pages.
If your selector contains things like #id div p, that div is either superfluous or serving a specific purpose.
If it's superfluous, change the rule to #id p, which selects any <p> that occurs as a descendant of #id.
If it serves a specific purpose, consider classing the <div> with a class name that describes its purpose -- perhaps <div class="photos-list">. Then your CSS could become .photos-list p, which is far more maintainable and reusable.