Cannot get the :before element to appear on ReactiveForms input - css

I am trying to display a FormControl on a form to hold a telephone country code prefix, and I want it to always display a plus sign in the left-padding area. My bet was to use a :before element on the input, but surprisingly I cannot get it to appear in the DevTools inspector. When I started to notice the problem I even went despearate and tried to place the :before element on all inputs - to no avail. On the other hand, styles for the main input element work as expected.
Same goes with :after.
So my question is - does placing a :before or :after element work for anyone? Is it a know "feature" of ReactiveForms or a bug?
css
input[name="telCountryCode"]:before {
content: '+';
display: inline-block;
position: absolute;
top: 0;
left: 0;
width: 1rem;
height: 1rem;
}
ts
this.form = this.fb.group({
telCountryCode: '',
telNumber: '',
});

pseduo elements like :before/:after do not work on INPUT tag

wrap the input with div
<div class="telCountryCode-wrapper">
<input type="text" name="telCountryCode">
</div>
and use this css
.telCountryCode-wrapper{
position:relative;
}
.telCountryCode-wrapper:before{
content: '+';
display: inline-block;
position: absolute;
top: 0;
left: 0;
width: 1rem;
height: 1rem;
}

:before/:after renders inside a container only
You can't use :before/:after or other pseudo-elements for input.
Also img br hr etc.
It doesn't apply for self-closing elements.

Pseudo-elements can only be defined (or better said are only supported) on container elements. Because the way they are rendered are within the container itself as a child element.
input can not contain other elements hence they're not supported.
Refer this Can I use the :after pseudo-element on an input field?

Related

CSS :after pseudo element doesn't work inside button in any IE version

I can't get this code to work in any IE version. Am I doing something wrong or is IE just crap as usual?
HTML:
<button>A button</button>
CSS
button {
position: relative;
}
button:after {
content: "Can u see me?";
position: absolute;
right: -100px;
top: 0;
}
Demo: http://jsfiddle.net/96ryusnp/
You need to add overflow: visible to button.
<button>A button</button>
button {
position: relative;
overflow: visible;
}
button:after {
content: "Can u see me?";
position: absolute;
right: -100px;
top: 0;
}
http://jsfiddle.net/96ryusnp/1/
IE must set it to hidden by default on buttons.
button elements are replaced elements.
And according to the CSS 2.1 spec,
This specification does not fully define the interaction of :before
and :after with replaced elements (such as IMG in HTML). This will be
defined in more detail in a future specification.
But the current draft of Selectors Level 3 only says
The ::before and ::after pseudo-elements can be used to describe
generated content before or after an element's content. They are
explained in CSS 2.1
Therefore, using :before or :after on button elements will produce unreliable results.

Pseudo-class on pseudo-element

OK to be clear, I am not trying to make the (pseudo)inception for css. Just wanted to check if it's possible to add a pseudo class on a pseudo element. For eg:
.some-class:after:hover {
}
doesnt seem to work.
This works though:
.some-class:hover:after {
}
And ofcourse, this doesn't:
.some-class:hover:after:hover {
}
What I am trying to do is- there is a div. If you hover on that div, I am attaching a delete icon using :after on the div. I want to style this icon (say, have it zoom to 1.1 or so). Is this possible purely on CSS? I just need it to work on Chrome.
No, the current standard does not allow attaching pseudo-classes to pseudo-elements. The only place where a pseudo-element may appear is at the very end of a complex selector, and no other selectors or combinators may appear after it. Refer to the spec.
Some implementations like WebKit have their own rules, but they are non-standard and do not work cross-browser. They may also not apply to all pseudo-classes and/or all pseudo-elements. For example, as far as I know, :after:hover does not work on any browser, Chrome included.
Either way, you will need to use an actual element instead of a pseudo-element.
As already answered by #BoltClock that it is not possible to attach an :hover pseudo on :after so if you want, you can nest an extra element inside your container element and achieve the desired effect.
div {
height: 300px;
width: 300px;
border: 1px solid tomato;
margin: 20px;
position: relative;
}
div span {
display: none;
position: absolute;
right: 0;
top: 0;
}
div:hover span {
display: block;
transition: font-size .5s;
}
div span:hover {
font-size: 20px;
}
<div>
<span>X</span>
</div>
This will give you desired effect without using any JavaScript on your page, only down side of this is that you need to have an extra element so if you don't have any access or permission to modify your HTML then this is not for you unless you can then append an element using JavaScript.

