Create pseudo elements, but exclude specific elements (with not:nth-child) - css

I want to set a pseudo element border on some containers, but exclude the third one. I thought I could combine the pseudo selector with :not , like: div:before:not(nth-child(3)), but it doesn't seem to work.
So is the :not selector incompatible with pseudo selectors? In that case, how can I make it work putting pseudo elements and exclude some specific elements?
(By the way, the idea with pseudo element borders is to control the borders so that they stay on top regardless if there are any overlays on top (haven't seen if it works though)
Here is a fiddle: (there are no visible borders because of the not:(nth-child(3)) selector)
Fiddle
Here is the code from the fiddle:
HTML:
<div class="ctr">
<div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
</div>
</div>
CSS:
.ctr > div div{
float:left;
width:100px;
height:100px;
background:black;
/*border:green 3px solid; */
}
.ctr > div:after{
content:"";
display:block;
clear:both;
}
.ctr > div div{
position:relative;
}
/* only if I remove ":not(:nth-child(3))" , the pseudo selector will appear: */
.ctr > div div:before:not(:nth-child(3)){
content: "";
display: block;
z-index: 2;
position: absolute;
left:0;
right:0;
bottom:0;
top:0;
height: 100%;
width: 100%;
border-right: 0.35em red solid;
border-bottom: 0.35em red solid;
}

Are you trying to create a ::before pseudo-element for all but the third child?
If so, the :not() pseudo-class needs to come first, since pseudo-elements can only appear at the very end of a selector (and this is why the made-up term "pseudo-selector" is dangerous to use, because you can't group pseudo-classes and pseudo-elements into a single umbrella term given their syntactic differences):
.ctr > div div:not(:nth-child(3))::before
Since you're using CSS3 pseudo-classes anyway, pseudo-elements should be indicated with double colons to further cement the difference between the two.
See also: How to write :hover condition for a:before and a:after?

I hope this will work for you
.ctr > div div:nth-child(3).before{
/*remove properties you don't need on third element*/
}
or you can even hide the pseudo element like below
.ctr > div div:nth-child(3).before{
display: none;
}

Related

Using css for background block & underline (100%)

I'm trying to do something like this using css:
I need it to:
Only have background (with padding) around the text, and
Have a solid line occupying 100% page width thereafter
For example, I'd like to be able to do the following:
<div style="my-custom-style">T E X T</div>
Would appreciate some input
You can use the :after pseudo element to minimise markup.
The point is to position the pseudo element absolutly and keep the div's position to default static position. This way, setting the pseudo element to width:100%; will make it span the whole width of the divs parent (you will although need to set that parent to an other position than the default static position. In the following demo it is the body element) :
DEMO
CSS :
body{
position:relative;
}
div{
background-color:#FF7F27;
display:inline-block;
}
div:after{
position:absolute;
display:block;
content:'';
width:100%;
height:5px;
background-color:inherit;
}
EDIT:
As stated in comments by #Paulie_D, you should be using a text node to display text like <span> <p> <li> <h1> <h2> ... Using this technique, <span> or a title tag should suit you depending on the content you need to display.
As Stated by #KheemaPandey using a manual space between the letters isn't the best considering HTML semantics , maintainability of your code and the "concept" of CSS styling.
You should be using letters-spacing to space your letters.
Considering both points, your code could look like this :
DEMO
HTML :
<span>TEXT</span>
CSS :
body{
position:relative;
}
span{
background-color:#FF7F27;
display:inline-block;
letter-spacing:0.5em;
}
span:after{
position:absolute;
display:block;
content:'';
width:100%;
height:5px;
background-color:inherit;
}
Try following code
DEMO
<div style="my-custom-style"><span>T E X T</span></div>
div{
border-bottom: 3px solid orange;
}
span{
display: inline-block;
padding: 3px 5px;
background: orange
}

CSS table-cell in Opera with :before and :after do not behave as normal

I want to achieve the following effect in CSS:
I use CSS table-cell with :before and :after pseudo-elements so that they auto-adjust their width in one row. In other words, I want the text container have the width of the text (with some padding) and the pseudo-elements fill the rest of the area. This means that I can't use 1px background-image positioned top, because each word has a different width.
Here's the fiddle.
HTML
<div id="container">
<div id="box">
<h2 id="header">UPDATES</h2>
</div>
</div>
CSS
#container {
background:url("http://lorempixel.com/output/abstract-q-g-640-480-9.jpg") center center no-repeat;
padding-top:50px;
height:400px;
width:50%;
margin:0 auto;
}
#box {
margin:0 auto;
width:50%;
display:table;
}
#header {
color:#fff;
font:14px Arial;
font-weight:500;
line-height:10px;
height:10px;
display:table-cell;
padding:0 10px;
width:auto;
text-align:center;
}
#box:after, #box:before {
content:"";
display:table-cell;
border:1px solid #fff;
border-bottom:0;
height:10px;
width:50%;
}
#box:after{
border-left:0;
}
#box:before{
border-right:0;
}
However, it doesn't work in Opera so, I need to find a different technique to achieve the same effect. I'd prefer to avoid using HTML tables and any js. Can you provide any suggestion?
In this example I got rid of the psuedo-elements and sandwiched the header tag between two that were styled as a table to get the line effect. Although this is done using a CSS table the similar concept should be applicable to an html table.
<div id="before" ></div>
<h2 id="header">UPDATES</h2>
<div id="after"></div>
styled like so....
#before {
content:"";
display:table-cell;
border:1px solid #fff;
border-bottom:0;
border-right:0;
height:10px;
width:50%;
}
#after {
content:"";
display:table-cell;
border:1px solid #fff;
border-bottom:0;
border-left:0;
height:10px;
width:50%;
}
http://jsfiddle.net/SteveRobertson/9SBXn/12/
After several tests, I found out that Opera needs a more detailed implementation when using CSS tables with pseudo-elements. In other words, it's not enough to set the parent container as display:table and children as display:table-cell.
You need to set the whole hierarchy, meaning that:
The parent needs to be set as:
display:table
The first children needs to be set as:
display:table-row
And finally set the other children as:
display:table-cell
If you set your CSS ignoring display:table-row like I did, Opera sets the children elements (after display:table-cell) as table-row and not as table-cell, thus the width of each child extends to 100% of the parent and behaves like a row. Setting the table hierarchy like in HTML tables (table > row > cell) you get the expected format.
This seems to affect only Opera, since all other browsers do not try to fix the hierarchy of the CSS table.
Here's the demo (check in Opera as well)
Instead of CSS tables, you could use inline-blocks with percentage width and max-width so that the containers don't fall in a new line.

