Is there a way to get the pseudo element :after, to obey the width of my container, so it is where the orange ends (after 500px), or will :after always kick in where the content inside the element ends?
Is the margin and/or padding of my element, always going to affect the :before and :after pseudo elements? I thought they have their own margin and padding. At least being able to add a padding to my element shouldn't affect the pseudo elements should it ....
See the following codepen: http://codepen.io/anon/pen/wgaYZg
#container {
width: 500px;
background-color: orange;
display: inline-block;
padding: 50px;
margin: 50px;
}
#container:before {
background-color: grey;
content: "before";
width: 100px;
display: inline-block;
}
#container:after {
background-color: grey;
content: "after";
width: 100px;
display: inline-block;
}
<div id="container">hello world</div>
This is what I'm looking to do:
To understand pseudo element :before and :after, just think them as limited version of <span> tags, since a pseudo element can only contain image or plain text as far as I know. They don't have their own padding or margin by default.
<container><:before>normal content<:after></container>
To achieve your layout, I suggest to use position tricks without introducing any new tags.
#container {
background-color: orange;
position: relative;
width: 500px;
padding: 50px 100px;
box-sizing: border-box;
}
#container:before,
#container:after {
position: absolute;
top: 0;
bottom: 0;
}
#container:before {
background-color: grey;
content: "before";
width: 100px;
left: 0;
}
#container:after {
background-color: grey;
content: "after";
width: 100px;
right: 0;
}
<div id="container">hello world</div>
Otherwise, if you can wrap the plain text into a HTML tag, that would be easy to do with flexbox.
#container {
width: 500px;
background-color: orange;
display: flex;
}
#container span {
padding: 50px;
flex: 1;
}
#container:before {
background-color: grey;
content: "before";
width: 100px;
}
#container:after {
background-color: grey;
content: "after";
width: 100px;
}
<div id="container"><span>hello world</span></div>
Related
I've three child div and wanted that middle div to ignore width of parent div and take full screen width (yet it needs to maintain its position below first div)
You can define the middle child width a width defined in vw:
.parent {
width: 100px;
height: 40px;
background: blue;
}
.child {
width: 100%;
background: yellow;
}
.overflower {
width: 100vw;
background: red;
}
<div class=parent>
<div class=child>child</div>
<div class=overflower>overflows</div>
<div class=child>child</div>
</div>
Solved this issue by using position: absolute tag. See JSfiddle at: https://jsfiddle.net/sachingpta/3qu3m466/. Sample code
`
html,body{
height: 100%;
padding: 0px;
margin: 0px;
}
.parent{
width: 300px;
height: 100%;
background-color: grey;
margin: 0 auto;
}
.child1{
background-color: red;
}
.child2{
background-color: green;
position: absolute;
left: 0px;
right: 0px;
}
.child3{
background-color: blue;
}
`
I have the following markup
<button class="filter"><div class="radio"><div class="circle"></div></div> <span>Account Management</span></button>
and CSS
.filter {
font-size: 3vw;
text-align: left;
line-height: 1.6;
padding: 0px;
display: block;
height:auto;
overflow: hidden;
margin-bottom: 3px;
}
.filter span {
background: $leithyellow;
height: 100%;
overflow:auto;
display: block;
width: calc(100% - 60px);
float: left;
margin-left:10px;
padding-left:20px;
}
I cannot get the span to expand to 100% height of the button. Can this be done?
Heights apply only if the heights are defined properly for the ancestors. If you want the height to work, that's a tricky one. You can use one of my favourites, but you need to make sure it works in all the cases:
Give position: relative; to the parent.
Give position: absolute; to the element that needs full height and width.
Give the element, 0 values for all the sides.
Snippet
.parent {
position: relative;
width: 100px;
height: 50px;
background: red;
}
.parent .child {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: skyblue;
}
<div class="parent">
<span class="child"></span>
</div>
In the above snippet, it is noted that this can also work, if you give:
.parent {
position: relative;
width: 100px;
height: 50px;
background: red;
}
.parent .child {
position: absolute;
width: 100%;
height: 100%;
background: skyblue;
}
<div class="parent">
<span class="child"></span>
</div>
One good part about this approach is, you don't need to use the dangerous calc:
.parent {
position: relative;
width: 150px;
height: 50px;
background: red;
}
.parent .child {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 60px;
background: skyblue;
}
<div class="parent">
<span class="child"></span>
</div>
Note: On a related note, you can also have a look at this question and answer: Calc() alternative to fixed side bar with content?
Set display: flex to the parent
Set align-self: stretch for the child
This will stretch the height of the child div/button to fit the height of its parent without doing any trick.
By using position: absolute instead of flex-box, it won't be very nice eventually when you have more stuff added or re-arrange later on would be the nightmare.
There must be something that I am missing, but I am trying to use ::after in my css, but unfortunately it isn't working.
My css code is below.
.test {
height: 40px;
width: 40px;
background: #444;
}
.test::after {
position: relative;
top: 15px;
height: 240px;
width: 240px;
background: red;
}
<div class="test"></div>
You just need add content: '' to pseudo-class :after or :before and set the position to absolute.
.test {
height: 40px;
width: 40px;
background: #444;
position:relative;
}
.test:after {
position: absolute;
top: 15px;
height: 240px;
width: 240px;
background: red;
content: ''
}
<div class="test"></div>
but if you want you can use it without absolute, just add some float to it, because pseudo-classes generates like inside the parent node.
.test {
height: 40px;
width: 40px;
background: #444;
position:relative;
}
.test:after {
content: '';
background: red;
width: 10px;
height: 10px;
float: right;
}
<div class="test"></div>
But if you need use it like icon, inside the block better way use it with absolute.
See this css:
div {
width: 100px;
height: 100px;
background: #333;
color: #fff;
}
div:after {
content: "test";
height: 100px;
}
I'm trying to vertically center the content of div:after. How can I do that?
I cannot set line-height to px value as height of the div might be dynamic (height: 100px is just for this example, in my app it stretches according to it's content)
http://codepen.io/anon/pen/ELnsJ
You can use CSS translate.
See pen: http://codepen.io/jhealey5/pen/Jseyt
div {
width: 100px;
height: 100px;
background: #333;
color: #fff;
position: relative;
}
div:after {
position: absolute;
content: "test";
margin-top: 50%;
transform: translateY(-50%);
}
Using display:table-cell you can make it vertically align middle.
div:after {
content: "test";
height: 100px;
display:table-cell;
vertical-align:middle;
}
You can try this
CSS
div {
width: 100px;
height: 100px;
background: #333;
color: #fff;
display: table;
}
div:after {
content: "test";
display: table-cell;
vertical-align: middle;
}
Try like this: DEMO
CSS:
div {
width: 100px;
height: 100px;
background: #333;
color: #fff;
display:table;
}
div:after {
content: "test";
height: 100px;
display:table-cell;
vertical-align:middle;
text-align:center;
}
With the following html, when I hover over child, I get a green background on parent. How can I stop that from happening? I do want the green background if I am hovering outside of the child element.
CSS3 is fine.
.parent {
padding: 100px;
width: 400px;
height: 400px;
}
.parent:hover {
background-color: green;
}
.child {
padding: 100px;
width: 200px;
height: 200px;
}
.child:hover {
background-color: blue;
}
<div class="parent">
<div class="child">Child</div>
</div>
So this is REALLY ugly, but it works (kind of). I'm basically creating a duplicate of parent as a sibling of child. parent-overwrite is hidden by default, then displayed on the hover of child. Chrome doesn't like it unless you use the + selector instead of the ~ selector. This isn't very scalable, but it may work.
As the other guys posted, javascript would likely be a better solution.
<style>
.parent { padding: 100px; width: 400px; height:400px; position: relative; z-index: 998; }
.parent:hover { background-color: green; }
.child { padding: 100px; width: 200px; height:200px; position: relative; z-index: 1000; }
.child:hover { background-color: blue; }
.parent-overwrite { padding: inherit; width: inherit; height: inherit; position: absolute; top: 0; left: 0; z-index: 999; background-color: #FFF; display: none; }
.child:hover ~ .parent-overwrite { display: block; }
</style>
<div class="parent">
<div class="child">Child</div>
<div class="parent-overwrite"></div>
</div>
In 2022:
This can be now achieved using a combination of the :has and :not pseudo-classes, with the following expression:
.parent:hover:not(:has(.child:hover)) {}
To break it down:
.parent
/* When this element is hovered */
:hover
/* but it does not */
:not(
/* have a child node .child, that is also hovered */
:has(.child:hover)
) {
/* apply these rules */
}
A working modification of the original snippet is below:
.parent {
padding: 100px;
width: 400px;
height: 400px;
}
.parent:hover:not(:has(.child:hover)) {
background-color: green;
}
.child {
padding: 100px;
width: 200px;
height: 200px;
}
.child:hover {
background-color: blue;
}
<div class="parent">
<div class="child">Child</div>
</div>
It can also be made recursive by reusing the .parent selector in place of the .child selector.
See browser support here. At the time of writing, all major browser support it—except Firefox, which still has a flawed experimental implementation.
I can only do this with adding additional markup. An empty div needs to be added that essentially functions as the parent background. Take a look at the CSS here.
HTML Part:
<div class="parent">
Parent
<div class="child">
Child
<div class="grandson">
Grandson
<div class="grandson-bg"></div>
</div>
<div class="child-bg"></div>
</div>
<div class="parent-bg"></div>
</div>
CSS part:
article, aside, figure, footer, header, hgroup, menu, nav, section { display: block; }
.parent { display: block; position: relative; z-index: 0;
height: auto; width: auto; padding: 25px;
}
.parent-bg { display: block; height: 100%; width: 100%;
position: absolute; top: 0px; left: 0px;
border: 1px solid white; z-index: 0;
}
.parent-bg:hover { border: 1px solid red; }
.child { display: block; position: relative; z-index: 1;
height: auto; width: auto; padding: 25px;
}
.child-bg { display: block; height: 100%; width: 100%;
position: absolute; top: 0px; left: 0px;
border: 1px solid white; z-index: 0;
}
.child-bg:hover { border: 1px solid red; }
.grandson { display: block; position: relative; z-index: 2;
height: auto; width: auto; padding: 25px;
}
.grandson-bg { display: block; height: 100%; width: 100%;
position: absolute; top: 0px; left: 0px;
border: 1px solid white; z-index: 0;
}
.grandson-bg:hover { border: 1px solid red; }
http://jsbin.com/ubiyo3/edit
The easiest thing to do may be to use JS for this sort of CSS. Maybe you can try to rethink your implementation. Why are you trying to do something like this?
This is not possible using plain-vanilla CSS. You're asking for a pseudo-class of a child (child:hover) to affect the background declaration of a parent. There's no way to specify that sort of thing using regular css.
This can definitely be done using javascript.
I have what i think is a better solution, since it is scalable to more levels, as many as wanted, not only two or three.
I use borders, but it can also be done with whatever style wanted, like background-color.
With the border, the idea is to:
Have a different border color only one div, the div over where the mouse is, not on any parent, not on any child, so it can be seen only such div border in a different color while the rest stays on white.
You can test it at: http://jsbin.com/ubiyo3/13
And here is the code:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Hierarchie Borders MarkUp</title>
<style>
.parent { display: block; position: relative; z-index: 0;
height: auto; width: auto; padding: 25px;
}
.parent-bg { display: block; height: 100%; width: 100%;
position: absolute; top: 0px; left: 0px;
border: 1px solid white; z-index: 0;
}
.parent-bg:hover { border: 1px solid red; }
.child { display: block; position: relative; z-index: 1;
height: auto; width: auto; padding: 25px;
}
.child-bg { display: block; height: 100%; width: 100%;
position: absolute; top: 0px; left: 0px;
border: 1px solid white; z-index: 0;
}
.child-bg:hover { border: 1px solid red; }
.grandson { display: block; position: relative; z-index: 2;
height: auto; width: auto; padding: 25px;
}
.grandson-bg { display: block; height: 100%; width: 100%;
position: absolute; top: 0px; left: 0px;
border: 1px solid white; z-index: 0;
}
.grandson-bg:hover { border: 1px solid red; }
</style>
</head>
<body>
<div class="parent">
Parent
<div class="child">
Child
<div class="grandson">
Grandson
<div class="grandson-bg"></div>
</div>
<div class="child-bg"></div>
</div>
<div class="parent-bg"></div>
</div>
</body>
</html>