This question already has answers here:
Why do the :before and :after pseudo-elements require a 'content' property?
(5 answers)
Closed 7 years ago.
I tried to set a img before my option field.
I tried
option::before
{
display: inline-block;
width: 16px;
height: 16px;
background-image: url();
}
But it doesn´t work. How to do it?
It is not displayed in Firefox inspector. Normally there should be displayed ::before
Pseudo selectors are like empty DOM elements. And any element to be styled needs to have some content.
Your ::before pseudo element needs some content, which you can simply fill in using 'content' property.
option::before {
content: '';
display: inline-block;
...
}
Also note, you can use 'content' property to any HTML DOM element.
And for pseudo selectors, they need to have a 'display' property along, unless positioned absolute or fixed.
Related
This question already has answers here:
Image inside div has extra space below the image
(10 answers)
Why is this inline-block element pushed downward?
(8 answers)
Closed 3 years ago.
Example:
https://codepen.io/229075284/pen/aboQVXZ
.outer{
background-color: pink;
}
.outer::after{
content:'';
background-color: red;
display: inline-block;
font-size: 0;
line-height: 0;
overflow: hidden;
height: 0;
/* display: table; */
}
.inner{
background-color: blue;
height: 300px;
}
<div class="outer">
<div class="inner"></div>
</div>
When I set display of outer::after to inline-block,the outer will have some extra space marked as pink, even if set font-size and line-height to 0. However, when I set display to table,the extra space disappears.
So I am wondering why the extra space appears?
I checked your codepen. It is a combination of both display: inline-block and content: "" on the ::after pseudo element. You are basically telling the browser that right after the outer element you want to reserve an element's place in the DOM.
You could see that if you remove the content: "" although you are using inline-block the extra pseudo div after the .outer element would disappear. That is because although you stated a certain display mode you practically have no content in this element and the browser ignores your element because it has no fixed size in pixels and no actual content within it.
The reason .outer is growing is that its height is set to auto in default, if you would give it a fixed height in pixels it might not show the spare div.
Your question has nothing to do with line-height or `overflow'.
Me personally I prefer not to use pseudo-classes like ::after and ::before in production. I prefer using regular divs and have my code more readable and understandable by other developers, anyway I hope I helped out. Feel free to discuss further if you have more questions.
This question already has answers here:
CSS, using display:table with before pseudo element
(2 answers)
Closed 5 years ago.
In this example, why does container need to have the pseudo-element after and before with content: '' and display: table to show the gray background? Shouldn't container automatically expand to fit both of its children and then fill out the negative space with the gray background without the pseudo-elements already?
This is called a 'clearfix', when a container has all of his the childs floating, you have to use a clearfix on it.
I put a black background in the container:
With clearfix: https://codepen.io/anon/pen/GvoEjx
Without clearfix: https://codepen.io/anon/pen/NvxgRe
https://css-tricks.com/snippets/css/clear-fix/
.container:before,
.container:after {
content: "";
display: table;
clear: both;
}
This question already has answers here:
Do <span> elements with "position: absolute;" behave as block-level elements?
(2 answers)
Closed 2 years ago.
Today I faced an interesting problem at work.
When I style an inline-element with position:absolute or fixed it behaves like a block-element which can have a height and with.
Here a short example:
span {
background: red;
height: 100px;
width: 100px;
}
span#absolute {
position: absolute;
top:30px;
left:30px;
}
<span>Inline</span>
<span id="absolute">Inline, too</span>
As you can see both spans have height and width (which should be ignored on inline-elemens). However it gets applied when using posision:absolute.
So my question: Is the second span behaving like display:block completely or is it just a semi-block-behaviour?
http://www.w3.org/TR/CSS21/visuren.html#dis-pos-flo:
The three properties that affect box generation and layout — 'display', 'position', and 'float' — interact as follows:
2. […] if 'position' has the value 'absolute' or 'fixed', the box is absolutely positioned, the computed value of 'float' is 'none', and display is set according to the table below.
And in that mentioned table below, you see that for the specified value inline (which span has by default from the user agent stylesheet), the computed value is … block
Per Chrome's computed styles on span#absolute, the element has a display:block property.
Please consider the following CSS. Note that there are no other CSS rules defined or in effect in this situation:
* {
position: absolute;
color: red;
}
div {
position: static;
color: blue;
}
When I add a div with a bit of text, which is live here, the text in the div no longer traverses the entire screen. It is as though the width property of the div is set to 10%. If I remove the position:absolute declaration from the wildcard, the div returns to normal (the text goes the whole way across the screen). This is puzzling to me, since I have all divs defined with the position:static declaration. I tried this with and without the famous "reset.css" stylesheet included, and I am getting the same results.
At first i thought that perhaps the wildcard rule takes presidence over the div rule in CSS. That would have been simple enough. However, I have the color property of the wildcard rule set to red and the color property of the div rule set to blue, and the text is showing up blue. So the answer cannot simply be that the wildcard rule takes precedence over the div rule.
One thing I think might be relevant: an absolutely positioned element is positioned relative to its first positioned (not static) ancestor element. In this case, the body has no such ancestor, and therefore this is probably just some kind of silent error caused be the body being set to absolute positioning but with no positioned ancestor element.
Does anyone know what the cause of this odd behavior is?
The position: absolute applies to the <div>'s parents.
It makes them shrinkwrap to fit their contents – the text of the <div>.
Since the <div>'s layout area no longer encompasses the full page width, it doesn't stretch.
You can fix this by adding width: 100% and getting rid of margins and padding.
Make html and/or body position static as well:
Demo with html { position: static; }
Demo with body { position: static; }
Or, change your selector to body *:
body * {
position: absolute;
color: red;
}
div {
position: static;
color: blue;
}
Is it possible to not display an element, as with display:none, but continue to display the :before and/or :after?
I tried
#myspan {display:none}
#myspan:after {display:inline; content:"*"}
but that didn't work. I'm trying to have CSS replace the content of a span with an asterisk, without introducing jQuery.
No, it is not possible.
Pseudo elements are rendered like children:
<span id="myspan">whatever<after></span>
And display:none hides the element including all children.
EDIT 1
JavaScript is your best option in my opinion. Even without jQuery changing text is not hard:
document.getElementById("myspan").innerHTML = "*";
Demo
EDIT 2
However, if you really want to do it with CSS, you can use negative text-indent to hide the text and relative positioning to show the asterisk:
#myspan {
text-indent: -9999px;
display: block;
}
#myspan:before {
content: '*';
position: absolute;
top: 0;
left: 9999px;
}
Demo
I think a very easy approach to doing this is to exploit the visibility property. But note that a "hidden" element still takes up the space. But if you are okay with that, just make make the parent element "hidden" and pseudo element "visible":
#myspan {visibility:hidden}
#myspan: after {visibility:visible}
Once you have the visibility taken care of, feel free to play around with the position so that excess space is avoided.
Something like,
myspan {
visibility: hidden;
position: relative;
}
myspan:after {
visibility: visible;
position: absolute;
left: 10px;
}
It's definitely possible. Use font-size: 0px instead of display: none:
#myspan {
/* display: none; */
font-size: 0px;
}
#myspan:after {
/* display: inline; */
font-size: 16px;
content: "*"
}
A demo is here.
In this case you can only use px/pt for the display text font units.
Use:
#myspan {font-size:0}
#myspan:after {font-size:16px; content:"*"}
If you have a min-font size specified, it won't work (browser setting). I'd only use this method for things like previous and next buttons so that screen readers will read "Previous", but you want to replace it with a \276e. So plan for what it will look like with the text showing up.
As explained by #bookcasey, setting display: none on an element unavoidably hides the :after or :before pseudo-element too (because they are not really something displayed after or before an element but content added inside the element, after or before its real content).
But the goal of replacing an element’s real content by generated content is in principle possible, according to the old (2003) CSS3 Generated and Replaced Content Module draft, by simply setting content on the element, e.g.
#myspan { content: "*"; }
So far, only Opera supports this. But a special case where the replacing content is an image is supported by WebKit browsers, too:
#myspan { content: url(asterisk.png); }
It is possible, but you need to use visibility:hidden instead of display:none.
See the answers in the following question for more detail:
How can I replace text with CSS?
You need to break them into multiple content DIV blocks because the style is inherited by child elements. So it's not possible once the parent display style is defined.