CSS Beginner troubles with hover

I'm been learning for web design as well as development for quite some time now but I'm still stumped by some basic rules of CSS.
I'm trying to figure out how the behavior of :hover works when hovering one element, to affect another. But I came across something unexpected...
Q: Why does element .one turn black when .two is hovered?
Here's the code and the fiddle.
HTML:
<div class="one">
<div class="two"></div>
</div>
CSS:
div {
width: 100px;
height: 100px;
position: absolute;
top:0;
}
.one {
left:0;
background: red;
border: 5px solid black;
}
.two {
left:200px;
background: yellow;
}
.one:hover {
background: black;
}
here is my jsFiddle
Help anyone?
The element .two is found inside the .one element. so hovering .two means that you are also hovering .one. The event "bubbles" up to the parent element.. even if it doesn't look like that visually. To hover each one independently you will have to take .two out of .one. You might want to wrap both in a container to properly set their positioning. working jsFiddle
<div class="someContainer">
<div class="one"></div>
<div class="two"></div>
</div>
You have to change your html structure to achieve this.
As right now div having class two is inside the div class one so two is becoming child of class one div so when you hover on div which have class two it automatics consider that you are hovring on class one div as well.
Use absolute div and don't make it child of class one div.

How to set opacity in parent div and not affect in child div? [duplicate]

