Before and After Pseudo Elements - html

JS Fiddle
I have a div:
<div id="strip"></div>
With the CSS:
width: 100%;
height: 130px;
background: grey;
I want a pseudo element after it and to be at the base of the strip.
#strip:after {
content: "";
display: block;
width: 100%;
height: 10px;
background: blue;
}
I also have a pseudo element before the strip.
#strip:before {
content: "";
display: block;
width: 100%;
height: 10px;
background: yellow;
}
The problem is, the after pseudo element does not sit at the bottom of the strip div. Where am I going wrong. Please note I have simplified the question, I know there are alternative ways to get strips of color at the top and bottom of a div.

The CSS specification says :
The :before and :after pseudo-elements interact with other boxes as if they were real elements inserted just inside their associated element.
In order to solve your issue, you can use the solution suggested by Nico O. The after pseudo-element is absolute positionned at the bottom of the main element.
#strip{
width: 100%;
height: 130px;
background: grey;
position: relative;
padding-bottom: 10px;
}
#strip:after {
content: "";
display: block;
width: 100%;
height: 10px;
background: blue;
position: absolute;
bottom:0;
}
#strip:before {
content: "";
display: block;
width: 100%;
height: 10px;
background: yellow;
}

Related

How to maintain a dynamic height of the pseudo selector ::before?

The UI View has an accordion, where I need to show some connector representation within an accordion and its children and I'm trying to achieve that using an ::before pseudo-selector for the container inside the parent accordion which has all the children accordions. The left vertical line needs to be stopped at the last intersection of the circle and the horizontal line. In the second sample image, the number of children inside the table is also unknown, I also tried placing the before element using a bottom property.
Any help I could achieve that?
& {
position: relative;
margin-left: 2rem;
padding: 0;
}
&::before {
content: '';
position: absolute;
top: 0;
background: #003d76;
left: 0;
height: 100%;
width: 1px;
display: block;
}
I have achieved this challenge, I have tried to follow the method suggested by #CBroe but there are some unavoidable dependencies that I couldn't change. Tried to make use of an ::after selector and hide the extra vertical line of the last-child with a white square.
.subAccordion {
& {
position: relative;
margin-left: 2rem;
padding: 0;
overflow: hidden;
}
&::before {
content: '';
position: absolute;
top: 0;
background: #003d76;
left: 2px;
height: 100%;
width: 2px;
display: block;
}
&:last-child::after {
content: '';
display: block;
position: absolute;
background: white;
width: 4%;
height: 100%;
top: 51px;
left: -5px;
}
}

Data attribute in div element and display on ::after pseudoelement

So this is my code. I would like to display my image via data-bg on my div::after pseudoelement. I always get url, but I want display image.
body {
background: red;
width: 100vw;
height: 100vh;
}
div:before {
content: attr(data-bg);
display: block;
}
<div data-bg="https://via.placeholder.com/150"></div>
Code correction
There is a few errors in your code:
If you want to get the image at the requested url, you need to use url()
You are using content instead of background-image
Theoretically, your code should you like the following snippet with the corrections, don't forget to add a content and to size you pseudo-element.
body{
background: red;
width: 100vw;
height: 100vh;
}
div:after{
content: '';
background-image: url(attr(data-bg));
width: 150px;
height: 150px;
display: block;
}
<div data-bg='https://via.placeholder.com/150'></div>
Unfortunately, this won't work
The background-image property does not work well with url(attr()), so here is another snippet that does what you are trying to achieve. We're declaring a CSS variable for the element instead of using an HTML attribute. You may find more details in this related question
body{
background: red;
width: 100vw;
height: 100vh;
}
div:after{
content: '';
background-image: var(--bg-image);
width: 150px;
height: 150px;
display: block;
}
<div style="--bg-image: url('https://via.placeholder.com/150');"></div>
<html><head>
body{
background: red;
width: 100%;
height: 100%;
}
div:after{
content: '';
background-image: var(--bg-image);
width: 50%;
height: 50%;
display: block;
}
</head><body><div style="--bg-image: url('https://images.unsplash.com/photo-1453728013993-6d66e9c9123a?ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8dmlld3xlbnwwfHwwfHw%3D&ixlib=rb-1.2.1&w=1000&q=80');"></div></body></html>`enter code here`

Prevent a pseudo element from changing the width/scroll width of a parent container?

