Hi please see the following two html codes:
<div class="price">
2
</div>
And:
<div class="price">
<div class="symbol">£</div> 2
</div>
So in the first one I want to add £ to the price so I am using this CSS
.price::before {
content: "£";
}
And it is working . But I don't want this if .symbol class is already present in .price class. Is there is any way to do this in CSS?
If you are applying £ symbol as default and .symbol for the different symbols as #BoltClock mentioned in the comments
You can use pseudo classes with position:absolute combination...
You have to apply position:absolute to both pseudo element and symbol class at the same position. If there is no symbol class, the pseudo element :before will be visible and if symbol class is there, it will be visible above pseudo element :before
Here the tricky part is the setting background-color:white of the .symbol class
Stack Snippet
.price::before {
content: "£";
position: absolute;
left: 0;
}
.price {
display: inline-block;
position: relative;
padding-left: 20px;
}
.symbol {
position: absolute;
left: 0;
background: #fff;
}
<div class="price">2</div>
<br>
<div class="price">
<div class="symbol">$</div> 4
</div>
You can achieve this in pure CSS:
.price::before {
content: "£";
}
/* Do not show the symbol if contained into a price element */
.price > .symbol {
display:none;
}
Why
So, CSS selectors work in a way for which a selector can only query an element's parents or siblings. It is not possible to create a selector which act by querying the children of an element. You have to reverse the order. That is why, you work on the .symbol class and show it or hide it.
You can check this class via jquery it is good aproch.
if( $('.price').hasClass('symbol') ) {
// ...
}
You can not achieve this using CSS only. You need a bit of jquery here.
What my jQuery code is doing is it is adding class .symbol-present to .price which has .symbol element and my CSS code is then adding symbol accordingly.
$(".price").addClass(function(){
return $(this).find(".symbol-present").length > 0 ? "symbol":"";
})
.price:not(.symbol-present)::before {
content: "£";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="price">
2
</div>
<div class="price">
<div class="symbol">£</div> 2
</div>
Related
Here is my code.
<div class="start">start</div>
<div>middle-1</div>
<div>middle-2</div>
<div>middle-3</div>
...................
...................
<div>middle-n</div>
<div class="end">end</div>
I want to apply css to all div's when mouse hover the first div with class start.
With the current HTML structure you can use couple of sibling selectors for this.
.start:hover ~ div {
color: red; /* styles you want to apply */
}
/* reset styles back for all other divs after .end */
.start:hover ~ .end ~ div {
color: inherit;
}
Demo: http://jsfiddle.net/3c6V6/1/
However I would recommend to change HTML structure if you can. For example:
<div class="start">start</div>
<div class="middles">
<div>middle-1</div>
<div>middle-2</div>
<div>middle-3</div>
<div>middle-n</div>
<div class="end">end</div>
</div>
<div>after-1</div>
<div>after-2</div>
and CSS:
.start:hover + .middles > div {
color: red;
}
You would just have much more flexibility.
Demo: http://jsfiddle.net/3c6V6/2/
Could it be as simple as putting a parent container around it, and putting the hover on that, or do you wish to single out some of the siblings directly?
In this case, try putting :hover on the parent container like this:
.parent:hover div {/*style*/}
This is for your second version found in the comments: JSFiddle DEMO
div.start:hover~div.middles div:not(.end) {
font-weight: bold;
}
(This is for your original question):
div.start:hover~div:not(.end) {
font-weight: bold;
}
JSFiddle DEMO
This is where I found the information to do it. Didn't know there were so many CSS selectors.
I have a scenario like the below to show a spacer(line) before and after icons(Cross symbols) and not to show spacer(line) before and after buttons(with Cancel text). How can I achieve this...
My Css file is
.Container > *:first-child::before,
.Container > *::after
{
display: inline-block;
content: url('../Content/Images/Line.png');
}
All my icons, buttons(with Cancel text) are inside container div
Can we restrict showing lines before and after buttons(with Cancel text)?
I tried the below code which did not work.
.Container > *:not(input[type="button"]):first-child::before,
.Container > *:not(input[type="button"])::after
{
display: inline-block;
content: url('../Content/Images/Line.png');
}
Edit:
Assuming demo markup like this:
<div class="container">
<span>x</span>
<span>x</span>
<span>x</span>
<input type="button" value="Cancel" />
<input type="button" value="Cancel" />
<span>x</span>
<span>x</span>
<span>x</span>
</div>
.. you could use the following CSS to acheive what you need:
CSS
.container > *:not([type="button"]):first-child::before,
.container > *:not([type="button"])::after
{
/*content: url('../Content/Images/Line.png');*/
content: ''; /* if line image is used, this is not necessary */
background: #555; /* if line image is used, this is not necessary */
display: inline-block;
width: 1px;
height: 100%;
vertical-align: middle;
margin: 0 8px;
}
FIDDLE
Side note: Instead of using the * selector - you could target the specific child elements, or -even better - add a class name to the child elements
So why didn't your original css - as posted in the question - work?
The :not() pseudo class can only accept a simple selector.
From the spec:
A simple selector is either a type selector, universal selector,
attribute selector, class selector, ID selector, or pseudo-class.
So although the not pseudo class can accept an attribute selector like: :not([type="button"]), in your code you have combined it with an element selector - ie. input ---- :not(input[type="button"]) - which is why the code doesn't work.
So this will work:
.Container > *:not([type="button"])::after
{
display: inline-block;
content: url('../Content/Images/Line.png');
}
..but this won't:
.Container > *:not(input[type="button"])::after
{
display: inline-block;
content: url('../Content/Images/Line.png');
}
Here is a demo to illustrate this.
If you only want the line before and after the icons, instead of using wildcard * and then trying to deselect buttons, simply target the icons alone. Assuming the icons has class .class
.Container > .icon:first-child::before,
.Container > .icon::after
{
display: inline-block;
content: url('../Content/Images/Line.png');
}
or if the icons are <img>, corresponding css would be
.Container > img:first-child::before,
.Container > img::after
{
display: inline-block;
content: url('../Content/Images/Line.png');
}
problem solved (can't be more specific since you haven't provided much information).
I think the key to solving your problem is using an adjacent sibling selector. You can select elements by their preceding sibling as follows:
.sibling#one + .sibling#two {
/* style every .sibling#two that is preceded by a .sibling#one */
}
I've made a quick example here, using borders instead of the images with lines and div's as buttons. I hope this will help, good luck!
in the code:
<!DOCTYPE html>
<html>
<head>
<style>
.parent {
position: absolute;
top:500px;
width:400px;
border:1px solid green;
}
.parent:before {
z-index:-1;
content:'';
position:absolute;
opacity:0.5;
width:400px;
height:200px;
background-image:url('wallpaper324845.jpg');
border:1px solid red;
}
.child {
Color:black;
border:1px solid black;
}
</style>
</head>
<body>
<div class="parent">
<div class="child">Hello I am child</div>
</div>
</body>
</html>
I'm trying to create a transparent background as described in this thread: How to set opacity in parent div and not affect in child div?.
Looking at the code from the 4th answer. How does this work, I'm confused with the use of .parent and .parent:before. I would think that this would create a .parent:before element before every parent element. Really confused how does this work?
:before creates a virtual content using CSS, so in the above case, author uses below snippet means
.parent:before{
z-index:-1;
content:'';
position:absolute;
opacity:0.5;
width:400px;
height:200px;
background-image:url('wallpaper324845.jpg');
border:1px solid red;
}
He is creating a virtual element using :before, which he then positions absolute, assigns some dimensions, and assigns the background, to make sure that it stays below the div content, he uses z-index: -1;
In other words, :before, :after are nothing but assume nesting two span elements inside your div, but by using pseudo elements, you don't need to have span as you can achieve the same thing with the pseudo elements.
Consider you have something like this
<div>
Hello
<span></span>
</div>
div {
position: relative;
}
div span {
position: absolute;
width: 100%;
height: 100%;
background: #f00;
z-index: -1;
left: 0;
top: 0;
}
Demo
Can be also achieved using :before or :after, markup stays the same but CSS goes like
div {
position: relative;
}
div:after {
content: "";
position: absolute;
width: 100%;
height: 100%;
background: #f00;
z-index: -1;
left: 0;
top: 0;
}
Demo
So, it just saves you one empty element in your HTML, but if you look at the above CSS, am using content property which is ALWAYS associated with :before or :after, and yes, it is required, even if you keep it blank.
Also, note that :before and :after generated content are inline, so inorder to make height, width work, you need to explicitly mention display: block; or display: inline-block; if you want to make it block level, but in this particular case, you won't need that as the pseudo element is positioned absolute
div:after {
content: "Hello";
margin-top: 20px; /* This wont work as pseudo is inline by default */
}
Demo
So make it block or inline-block
Demo
Authors specify the style and location of generated content with the :before and :after pseudo-elements. As their names indicate, the :before and :after pseudo-elements specify the location of content before and after an element's document tree content. The 'content' property, in conjunction with these pseudo-elements, specifies what is inserted.
Below is a document tree with HTML as root.
HTML
.HEAD
..TITLE
.BODY
..H1
..P
..UL
...LI
...LI
...LI
For example, the following rule inserts the string "Note: " before the content of every P element whose "class" attribute has the value "note":
p.note:before { content: "Note: " }
The formatting objects (e.g., boxes) generated by an element include generated content. So, for example, changing the above style sheet to:
p.note:before { content: "Note: " }
p.note { border: solid green }
would cause a solid green border to be rendered around the entire paragraph, including the initial string.
The :before and :after pseudo-elements inherit any inheritable properties from the element in the document tree to which they are attached.
For example, the following rules insert an open quote mark before every Q element. The color of the quote mark will be red, but the font will be the same as the font of the rest of the Q element:
q:before {
content: open-quote;
color: red
}
In a :before or :after pseudo-element declaration, non-inherited properties take their initial values.
So, for example, because the initial value of the 'display' property is 'inline', the quote in the previous example is inserted as an inline box (i.e., on the same line as the element's initial text content). The next example explicitly sets the 'display' property to 'block', so that the inserted text becomes a block:
body:after {
content: "The End";
display: block;
margin-top: 2em;
text-align: center;
}
The :before and :after pseudo-elements elements interact with other boxes, such as run-in boxes, as if they were real elements inserted just inside their associated element.
For example, the following document fragment and style sheet:
<h2> Header </h2> h2 { display: run-in; }
<p> Text </p> p:before { display: block; content: 'Some'; }
...would render in exactly the same way as the following document fragment and style sheet:
<h2> Header </h2> h2 { display: run-in; }
<p><span>Some</span> Text </p> span { display: block }
Similarly, the following document fragment and style sheet:
<h2> Header </h2> h2 { display: run-in; }
h2:after { display: block; content: 'Thing'; }
<p> Text </p>
...would render in exactly the same way as the following document fragment and style sheet:
<h2> Header <span>Thing</span></h2> h2 { display: block; }
span { display: block; }
<p> Text </p>
Basically, :before (like :after) is a CSS pseudo-element. So it's almost like a HTML inline element. Almost.
To play with pseudo elements, you need to give it a content property (empty string in most cases). Note that it's an inline element by default, so it can't have width / height. You need to set display: block (or inline-block, or whatever).
I think you missed to set the relative position on the parent element (.parent). There it is :
.parent{
position: relative;
top:500px;
width:400px;
border:1px solid green;
}
Try looking at this article. it explains how :before and :after pseudo selectors work:
http://coding.smashingmagazine.com/2011/07/13/learning-to-use-the-before-and-after-pseudo-elements-in-css/
I want solution using only CSS
we have 3 circle here.
Whenever I perform mouse-over on circles with class Name Mycircle , the circle with class Name BigCircle should change to red color
html
<div class="BigCircle"></div>
<div class="mycircle"></div>
<div class="mycircle"></div>
CSS
.mycircle,.BigCircle{width:50px; height:50px; border-radius:30px; background-color:grey; margin:3px}
.mycircle:hover{background:yellow}
.mycircle:hover .BigCircle{background:red}
Here is the demo >http://jsfiddle.net/JGbDs/4/
Thanks in Advance
In your comments you state that you cannot re-arrange the elements, but you can add ones if required.
For that reason the general sibling combintor in the accepted answer is not suitable as the .bigCircle element would have to come after all of the .myCircle elements.
There is no perfect way of achieving this using only CSS but it is possible by adding a "parent" element and using one of the following CSS solutions:
Solution 1
When hovering on the parent element, the .bigCircle child element will be coloured red:
Working example: http://jsfiddle.net/CKRef/
HTML
<div class="parent">
<div class="bigCircle"></div>
<div class="mycircle"></div>
<div class="mycircle"></div>
</div>
CSS
/* Add float to parent to fit width to content */
.parent {
float: left;
clear: both;
}
.parent:hover > .bigCircle{
background: red;
}
The issue with this solution is that the .bigCircle element will be coloured red when you hover anywhere on the parent, not just on .myCircle. Adding the float reduces this effect - but if you hover just outside of the circle then the .bigCircle will still be red.
Solution 2
Using the parent element as a relative container, we can add a new element to the page using the after pseudo selector when a .myCircle element is hovered over:
Working example http://jsfiddle.net/CKRef/1/
HTML
<div class="parent">
<div class="mycircle"></div>
<div class="mycircle"></div>
<div class="mycircle"></div>
</div>
CSS
/* replaced .bigCircle with mycircle:hover::after */
.mycircle, .mycircle:hover::after {
....
}
.parent {
position: relative;
}
.mycircle:hover::after {
content: "";
background-color: red;
position: absolute;
top: 0;
left: 0;
margin-top: 0;
}
The imperfection with this solution is that we are targeting the position of the first child of the parent element, rather than the element with the class name .bigCircle. Also, the after pseudo selector is not supported in IE7.
No. That's not possible using just css. "Any sibling" selector is not there in css.
However, if you can move BigCircle to end, you can use general sibling combinator which can select successor siblings.
.mycircle:hover ~ .BigCircle{background:red}
I'm trying to set the background color of the first div with the class offer. I thought .offer:first-child would do the trick, but that isn't working.
I've also tried using :nth-child(1), but that's not working either.
Any suggestions is greatly appreciated.
My fiddle: http://jsfiddle.net/MNQar/
CSS
.offer:first-child { background-color: indianred; }
.special-offers .title,
.special-offers .offer,
.special-offers .more {
height: 200px;
}
[class*="column"] {
display: inline;
float: left;
margin: 0;
}
.column2 { width: 190px;}
.column3 { width: 285px;}
HTML
<div class="row row-spacer special-offers">
<div class="column2 title">
<h2>Offers</h2>
</div>
<div class="column3 offer padding">
<div class="date">10. June</div>
<h3>Høyer tømmer lageret!</h3>
</div>
<div class="column3 offer padding">
<div class="date">10. June</div>
<h3>Super salg hos Vivikes</h3>
</div>
<div class="column1 more">
<div class="caret"></div>
More offers
</div>
</div>
.offer:first-child means "An element With the class 'offer' that is the first child beneath its parent", not "the first child with class 'offer'".
I believe you have to re-think how you do this. For example, stick a separate class to the first child or something, then use a selector like .offer.highlight.
CSS Only
This should work:
.offer { background-color: #ccc; }
.offer ~ .offer {background-color: transparent; }
It first sets all .offer elements to have a background color, then uses the sibling selector (~) to undo it for all subsequent .offer elements. Kind of a hack but it should be okay if you're not willing to use javascript. See here for a much more complete explanation: CSS selector for first element with class
And here's a fiddle: http://jsfiddle.net/MNQar/4/
JS
Alternatively, this is really easy to do with Javascript: $(".offer").eq(0).css("background-color","#ccc");
Fiddle: http://jsfiddle.net/MNQar/6/
The problem is that there is a div that precedes the first offer, making it the second element, not the first. The best solution is to give the first offer a different class, offer-first and use that. If that's not possible and the first offer is always the second child, you can use :nth-child(2)
Using :nth-child(2)
http://jsfiddle.net/MNQar/3/