This question already has answers here:
I do not want to inherit the child opacity from the parent in CSS
(18 answers)
Closed 7 years ago.
Hey i am searching in google but i can't fine any perfect answer
I want to Opacity in parent DIV but not Child DIV
Example
HTML
<div class="parent">
<div class="child">
Hello I am child
</div>
</div>
Css
.parent{
background:url('../images/madu.jpg') no-repeat 0 0;
}
.child{
Color:black;
}
Note: -- I want to background-image in Parent Div not Color
I know this is old, but just in case it will help someone else.
<div style="background-color: rgba(255, 0, 0, 0.5)">child</div>
Where rgba is: red, green, blue, and a is for transparency.
May be it's good if you define your background-image in the :after pseudo class. Write like this:
.parent{
width:300px;
height:300px;
position:relative;
border:1px solid red;
}
.parent:after{
content:'';
background:url('http://www.dummyimage.com/300x300/000/fff&text=parent+image');
width:300px;
height:300px;
position:absolute;
top:0;
left:0;
opacity:0.5;
}
.child{
background:yellow;
position:relative;
z-index:1;
}
Check this fiddle
You can do it with pseudo-elements: (demo on dabblet.com)
your markup:
<div class="parent">
<div class="child"> Hello I am child </div>
</div>
css:
.parent{
position: relative;
}
.parent:before {
z-index: -1;
content: '';
position: absolute;
opacity: 0.2;
width: 400px;
height: 200px;
background: url('http://img42.imageshack.us/img42/1893/96c75664f7e94f9198ad113.png') no-repeat 0 0;
}
.child{
Color:black;
}
As mentioned by Tom, background-color: rgba(229,229,229, 0.85) can do the trick.
Place that on the style of the parent element and child wont be affected.
You can't. Css today simply doesn't allow that.
The logical rendering model is this one :
If the object is a container element, then the effect is as if the contents of the container element were blended against the current background using a mask where the value of each pixel of the mask is .
Reference : css transparency
The solution is to use a different element composition, usually using fixed or computed positions for what is today defined as a child : it may appear logically and visualy for the user as a child but the element doesn't need to be really a child in your code.
A solution using css : fiddle
.parent {
width:500px;
height:200px;
background-image:url('http://canop.org/blog/wp-content/uploads/2011/11/cropped-bandeau-cr%C3%AAte-011.jpg');
opacity: 0.2;
}
.child {
position: fixed;
top:0;
}
Another solution with javascript : fiddle
I had the same problem and I fixed by setting transparent png image as background for the parent tag.
This is the 1px x 1px PNG Image that I have created with 60% Opacity of black background !
You can't do that, unless you take the child out of the parent and place it via positioning.
The only way I know and it actually works, is to use a translucid image (.png with transparency) for the parent's background. The only disavantage is that you can't control the opacity via CSS, other than that it works!

CSS first GENERATION div but not second selector

I want to match the first generation division elements (all of them) but NOT any of THEIR children. So if I used the selector to apply a border 1 (as below visually) would gain the container however 2 (as below visually) would NOT gain the container. How do I construct that selector please?
<div id="container">
<div>1<div>2</div></div>
<div>1<div>2</div></div>
<div>1<div>2</div></div>
</div>
#container > div {
border: 1px solid #f0f;
}
The best way is using the immediate child selector (>):
#container > div {
border: 1px solid red;
}
(IE6 does not support this)
The selector for that is:
div#container > div
or just
#container > div
I really like the SelectORacle to help understand CSS selectors. More on Child Selectors from Eric Meyer.
UPDATE FOR Microsoft Internet Explorer 6
If support for > is a concern, as in the case of MSIE6, the traditional way I used to handle it was to set the styles for the first generation, then unset them for every other descendent generation. So, like this:
#container div { border: 1px solid #000; }
#container div div { border: none; }
#container div div div { border: none; }
#container div div div div { border: none; }
You do that with as many generations down as you need to do. In the above I allow 3 more levels of nesting (enough?) It is not pretty, but it is reliable.
Since one browser in particular (IE6) does not support the child selector >, you could use descendent selectors instead to add a border to the first descendant and remove it from the descendent's descendent.
HTML
<div id="container">
<div>1
<div>2</div>
</div>
<div>1
<div>2</div>
</div>
<div>1
<div>2</div>
</div>
</div>
CSS
#container div {
border:1px dashed grey;
}
#container div div {
border:none;
}
If IE6 is a browser you do need to support then the > selector as already answered is the simplest way to style the child.

Resources