I'm trying to put a green area, a pseudo element, to the right of of a blue element, the pseudo element's parent, such that the green element doesn't increase the width of the red scroll area, the container. My actual use-case is a bit more complex, but it relies on using a pseudo element so this below example sets up the problem well. I've included two blue areas and two green areas simply to show that I want the scroll area to scroll if the blue width is large enough. I just don't want the green area to be part of the calculation:
* {margin:0;padding:0}
div {
display: inline-block;
width: 200px;
height: 200px;
background-color: red;
overflow: auto;
}
span {
display: inline-block;
height: 50px;
position: relative;
background-color: blue;
vertical-align: top;
}
span:before {
content: '';
position: absolute;
left: 100%;
width: 500px;
top: 0;
bottom: 0;
background-color: green;
}
<div>
<span style="width:50px"></span>
<span style="width:250px"></span>
</div>
JS Fiddle
Ideally the green pseudo element would be pulled out of the layout completely and have no width. The problem is for the background-color to work it requires a width. I'm strongly suspecting I can't use background-color for this. If something like outline-right: 500px solid green; existed that would be a solution, but I can't find anything like that. I can't use box-shadow, border-right, or anything else since those all add to the width. Is there any mechanism in CSS that would allow the green area to not be included in the red's scroll width area?
Using an outer container with the inner one set to overflow: hidden; removes the absolutely positioned elements from being included in the width and scroll area calculation.
Using min-width: 100%; ensures that the inner container takes up at least the whole width of the outer container.
* { margin: 0; padding: 0; }
#first {
display: inline-block;
width: 200px;
height: 200px;
background-color: red;
overflow: auto;
}
#second {
display: inline-block;
overflow: hidden;
min-width: 100%;
}
span {
display: inline-block;
height: 50px;
position: relative;
background-color: blue;
vertical-align: top;
}
span:before {
content: '';
position: absolute;
left: 100%;
width: 500px;
top: 0;
bottom: 0;
background-color: green;
}
<div id="first">
<div id="second">
<span style="width:50px;"></span>
<span style="width:250px;"></span>
</div>
</div>
JS Fiddle

How to make content appear before and after div

I want my content from &:before and &:after appear outside my div.first and before and after.
I thought the best way is using the css above, but it still appears inside my div, am I using the wrong method or is it something else?
Jsfiddle: https://jsfiddle.net/1uuL3sf6/1/
HTML
<div class="first">
</div>
CSS
.first
{
width: 100%;
height: 500px;
background-color:red;
&:before
{
content:"before";
width: 100%;
height: 20px;
}
&:after
{
content:"after";
width: 100%;
height:20px;
}
}
The pseudo elements :before and after do not create content before and after their parent element. They are inserted before and after its actual content.
A pseudo-element does exactly what the word implies. It creates a phoney element and inserts it before or after the content of the element that you’ve targeted.
From "Learning To Use The :before And :after Pseudo-Elements In CSS"
That's why they are always displayed inside the box of their parent.
However, as an example you can use absolute positioning to move the pseudo element out of the box:
&:before {
content:"before";
position: absolute;
top: -20px;
width: 100%;
height: 20px;
}
But you can also float them or display them as block to achieve your desired result.
Demo
Try before buy
.first {
width: 100%;
height: 500px;
background-color:red;
}
.first::before
{
content:"before";
}
.first::after
{
content:"after";
}
<div class="first">
</ br> This is your first div. </ br>
</div>
Here is a solution: https://jsfiddle.net/e8qtoxL9/
.first
{
width: 200px;
height: 200px;
margin: 0 auto;
background-color:lightgreen;
position: relative;
&:before
{
content:"before";
width: 100%;
height: 20px;
display: block;
background: lightblue;
left: -100%;
top: 0;
position: absolute;
}
&:after
{
content:"after";
width: 100%;
height:20px;
display: block;
background: lightblue;
left: 100%;
top: 0;
position: absolute;
}
}

Using the last line of an inline element as the width for :after pseudo element

I'm facing an issue that I'm struggling to overcome.
This is best demonstrated with an example I guess:
As a fiddle: http://jsfiddle.net/wchv2hmn/3/
In the browser:
div {
background-color: blue;
text-align: center;
}
span {
position: relative;
background-color: green;
}
span:after {
content: '';
display: block;
position: absolute;
left: 0;
right: 0;
height: 10px;
width: 100%;
background-color: red;
}
<div>
<span>
htejuteujetjtjehrehreheherhrehrehre sghosgjosjoskoskfosjofshohofshofusofhrehrhrehehhrehrherheheuorfos
</span>
</div>
I need the :after pseudo element to take on the width of the last line of text within the <span>, not the first.
Adding inline-block to the span, results in the text just being displayed as a block level element, as seen here in chrome and Firefox 39:
div {
background-color: blue;
text-align: center;
}
span {
position: relative;
background-color: green;
display:inline-block;
}
span:after {
content: '';
display: block;
position: absolute;
left: 0;
right: 0;
height: 10px;
width: 100%;
background-color: red;
}
<div>
<span>
htejuteujetjthehtehtehethetje sghosgjosjoskoskfosjofshohofshofusethehetthehehterfos
</span>
</div>
It's as if the <span>s min-width is set to the length the <span> will occupy when all the text fits on one line. So when the window shrinks, and the text splits to occupy two or more lines, the width can't shrink any smaller than it's assumed min-width...
Does anyone have any ideas? Preferably without having to alter the DOM, although it can be done if absolutely necessary.
You need to set the span as block element.
Html
<div>
<span>
htejuteujetjtje sghosgjosjoskoskfosjofshohofshofusofuorfos
</span>
</div>
CSS
div {
background-color: blue;
}
span {
position: relative;
background-color: green;
}
span{display:block;}
span:after {
content: '';
display: block;
height: 10px;
width: 100%;
background-color: red;
position: absolute;
}
Add display:inline-block to span style
span {
position: relative;
background-color: green;
display:inline-block;
}
Result: