Are there any specific rules for things such as input[type="submit"]? I'm having trouble with the CSS properties being loaded in a seemingly incorrect order.
On line 400 of my CSS style sheet I have the following:
input[type="submit"] {
margin: 5px;
}
This is the standard setting for Submit buttons. However, I have a particular submit button that I'd like to style differently, which is on line 800 of my CSS style sheet and so I would have thought it would overwrite the previous style:
.inputSubmit {
margin: 0;
margin-left: 5px;
font-size: 13px;
line-height: 18px;
vertical-align: middle;
color: #555555;
border: 1px solid #cccccc;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
My HTML is as follows:
<div style="position: absolute; bottom: 0; right: 0;">
<form method="get" name="search">
<input type="text" name="searchBox" class='inputText'>
<input type="submit" value="search" class='inputSubmit'>
</form>
</div>
When the page loads, the Submit button loads all of the styles for inputSubmit except the margin settings, which when I inspect the element in Chrome I can see as being crossed out in favour of the earlier style. This has thrown my understanding of CSS out of the window, because I thought it worked in order - and always has in every situation in the past.
For example, I can set h6 {margin: 5px;} and .h6Test {margin: 0px; } in that order, and all browsers still recognise the "class" was assigned afterwards and overwrite the default margin for any <h6 class="h6Test"> tags.
I can force the styles to take effect applying input[type="submit"].inputSubmit, so I have achieved the result I need, but I don't understand why I've had to do that. This is what makes me think this is a "Special" type of property that for some reason operates outside of the boundaries of normal CSS.
Can anyone shed any light on it please?
The reason is that the selector input[type="submit"] has higher specificity than the selector .inputSubmit. The rule with more specific selector “wins”. This has nothing to do with loading order.
By the cascade rules (a key part of CSS, Cascading Style Sheets, yet misunderstood by most people), input[type="submit"] has specificity 0,0,1,1 (one attribute selector, one element selector), whereas .inputSubmit has specificity 0,0,1,0 (just one class selector, counted as an attribute selector). Using input[type="submit"].inputSubmit you get specificity 0,0,2,1, which is fine. Actually, [type="submit"].inputSubmit would suffice (specificity 0,0,2,0).
ID selectors have a higher specificity than attribute selectors.
For example, in HTML, the selector #p123 is more specific than [id=p123] in terms of the cascade.
A:
a#a-02 { background-image : url(n.gif); }
and
B:
a[id="a-02"] { background-image : url(n.png); }
the first rule (A) is more specific than the second one (B). W3C CSS 2.1 Specification
Related
I'm having trouble understanding the behavior of the CSS :after property. According to the spec (here and here):
As their names indicate, the :before and :after pseudo-elements specify the location of content before and after an element's document tree content.
This doesn't seem to place restrictions on which elements can have a :after (or :before) property. However, it seems to only work with specific elements... <p> works, <img> doesn't, <input> doesn't, <table> does. I'm could test more, but the point is made. Note that this seems pretty consistent across browsers. What determines whether an object can accept a :before and :after property?
img and input are both replaced elements.
A replaced element is any element whose appearance and dimensions are
defined by an external resource. Examples include images (<img> tags),
plugins (<object> tags), and form elements (<button>, <textarea>,
<input>, and <select> tags). All other elements types can be referred
to as non-replaced elements.
:before and :after only work with non-replaced elements.
From the spec:
Note. This specification does not fully define the interaction of
:before and :after with replaced elements (such as IMG in HTML). This
will be defined in more detail in a future specification.
With span:before, span:after, the DOM looks like this:
<span><before></before>Content of span<after></after></span>
Evidently, that won't work with <img src="" />.
:before and :after are not required to work for replaced elements, and CSS specifications do not specify how they would work for them, and the concept of replaced element is somewhat vague.
The CSS 2.1 specification clearly suggests that they can work for replaced elements, just saying that it does not “fully define” how. This relates to the issue that a replaced element is expected to have its own visual rendering, which is not controlled by CSS, whereas the pseudo-elements should add something to the content of the element. The spec adds that this will be defined “in more detail” in a future specification, but this has not taken place so far.
Browser vendors just decided to avoid problems by not implementing these pseudo-elements for some elements at all.
It is not clear at all what “replaced element” means, and the meaning appears to have changed somewhat. It is often interpreted as meaning the same as empty element (an element with EMPTY declared content, i.e. an element that cannot have any content), but CSS 2.1 itself shows a sample style sheet with the selector br:before (though browsers have ignored this, implementing br their own way). It can be argued that more and more elements have moved into the scope of CSS rendering, at least in part. For example, an input element (incuding its font, colors, etc.) is largely controllable with CSS in modern browsers.
Current browsers (Firefox, IE, Chrome) do not seem to support the :after and :before pseudo-elements for empty elements other than hr. For hr, IE and Chrome place the generated content inside a bordered box, which is the implementation of hr; the content makes the box taller. Firefox places the content of both (!) pseudo-elements after the horizontal rule that is its implementation of hr. This variation illustrates the kinds of “interaction” problems that are referred to in CSS 2.1.
It is often claimed that these pseudo-elements cannot be used for empty elements since their HTML definitions do not allow any content. This is a category error. The syntax rules of a markup language do not restrict what you can do in CSS
To conclude, :after and :before are currently not usable for empty elements (except marginally for hr), but this is mainly due to implementations and may change in the future.
I've spent several hours plucking out my hair only to find that some other css override content (or display:none) property of my selector.
For example, if the following code is written in some other place, before or after element will never show:
#id > child:before {
content: none!important;
}
<html>
<div id="id" class="class">
<child>
Before element is not showing
</child>
</div>
<style>
child:before {
content: 'before';
color: 'red';
}
</style>
</html>
Just find the css which is overwriting your style and spam stronger selectors and !important to make it work
#id>child:before {
content: none!important;
}
<html>
<div id="id" class="class">
<child>
Before element is <strong>showing</strong>
</child>
</div>
<style>
#id.class>child:before {
content: 'before'!important;
border: 1px solid red;
}
</style>
</html>
<img> is a replaced element and using :before or :after pseudo-elements on it works if the image fails to load and otherwise it does not work. If you intend to have a fallback in case of image load failure, the following css useful:
img{
position: relative;
}
img:after{
position: absolute;
content: "Any allowed type of content including a fallback image";
left: 0;
}
For a good example, please refer to https://css-tricks.com/7-practical-uses-for-the-before-and-after-pseudo-elements-in-css/
Elements that doesn't have closing tag are void elements and they can't display content inside them:
https://www.w3.org/TR/html5/syntax.html#void-elements
All Blink, Webkit and Quantum browsers allow you to create pseudo elements only on checkboxes but this is controversial since no spec allow this behavior.
Here an example:
https://codepen.io/equinusocio/pen/BOBaEM/
input[type="checkbox"] {
appearance: none;
color: #000;
width: 42px;
height: 24px;
border: 1px solid currentColor;
border-radius: 100px;
cursor: pointer;
transition: all 100ms;
background-size: 30%;
outline: none;
position: relative;
box-sizing: border-box;
background-color: #eee;
transition: background-color 200ms;
&::before {
content: '';
position: absolute;
left: 2px;
top: 2px;
bottom: 2px;
height: 18px;
width: 18px;
border-radius: 50%;
background-color: currentColor;
will-change: transform;
transition: transform 200ms cubic-bezier(.01,.65,.23,1);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
&:checked {
background-color: aquamarine;
&::before {
transform: translateX(100%);
}
}
}
Consider the following CSS stylesheet:
#start_experiment_button
{
display: inline-block;
color: black;
border: 3px outset gray;
background-color: #CCCCCC;
padding: 8px;
text-decoration: none;
font-family: Arial, Helvetica;
font-weight: bold;
}
#start_experiment_button:hover
{
border: 3px inset gray;
}
#start_experiment_button:active
{
border: 3px inset gray;
}
#start_experiment_button
{
display: none;
}
Notice that the display property of #start_experiment_button is defined twice. Does this serve a purpose? Does the second definition simply over-ride the first, such that the first need not have been written at all? Or do the intervening definitions for hover and active somehow influence when the two display values take effect?
The last rule
#start_experiment_button {
display: none;
}
overrides the first one. Hence the element is not shown at all. Because the element is invisible both :hover and :active are not applied.
Note that as more specific the selector as higher priority the rule has. So if the element was visible the rules defined by the selectors #start_experiment_button:hover and #start_experiment_button:active would have higher priority then the rule defined by #start_experiment_button.
Does the second definition simply over-ride the first, such that the first need not have been written at all?
Yes, and only for the display property. The other properties are unaffected.
Or do the intervening definitions for hover and active somehow influence when the two display values take effect?
No, they don't, because neither of those rules have their own display declarations, and even if they did, those states would be impossible to reach because the element is never rendered.
It's not clear why that last rule exists and why it appears in that spot unguarded by either a media query or a more qualified selector, because with its display: none declaration, it makes all the other three rules redundant by preventing the element from ever being rendered.
Yes it will override..
#start_experiment_button
{
display: none;
}
This code will override your first code, as the code reads from first line to the last while its executed.. hope you got your answer..
I have the following ASP.Net code
...
<div style="width: 40%; float: left; margin-left: 15px">
<b>County:</b>
<asp:ComboBox ID="cboCounty" runat="server" MaxLength="0"
AutoCompleteMode="SuggestAppend" CssClass="EPSCombo">
</asp:ComboBox>
<br />
...
The problem: This div contains many combobox's and they are not showing as expected, they all have EPSCombo class. and when I debug the CSS I find that it is being overridden, here is the output from FireBug
My EPSCombo style is as follows (overriding the default AjaxToolkit CSS)
.EPSCombo .ajax__combobox_inputcontainer .ajax__combobox_textboxcontainer input
{
margin: 0;
border: solid 1px #7F9DB9;
border-right: 0px none;
padding: 1px 0px 0px 5px;
font-size: 13px;
height: 18px;
}
.EPSCombo .ajax__combobox_inputcontainer .ajax__combobox_buttoncontainer button
{
margin: 0;
padding: 0;
background-image: url(../images/windows-arrow.gif);
background-position: top left;
border: 0px none;
height: 21px;
width: 21px;
}
.EPSCombo .ajax__combobox_itemlist
{
border-color: #7F9DB9;
}
And the CSS file containing EPSCombo is the last one included in the Master page.
Question: It might had been a while since I did web development, but if I decide the CSS class for a control shouldnt that have the highest priority and should override everything else, correct? If so, then why is my combobox style (Height, Width, margin, and padding) is being overridden?? I dont have any other style class that set the height and width for those values shown in Firebug.
Update after Loki's answer I thought I should add this, adding !important to these attributes would solve the problem, but I want to get to the root cause of this and see where things went wrong.
Your ComboBox may be inheriting it's styling from the <div> it is contained in, or from a div higher than that. Since you have not specified a 'class' or 'ID' attribute for the div that it is contained within, that div may be retrieving style from your CSS file if you have something like:
div
{
height: 21px;
margin: 0px;
padding: 0px;
width: 21px;
}
To force your ComboBox to take independent styling though you may use the asp style attribute like so:
<asp:ComboBox ID="cboCounty" runat="server" MaxLength="0"
AutoCompleteMode="SuggestAppend" style="margin: 0;padding: 0;height: 21px;width: 21px;">
</asp:ComboBox>
That should be the highest priority over any other styling that may be interfering in your application. Although considered improper programming practice it may help you narrow down the issue.
Cheers, Eric
EDIT I should also mention that your CSS code is interpreted in order from the most specific to least specific tag definitions. Ex, div.menu is more specific than div, this may be occurring somewhere else in your style-sheet.
This is also a good article to look at describing inheritance. Hope this helps!
A quick fix - add !important flags to your stylesheet. They'll have higher priority over everything else, unless there are other flags defining the very same property of the very same element
I'm having trouble understanding the behavior of the CSS :after property. According to the spec (here and here):
As their names indicate, the :before and :after pseudo-elements specify the location of content before and after an element's document tree content.
This doesn't seem to place restrictions on which elements can have a :after (or :before) property. However, it seems to only work with specific elements... <p> works, <img> doesn't, <input> doesn't, <table> does. I'm could test more, but the point is made. Note that this seems pretty consistent across browsers. What determines whether an object can accept a :before and :after property?
img and input are both replaced elements.
A replaced element is any element whose appearance and dimensions are
defined by an external resource. Examples include images (<img> tags),
plugins (<object> tags), and form elements (<button>, <textarea>,
<input>, and <select> tags). All other elements types can be referred
to as non-replaced elements.
:before and :after only work with non-replaced elements.
From the spec:
Note. This specification does not fully define the interaction of
:before and :after with replaced elements (such as IMG in HTML). This
will be defined in more detail in a future specification.
With span:before, span:after, the DOM looks like this:
<span><before></before>Content of span<after></after></span>
Evidently, that won't work with <img src="" />.
:before and :after are not required to work for replaced elements, and CSS specifications do not specify how they would work for them, and the concept of replaced element is somewhat vague.
The CSS 2.1 specification clearly suggests that they can work for replaced elements, just saying that it does not “fully define” how. This relates to the issue that a replaced element is expected to have its own visual rendering, which is not controlled by CSS, whereas the pseudo-elements should add something to the content of the element. The spec adds that this will be defined “in more detail” in a future specification, but this has not taken place so far.
Browser vendors just decided to avoid problems by not implementing these pseudo-elements for some elements at all.
It is not clear at all what “replaced element” means, and the meaning appears to have changed somewhat. It is often interpreted as meaning the same as empty element (an element with EMPTY declared content, i.e. an element that cannot have any content), but CSS 2.1 itself shows a sample style sheet with the selector br:before (though browsers have ignored this, implementing br their own way). It can be argued that more and more elements have moved into the scope of CSS rendering, at least in part. For example, an input element (incuding its font, colors, etc.) is largely controllable with CSS in modern browsers.
Current browsers (Firefox, IE, Chrome) do not seem to support the :after and :before pseudo-elements for empty elements other than hr. For hr, IE and Chrome place the generated content inside a bordered box, which is the implementation of hr; the content makes the box taller. Firefox places the content of both (!) pseudo-elements after the horizontal rule that is its implementation of hr. This variation illustrates the kinds of “interaction” problems that are referred to in CSS 2.1.
It is often claimed that these pseudo-elements cannot be used for empty elements since their HTML definitions do not allow any content. This is a category error. The syntax rules of a markup language do not restrict what you can do in CSS
To conclude, :after and :before are currently not usable for empty elements (except marginally for hr), but this is mainly due to implementations and may change in the future.
I've spent several hours plucking out my hair only to find that some other css override content (or display:none) property of my selector.
For example, if the following code is written in some other place, before or after element will never show:
#id > child:before {
content: none!important;
}
<html>
<div id="id" class="class">
<child>
Before element is not showing
</child>
</div>
<style>
child:before {
content: 'before';
color: 'red';
}
</style>
</html>
Just find the css which is overwriting your style and spam stronger selectors and !important to make it work
#id>child:before {
content: none!important;
}
<html>
<div id="id" class="class">
<child>
Before element is <strong>showing</strong>
</child>
</div>
<style>
#id.class>child:before {
content: 'before'!important;
border: 1px solid red;
}
</style>
</html>
<img> is a replaced element and using :before or :after pseudo-elements on it works if the image fails to load and otherwise it does not work. If you intend to have a fallback in case of image load failure, the following css useful:
img{
position: relative;
}
img:after{
position: absolute;
content: "Any allowed type of content including a fallback image";
left: 0;
}
For a good example, please refer to https://css-tricks.com/7-practical-uses-for-the-before-and-after-pseudo-elements-in-css/
Elements that doesn't have closing tag are void elements and they can't display content inside them:
https://www.w3.org/TR/html5/syntax.html#void-elements
All Blink, Webkit and Quantum browsers allow you to create pseudo elements only on checkboxes but this is controversial since no spec allow this behavior.
Here an example:
https://codepen.io/equinusocio/pen/BOBaEM/
input[type="checkbox"] {
appearance: none;
color: #000;
width: 42px;
height: 24px;
border: 1px solid currentColor;
border-radius: 100px;
cursor: pointer;
transition: all 100ms;
background-size: 30%;
outline: none;
position: relative;
box-sizing: border-box;
background-color: #eee;
transition: background-color 200ms;
&::before {
content: '';
position: absolute;
left: 2px;
top: 2px;
bottom: 2px;
height: 18px;
width: 18px;
border-radius: 50%;
background-color: currentColor;
will-change: transform;
transition: transform 200ms cubic-bezier(.01,.65,.23,1);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
&:checked {
background-color: aquamarine;
&::before {
transform: translateX(100%);
}
}
}
Ok, a really quick question - which is the best way out of these to apply css styles:
1 - Use lots of different classes that apply different parts of the style i.e. class='font-1 red-bkg border-1' etc etc.
Or
2 - Style up individual parts of the site seperately
What you should do for font for example is to apple it to body, same for background colour, font colour etc...
body{font: Verdana 38px; color: #000; background: #fff;}
Then for individual features (e.g. margins, padding, borders etc) they should be defined in a per-class way.
.classname {
margin: 0px 5px 10px 5px;
padding: 10px 5px 10px 6px;
}
It is better for maintainability and makes your HTML less messy.
I believe to justify shared classes you should have more than one property in it, otherwise you are not gaining anything from using CSS's modularity.
I.e. things like this are not good ideas:
.bold { font-weight: bold; }
Style up individual parts of the site seperately. The other solution would kind of screw the intention behind it - separating content from styling.
Seems like you will enjoy this read, I certainly did:
http://net.tutsplus.com/tutorials/html-css-techniques/30-css-best-practices-for-beginners/
You should name logically classes, because when you change your layout and currently you have style like
.bold .5px-brd .red.bg
then changing this to another colour and style will include grep'ing through entire application code in order to correct css styles.
As you may notice approach like
.bold .5px-brd .red.bg
it's good, and don't go with philosophy of CSS.
Classes with name like
.bold
should be used as auxiliary style. Never as basic construction block.
http://jsfiddle.net/sheriffderek/RMfEn/
html
<section class='container blocks'>
<h2>Blocks of content</h2>
<div class='block highlight-theme'>
<p>None of the styling should be done in the html.</p>
</div>
<div class='block base-theme'>
<p>You can use modular classes to style common pieces of the layout and then modify them with more specific classes.</p>
</div>
<div class='block contrast-theme'>
<p>So the stuff in this box could be a dark-theme with .contrast-theme or something</p>
</div>
</section>
css
.container, .block { /* structural elements */
width: 100%;
float; left;
padding: .5rem;
overflow: hidden; /* use a clear-fix instead */
}
/* mini themes /// mix and match */
.base-theme {
background: lightgray;
color: black;
}
.highlight-theme {
background: yellow;
color: red;
}
.contrast-theme {
background: gray;
color: white;
}