CSS rules priority - css

I have this simple CSS:
.cont div {
margin:10px;
border:1px solid;
}
.mark { /* This get ignored? */
margin:30px;
}
With this markup:
<div class="cont">
<div>a</div>
<div class="mark">b</div>
</div>
I except the div.mark having margin:30px; but at least in Chrome this isn't true because the generic rule .cont div seems to have a higher priority.
Consider I don't want to use !important are there any other way to solve this?
http://jsfiddle.net/xNVRm/

Just make your selector more specific by adding the tag name:
div.mark {
margin:30px;
}
Demo: http://jsfiddle.net/xNVRm/1/
You could also use .cont .mark if you want to avoid using the tag name.

In order to avoid to use the important you need to make your css selector more specific. You can use .cont div.mark. It is more specific than div.mark.

The ".cont div" declaration overrides the ".mark" declaration because it's actually more specific. CSS uses a kind of point system to figure out which rules apply. In your case, ".cont div" specifies both a class and an element inside it, whereas ".mark" only specifies a class.
For the exact rules that should be used by all conforming browsers, see this link: http://www.w3.org/TR/CSS21/cascade.html#specificity
In your case you could fix this by using ".cont .mark" in the second declaration.

Specificity is key to how CSS rules are given a pecking order. Try looking at this article from HTML Dog:
http://www.htmldog.com/guides/cssadvanced/specificity/
You could use div.mark instead, which means any div that has the class of mark, do this.

Looking over this again, I see I wasn't understanding what you were trying to do. I think I see now.
You are is saying - ANY div inside of anything with class .cont will have 10px margin. It's more specific then .mark. .mark is 30px - BUT it's a div that is inside of .cont - so it's 10px. It reads right to left - that is a good way to think about it and check specificity.
I have come to think of things with a more object oriented approach. What do you think about this approach?
HTML
<div class="container section01">
<div class="block a">a</div>
<div class="block b">b</div>
</div>
CSS
.container {
width: 100%;
float: left;
border: 1px solid red;
}
.container .block {
/* you can style these site wide */
}
.section01 .block {
border:1px solid black;
padding:10px;
margin-bottom: 1em;
}
.section01 .block:last-of-type {
margin-bottom: 0;
}
.section01 .a {
background-color: red;
}
.section01 .b {
background-color: lightblue;
}
SASS would make this much easier.
a jsFiddle of this example
a CODEPEN of this on a larger scale

Related

Change margin top of div based on if div exists [duplicate]

Is this possible, with CSS ?
Apply this rule if .div1 doesn't exist:
.div2{
property: value;
}
like
<div class="div1">
...
</div>
<div class="div2">
<!-- it exists, so do nothing -->
</div>
and
<div class="div2">
<!-- it doesn't exist, apply the css -->
</div>
Exists, or doesn't exist? Your question confuses me :)
Apply style to .div2 if .div1 exists:
Option 1: .div2 follows directly after .div1
.div1 + .div2 {
property: value;
}
Option 2: .div2 follows .div1 as a sibling:
.div1 ~ .div2 {
property: value;
}
Style .div2 without .div1:
It's a bit of a hack, but you could do the reverse.
Style .div2 normally, and then override the styling with the selectors above.
If .div1 doesn't exist, .div2 gets the normal styling.
.div2 {
background: #fff;
}
.div1 + .div2 {
background: #f00; /* override */
}
/* or */
.div1 ~ .div2 {
background: #f00; /* override */
}
If you know the 'unstyled' styles of the div, you could use a css sibling selector to style it one way if it follows .div1, and the 'plain' way if it doesnt - ie
.div2 {
/* styled however you want */
}
.div1 + .div2 {
/* 'plain' styling */
}
See the fiddle. Try removing div1 to see div2 as it would be styled without div1
Generally speaking, no, you can't do that.
But you may 'hack' it using CSS selectors, I'm referring to to:
+ .something selector
~ .something selector
I'd use the second selector, which is the "general sibling" selector.
Given the HTML you posted you can apply the style to the .div2 class and then reset it using the .div1 ~ .div2 selector.
So something like this:
.div1 {
color: red;
}
.div2 {
color: blue;
}
.div1 ~ .div2 {
color: black;
}
In this way, with the first HTML snippet the div2 will be black and with the second snippet it will be blue.
NO
With CSS alone, the if conditions which check the availability of an element, is not possible. You should use JavaScript, (jQuery is recommended).
Notes: With CSS you can check some conditions of an element, like checking if an element has an attribute (like input[type=text]), or checking if an element is the first element of a list (like p:first-child), etc. But you can't check anything from the element's sibling elements, or ancestors. Also you can't check the negative conditions most of the times.
No, this is not possible. But you can create class "div3" and in your code determine whether DIV1 exists and in that case apply the "div3" class instead of "div2"

Bootstrapc3 : Overriding row left and right margins

Trying to override row class's default left and right margins which are
.row .row {
margin-right: -15px;
margin-left: -15px;
}
Page has multiple rows like
HTML
<div class="row row-padded" id="question1"></div>
<div class="row row-padded" id="question2"></div>
<div class="row row-padded" id="question3"></div>
CSS
.row-padded {
margin-top:15px;
padding-left:25px;
padding-top:10px;
padding-bottom:10px;
}
It works fine if I overide it with id. This works fine for one row
#question1 {
margin-left:0px;
margin-right:0px;
}
but this does not
div[id^='question'] {
margin-left:0px;
margin-right:0px;
}
You need to understand how specificity works. The reason that div[id^='question'] doesn't override .row .row is because it only has one element and one attribute selector (considered the same specificity as a class) while the latter has two class selectors - classes override regular elements in specificity, so it makes sense that two classes combined has more priority than one class and one element. Also remember that an ID overrides both class and element selectors.
If you want the second selector to work, try:
div.row[id^='question'] {
margin-left: 0px;
margin-right: 0px;
}
<style>
.row{
margin-left: 0px;
margin-right: 0px;
}
</style>
Provide these codes in your page so that it will override default properties.
Try to mark the margin properties as important:
div[id^='question'] {
margin-left:0px !important;
margin-right:0px !important;
}

Display first letter only

Lets say this markup:
<div id="socialMedia">
<a class="Twitter">Twitter</a>
</div>
What i want is only to be visible the first letter of the text (in this case, just a T)
(Actually I won't end up using it but I am curious about this; sure can be helpfull later)
So this was my a attempt:
#socialMedia .Twitter{
display:none;
}
#socialMedia .Twitter:first-letter {
display: block !important;
}
I was able to check that it won't achieve it. Question is why? and is there some work-around this?
-EDIT-
We are looking for IE=+7/8 version capable solutions..
Salut
Try something like this:
.Twitter {
font-size: 0;
}
.Twitter:first-letter {
font-size: 12px;
}
<div class="Twitter">Twitter</div>
Maybe this is not the best solution, but it works.
Edit: Disclaimer: this does not work according to comments. Please don't use as-is without checking it fits your needs.
If you check the specification for the :first-letter pseudo-element, you'll notice the following:
The :first-letter pseudo-element must select the first letter of the first line of a block, if it is not preceded by any other content (such as images or inline tables) on its line.
The important word here is "block."
You are trying to use the pseudo-element on an <a/> tag with class of Twitter. By default, anchor tags are inline elements (not block level elements).
For your given markup, one solution to your problem would be to style the anchor this way:
.Twitter {
display:block;
visibility:hidden;
}
.Twitter:first-letter {
visibility:visible;
}​
I'm not sure exactly what you are going for, but that is good enough for experimental purposes. Check out a demo here: http://jsfiddle.net/H7jhF/.
Another way is to use color: transparent
.twitter{
display: block;
color: transparent;
}
.twitter:first-letter{
color: #000;
}
<div id="socialMedia">
<a class="twitter">Twitter</a>
</div>
JSFiddle
However, this won't work for lte IE8.
References:
IE7 IE8 IE9 color:transparent property
color: transparent is not working in Internet Explorer
What you're doing is like hiding a parent element and trying to show one of its children, it won't work because the parent's style overrides it. The parent element also has to be a block level element for it to work. Like a div or p tag, or display: block; on the a tag.
Here's something using color:
HTML
<div id="socialMedia">
<a class="Twitter">Twitter</a>
</div>
CSS
body {
background-color:#FFF;
}
.Twitter{
display: block;
color:#FFF;
}
.Twitter:first-letter {
color:#000;
}
shoot the content off the page and show the letter using dynamic content:
.twitter{
text-indent:-9999px;
display:block;
position:relative;
}
.twitter:before,.twitter::before{
content:"T";
position:absolute;
width:10px;
height:15px;
z-index:100;
text-indent:9999px;
}
at play in this fiddle:
http://jsfiddle.net/jalbertbowdenii/H7jhF/67/
Why not just use JavaScript and split the string into an array and use the first item in the array. Or charAt()
The pure-CSS answers use visibility and color tricks to hide the remaining letters, but they are still present and affecting layout. It could cause layout issues, e.g. if you wish to float the element and put something beside it.
I found a funny way to do this without hidden elements. The trick is to shrink the entire word down to almost nothing and then blow up just the first letter. It's a bit like OP was trying to do, but it works because it's operating on a continuous spectrum rather than display: none which just shuts down anything inside it. (Kind of an analogue > digital situation.)
Demo
HTML:
<div>Ding Dong</div> and other stuff
CSS:
div {
font-size: 0.0000016px;
float: left;
}
div::first-letter {
color: red;
font-size: 10000000em;
}
Result:
Here's what I do:
.Twitter{
display:block;
width:1ch;
overflow:hidden;
white-space: nowrap;
}

Align text at the end and the beginning of a div