Is it somehow possible to style an iframes before/after pseudo-element?

As the title says, is there a way to style an iframes pseudo before/after? Without wrapping the iframe with another div, or else?`
I tried to style it like any other element, but no success:
iframe::before {
content: 'foo';
position: absolute;
top: 0;
left: 0;
}
iframe::after {
content: 'bar';
position: absolute;
top: 0;
right: 0;
}
http://fiddle.jshell.net/ppRqm/
Update
A known workaround is to add the before/after to an element in the source file:
http://fiddle.jshell.net/ppRqm/2/
But sometimes you've no access to the source-file.
I am not sure but I think it isn't possible. Or the logic behind an iframe makes it imposible to achieve.
As you know, pseudo-elements are added to its container, if you do that with an iframe, pseudo-elements would be added inside the iframe.
But, and here's the problem, the iframe content, the inline content, will just load if the browser doesn't support iframes.
This means that this:
<iframe>
<div>Your browser doesn't support iframes</div>
</iframe>
And adding pseudo-elements, will do the same thing; on modern browsers inline content wouldn't be displayed.
Direct Work-Around for Debugging Purposes
I have a debugging CSS tier that gives an outline to elements with invalid or obsolete code. While not exactly an answer someone may find it helpful as I was trying to find a way to visually ensure that any content embedded with an iframe had an allowfullscreen="true" attribute/value. This work-around uses a sibling selector and it works well-enough.
iframe:not([allowfullscreen]) + *::after
{
background-color: #f00;
border: #f00 solid 4px;
color: #fff;
content: 'Missing allowfullscreen attribute on iframe!' !important;
font-size: 24px;
padding: 4px;
}
Direct Styling using Third Element
If you're looking to position relative to the iframe my next recommendation would be to set the iframe's parent position to position: relative; and then set position: absolute; on a third element to match the iframe's rendering. Lastly you could finally apply the ::after on that third element.

In CSS, what is a better way of forcing a line break after an element than making it a block element?

I have an H3 heading that I'd like to style as having a particular background color, but without having the element's background take up the full width of the parent element. Seeing as H3 is by default a block element, my style would need to change the element to an inline-block element, or just an inline inline element like so:
h3 {
background-color: #333;
color: white;
display: inline-block;
}
This will work fine, but only if it is immediately followed by a block element. I do not want to change the markup just to cater for this style, so I was wondering if there is a way to cause any adjacent element, irrespective of how it displays, to start on the next line?
Assume I can use CSS3.
try this:
h3:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
display:block;
width:auto;
This will make the width as small as possible (not filling the whole parent element) and make other elements appear below.
How often does it happen that the element after the <h3> is an inline element? (Usually after a header there should be like a <p>, <ul> or other block elements, although this totally depends on your html. Is it predictable? Is it an option to just turn every element that directly follows a <h3> into a block element?
h3 ~ * { display: block }
The only other way I know to have a block-element not take up all the space is floating it, but this leaves another problem.
I come across this all the time in my code, usually for div's that are inline-block'ed. The best way I've seen is to force a new line is to wrap your code in an additional div. Your original html gets the formatting you expected and the div wrapper forces a new line.
Assuming this is your h3 styling,
h3 {
display: inline-block;
}
Then just wrap it in a div.
<div>
<h3>My heading</h3>
</div>
I've had to do something similar with inline nav items that need breaking at certain points. Does this work?
h3:after {
content: "\A ";
line-height: 0;
white-space: pre;
display:inline-block;
}
I seem to remember IE7 having an issue with it.
If you don't need to center h3, this may help:
h3 {
background-color: #333;
color: white;
display: inline-block;
float: left;
clear: left;
}

Is it possible to set the stacking order of pseudo-elements below their parent element? [duplicate]

This question already has answers here:
How to get a child element to show behind (lower z-index) than its parent? [duplicate]
(7 answers)
Why can't an element with a z-index value cover its child?
(5 answers)
Closed 3 years ago.
I am trying to style a element with the :after pseudo element CSS selector
#element {
position: relative;
z-index: 1;
}
#element::after {
position:relative;
z-index: 0;
content: " ";
position: absolute;
width: 100px;
height: 100px;
}
It seems like the ::after element can not be lower then the element itself.
Is there a way to have the pseudo element lower then the element itself?
Pseudo-elements are treated as descendants of their associated element. To position a pseudo-element below its parent, you have to create a new stacking context to change the default stacking order.
Positioning the pseudo-element (absolute) and assigning a z-index value other than “auto” creates the new stacking context.
#element {
position: relative; /* optional */
width: 100px;
height: 100px;
background-color: blue;
}
#element::after {
content: "";
width: 150px;
height: 150px;
background-color: red;
/* create a new stacking context */
position: absolute;
z-index: -1; /* to be below the parent element */
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Position a pseudo-element below its parent</title>
</head>
<body>
<div id="element">
</div>
</body>
</html>
I know this is an old thread, but I feel the need to post the proper answer. The actual answer to this question is that you need to create a new stacking context on the parent of the element with the pseudo element (and you actually have to give it a z-index, not just a position).
Like this:
#parent {
position: relative;
z-index: 1;
}
#pseudo-parent {
position: absolute;
/* no z-index allowed */
}
#pseudo-parent:after {
position: absolute;
top:0;
z-index: -1;
}
#parent { position: relative; z-index: 1; }
#pseudo-parent { position: absolute; } /* no z-index required */
#pseudo-parent:after { position: absolute; z-index: -1; }
/* Example styling to illustrate */
#pseudo-parent { background: #d1d1d1; }
#pseudo-parent:after { margin-left: -3px; content: "M" }
<div id="parent">
<div id="pseudo-parent">
</div>
</div>
Try it out
el {
transform-style: preserve-3d;
}
el:after {
transform: translateZ(-1px);
}
There are two issues are at play here:
The CSS 2.1 specification states that "The :beforeand :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." Given the way z-indexes are implemented in most browsers, it's pretty difficult (read, I don't know of a way) to move content lower than the z-index of their parent element in the DOM that works in all browsers.
Number 1 above does not necessarily mean it's impossible, but the second impediment to it is actually worse: Ultimately it's a matter of browser support. Firefox didn't support positioning of generated content at all until FF3.6. Who knows about browsers like IE. So even if you can find a hack to make it work in one browser, it's very likely it will only work in that browser.
The only thing I can think of that's going to work across browsers is to use javascript to insert the element rather than CSS. I know that's not a great solution, but the :before and :after pseudo-selectors just really don't look like they're gonna cut it here.
Speaking with regard to the spec (http://www.w3.org/TR/CSS2/zindex.html), since a.someSelector is positioned it creates a new stacking context that its children can't break out of. Leave a.someSelector unpositioned and then child a.someSelector:after may be positioned in the same context as a.someSelector.
I know this question is ancient and has an accepted answer, but I found a better solution to the problem. I am posting it here so I don't create a duplicate question, and the solution is still available to others.
Switch the order of the elements. Use the :before pseudo-element for the content that should be underneath, and adjust margins to compensate. The margin cleanup can be messy, but the desired z-index will be preserved.
I've tested this with IE8 and FF3.6 successfully.
Set the z-index of the :before or :after pseudo element to -1 and give it a position that honors the z-index property (absolute, relative, or fixed). This works because the pseudo element's z-index is relative to its parent element, rather than <html>, which is the default for other elements. Which makes sense because they are child elements of <html>.
The problem I was having (that lead me to this question and the accepted answer above) was that I was trying to use a :after pseudo element to get fancy with a background to an element with z-index of 15, and even when set with a z-index of 14, it was still being rendered on top of its parent. This is because, in that stacking context, it's parent has a z-index of 0.
Hopefully that helps clarify a little what's going on.
I fixed it very simple:
.parent {
position: relative;
z-index: 1;
}
.child {
position: absolute;
z-index: -1;
}
What this does is stack the parent at z-index: 1, which gives the child room to 'end up' at z-index: 0 since other dom elements 'exist' on z-index: 0. If we don't give the parent an z-index of 1 the child will end up below the other dom elements and thus will not be visible.
This also works for pseudo elements like :after
I don't know if someone will have the same issue with this. The selected answer is partially correct.
What you need to have is:
parent{
z-index: 1;
}
child{
position:relative;
backgr

Resources