Currently I'm having a solution, but I'm almost certain that there's a better solution out there. Basically I'm having a block-element and want to align some of the text at the beginning of my block and some at the end.
Here's a little jsfiddle example
What I'm doing is using float and 2 more block-elements inside to align it:
<div id="block">
<div id="start">1</div>
-
<div id="end">12</div>
</div>
#block {
text-align:center;
background: #000;
color: white;
width:150px;
}
#start {
float:left;
}
#end {
float:right;
}
I have many of those little objects, so my code is bloated with div's. Is there no more lightweight solution for this out there ?
I fiddled a possible answer based on the answer to this question.
http://jsfiddle.net/ScHdJ/2/
Works in all browsers, as far as I can see...
May be you can use CSS :after & :before pseudo classes like this:
HTML:
<div id="block">
hello
**</div>
CSS:**
#block {
text-align:center;
background: #000;
color: white;
width:150px;
overflow:hidden;
}
#block:before{
content:"1";
float:left;
}
#block:after{
content:"12";
float:right;
}
http://jsfiddle.net/ScHdJ/3/
But is not work in IE7 & below.

How to make an element inherit a set of CSS rules for another element?

Say I have a <div> like this that is going to have all of the same properties with a background image or something like that:
div.someBaseDiv {
margin-top: 3px;
margin-left: auto;
margin-right: auto;
margin-bottom: 0px;
}
And I wanted to inherit from it like this:
div.someBaseDiv someInheritedDiv {
background-image: url("images/worldsource/customBackground.gif");
background-repeat: no-repeat;
width: 950px;
height: 572px;
}
Of course I’m pretty sure this is written wrong, and I’m not afraid to ask for help, so can someone tell me how to make this work and include the HTML markup?
The easiest is to add your someInheritedDiv element to the first rule like this.
div.someBaseDiv,
#someInheritedDiv
{
margin-top:3px;
margin-left:auto;
margin-right:auto;
margin-bottom:0px;
}
This will tell your #someInheritedDiv to apply the same styles as div.someBaseDiv has. Then you extend this set of styles with more specific to your #someInheritedDiv:
#someInheritedDiv
{
background-image:url("images/worldsource/customBackground.gif");
background-repeat:no-repeat;
width:950px;
height:572px;
}
This is how specificity in CSS works.
Use both classes and combine them like so:
.baseClass
{
margin-top:3px;
margin-left:auto;
margin-right:auto;
margin-bottom:0px;
}
.baseClass.otherClass /* this means the element has both baseClass and otherClass */
{
background-image:url("images/worldsource/customBackground.gif");
background-repeat:no-repeat;
width:950px;
height:572px;
}
The markup is as follows:
<div class="baseClass otherClass"></div>
Now, in this fashion you can override baseClass if necessary... and since you don't have to keep adding your new class names to the baseClass definition, it's a bit cleaner.
For this task, I would recommend you use a powerful extension of CSS called LESS. It compiles into CSS or can be used on-the-fly with a javascript file as the link explains.
LESS supports inheritance (almost) as you describe. The documentation has the details (see the section "Mixins").
For your example, the LESS code would be:
.someBaseDiv {
margin-top:3px;
margin-left:auto;
margin-right:auto;
margin-bottom:0px;
}
someInheritedDiv {
.someBaseDiv;
background-image:url("images/worldsource/customBackground.gif");
background-repeat:no-repeat;
width:950px;
height:572px;
}
Note that it would have to be .someBaseDiv and not div.someBaseDiv
What you want to do is make some CSS apply to two different types of elements, but allow them to have some differences as well. You can do this using some simple HTML:
<div class="base">
<div class"inherited">
</div>
</div>
And CSS:
.base, .inherited{
margin-top:3px;
margin-left:auto;
margin-right:auto;
margin-bottom:0px;
}
.inherited{
background-image:url("images/worldsource/customBackground.gif");
background-repeat:no-repeat;
width:950px;
height:572px;
}
This will add the shared properties to both types of div, but specific ones only to derived divs
That really depends on your markup. If your inherited element resides under a div with class someBasDiv, then all child elements of it will automatically inherit those properties.
If however, you want to inherit the someBaseDiv class in any place in your markup, you could just make the element which you want to inherit with, use both of those classes like this:
<div class="someBaseDiv someInheritedDiv">
and your css would be like this:
div.someBaseDiv
{
margin-top:3px;
margin-left:auto;
margin-right:auto;
margin-bottom:0px;
}
div.someInheritedDiv
{
background-image:url("images/worldsource/customBackground.gif");
background-repeat:no-repeat;
width:950px;
height:572px;
}
If you want all the inner DIVs with a specific class to inherit from the base class build the HTML markup like this:
<div class="parent">
<div class="child">X</div>
</div>
And the CSS
.parent { border: 2px solid red; color: white }
.parent .child { background: black }
If all DIVs must inherit change .child to div.
See this example on jsFiddle
The following code
// parent // all DIVs inside the parent
.someClass div { }
Means: A top element (any) with the class someClass will add the styles to all its children DIVs (recursively).

Resources