I was looking at a couple Twitter Bootstrap templates and I saw that a lot of ::before and ::after were inserted before and after div tags.
Can anybody tell me what they are?
The ::before and ::after pseudo elements are for css and are in no way bootstrap specific.
A quick example of some of the stuff it can do is this:
Say you have a basic p element:
<p>Hello</p>
In your css, if you had this:
p::before{
content:'Hi';
}
The p tag in html would now say:
HiHello
If it was
p::after{
content:'Hi';
}
It would be:
HelloHi
This can be very useful if you're using it with things such as phone numbers, or e-mail addresses e.g
p.phone_number::before{
content:'Phone #: ';
}
<p class='phone_number'> would now have Phone #: before it.
You can do very many things, even use it for styling.
If you look at The shapes of CSS, you will see that it's used on the more complex shapes.
One thing that ::before and ::after have in common and MUST have to work, is the content attribute. If it doesn't have a content attribute it wont show up. Don't mistake this as having a blank content, though, as this will work provided you give it a height/width like any other element.
::before and ::after aren't the only Pseudo elements though, here is a list:
::after
::before
::first-letter
::first-line
::selection
You can also double up on these elements:
For example:
p:hover::before{
content:'Hovered! ';
}
They represent pseudo-elements, which you don't include directly in your markup, but are available to you to create some neat effects with CSS. You have mentioned ::before and ::after, and they represent pseudo-elements that appear, shockingly, before and after your elements.
The whole list is included below and should be fairly self-explanatory:
::after
::before
::first-letter
::first-line
::selection
ref: https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements
Note the use of the double-colon, which is consistent with the spec. Sometimes you will see pseudo-elements specified with a single colon, but that was only because we needed to support browsers that didn't understand the double-colon syntax.
Related
Is there any functional difference between the CSS 2.1 :after and the CSS 3 ::after pseudo-selectors (other than ::after not being supported in older browsers)? Is there any practical reason to use the newer specification?
It's pseudo-class vs pseudo-element distinction.
Except for ::first-line, ::first-letter, ::before and ::after (which have been around a little while and can be used with single colons if you require IE8 support), pseudo-elements require double colons.
Pseudo-classes select actual elements themselves, you can use :first-child or :nth-of-type(n) for selecting the first or specific <p>'s in a div, for example.
(And also states of actual elements like :hover and :focus.)
Pseudo-elements target a sub-part of an element like ::first-line or ::first-letter, things that aren't elements in their own right.
Actually, better description here: http://bricss.net/post/10768584657/know-your-lingo-pseudo-class-vs-pseudo-element
Also here: http://www.evotech.net/blog/2007/05/after-v-after-what-is-double-colon-notation/
CSS Selectors like ::after are some virtual elements not available as a explicit element in DOM tree. They are called "Pseudo-Elements" and are used to insert some content before/after an element (eg: ::before, ::after) or, select some part of an element (eg: ::first-letter). Currently there is only 5 standard pseudo elements: after, before, first-letter, first-line, selection.
On the other hand, there are other types of selectors called "Pseudo-Classes" which are used to define a special state of an element (like as :hover, :focus, :nth-child(n)). These will select whole of an existing element in DOM. Pseudo classes are a long list with more than 30 items.
Initially (in CSS2 and CSS1), The single-colon syntax was used for both pseudo-classes and pseudo-elements. But, in CSS3 the :: syntax replaced the : notation for pseudo-elements to better distinguish of them.
For backward compatibility, the old single-colon syntax is acceptable for pseudo-elements like as :after (browsers still all support the old syntax with one semicolon). Only IE-8 doesn’t support the new syntax (use single-colon if you want to support IE8).
I did research on it and as far as I know - CSS pseudo-elements ::before and ::after behaves like just span tags nested in a parent element.
On the other hand I have read they are might be extremely useful and in some cases even indispensable. If that is true they need to have some additional or different behavior than just span tags nested into the parent element.
If so what are the pros for using them over span tags?
The most common use of ::before and ::after selectors is to add content to an element solely via CSS, without the need to change the HTML itself. This may be required in situations where you can’t change the HTML, or for semantic reasons.
I recently noticed on a project that the ::after pseudoelement did not add any content after an input element:
input::after { content: "xxxxxxxxxx"; } // no "virtual last child" inserted into DOM "after" the input
(reference to "virtual last child" is from MDN page here)
Of course, an element such as a div will have content "after" it, and the last child "::after" will be inserted into the DOM:
div:empty::after { content: "xxxxxxxxxx"; }
//In DOM
<div>::after</div>
but nothing is inserted in these cases:
head, script { content: "qaqaqa"; }
My initial assumption was that any HTML elements that are rendered by the browser with tags that should be closed (.e.g, p, body, html, div,....etc) will have ::after inserted as a last child (and ::before inserted as a first-child), whereas elements that do NOT fit this (e.g., script, head, img, br, input,...etc) will not exhibit this behavior. My CodePen attempts suggested this was correct.
I read through documentation which finally led me to this resource, in which a note reads:
Note. 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.
(for definition of "replaced elements" see here)
So now my refined assumption regarding ::after and ::before is that these pseudoelements are only applicable to "renderable" elements which cannot be classified as "replaced elements" (Note this refined assumption now excludes textarea from use with ::after / ::before, whereas my initial assumption would have included it - textarea::after was tested with CodePen and no ::after last child is inserted into the DOM).
Would the refined assumption be correct?
HTML does not define which elements are replaced elements or which elements can contain ::before and ::after pseudo-elements. Neither do CSS2.1 or selectors-3. The latest rewrite of css-content-3, however, states pretty unambiguously:
Replaced elements do not have '::before' and '::after' pseudo-elements
although implementations of course are not consistent with the draft (famously or otherwise, WebKit/Blink) since this wasn't hitherto defined.
Whether an element can have ::before and ::after pseudo-elements is not defined by its content model (i.e. if it's void or otherwise), or whether it has an end tag, in HTML. And again, a lot of this is implementation-dependent. For example, some implementations allow br of all things to have ::before and ::after pseudo-elements, because nobody knows exactly how br is supposed to be implemented in terms of CSS and each browser does it its own way (because neither HTML nor CSS actually defines this).
A head element and any of its descendants can have ::before and ::after pseudo-elements — all you have to do is change their display to something other than none. Obviously, they're not supposed to be displayed, but that doesn't stop anyone trying to be clever.
As far as CSS is concerned, input and textarea are both considered replaced elements, even though textarea has a start tag, end tag, and content. Whether these elements should or must be replaced elements is not stated (not even in section 14.5 of WHATWG HTML), but most browsers render them as replaced elements by default, and this behavior usually can't be changed. And for the purposes of the ::before and ::after pseudo-elements not being supported, that's all that matters.
Don't guess, read: https://drafts.csswg.org/selectors-3/#gen-content
The ::before and ::after pseudo-elements can be used to describe generated content before or after an element's content.
input has no content, so no after element is shown. Same applies for every HTML element with no content (br, menuitem, link...). All auto-closing tags have no content, and some others (like script) have none too.
couldn't find an example that uses css :before to add <use> inside a <svg> tag. So far I've tried:
.icon-test:before {
content : '<use xlink:href="test.svg#icon-test"></use>';
}
.icon-test:before {
content : '\003Cuse xlink\003Ahref\003D\0022test\002Esvg\0023icon-test\0022\003E\003C\002Fuse\003E';
}
<svg class="icon-test"></svg>
Does anybody know the correct way to do it? Or this is not possible?
Basically the end result should yield something like:
<svg class="icon-test">
<use xlink:href="test.svg#icon-test"></use>
</svg>
But I want to simplify the usage by using :before. Thanks!
use ::before
is not possible. You will receive text;
A little more detail compared to Jarosław Goszowski's answer:
The ::before and ::after pseudoelements create a new CSS layout box as the first or last child of the CSS layout box for the element(s) matched by the rest of the selector.
The :: notation distinguishes pseudoelement selectors from pseudoclass selectors, and is supported in all browsers after IE8 (in other words, all browsers that will support inline SVG). The single : syntax is only supported for backwards-compatibility.
The psuedo-elements do not create new elements in the DOM, and cannot be used to insert markup. They only affect CSS layout. The content is injected after the HTML markup has been parsed. You cannot even use HTML entities like &; you definitely cannot use entire element markup.
Because they only affect CSS layout, pseudo-elements can only exist for elements whose content follows the CSS layout model. That means you cannot have pseudo-elements for:
<img> and <video> elements (the content of the element is replaced by the external file, it does not have a CSS layout model);
<input> and <select> elements (the content is replaced by the form widgets created by the browser, no CSS layout model);
SVG elements (the content is drawn according to SVG rules, not CSS layout).
So there are two reasons why you cannot use pseudoelements to inject your <use> elements: one, pseudoelements don't have an effect on SVG; two, even if they did, pseudoelements can only be used to inject plain text (or complete image files), not markup.
This might be a stupid question, but if I have something like this:
<div id="topDiv">
<header id="headerId" class="headerClass" style="display: block;">
::before
<div>...</div>
<div>...</div>
<div>...</div>
</header>
</div>
What does this 'before' in the html do?
I understand if I do the following in the CSS it adds these properties before every p element: (this is from a W3Schools example)
p::before {
content: "Read this -";
background-color: yellow;
color: red;
font-weight: bold;
}
You're seeing that ::before because that is how your browser's developer tools represents a CSS ::before pseudo-element in the document tree view.
If you literally had a string of text "::before" in your HTML file, it would do nothing special as it has no meaning in HTML; it would just show up as the text "::before" on your page.
I guess there can be two reason (Its via personal experience & observation not a valid reference for support)
1) It provides a visual representation of these pseudo selectors according to their meaning
::before before the div to which its applied to and ::after after the div to which its applied to
2) Pseudo selectors are used to insert some content:'' in HTML. So this provides a distinct representation. User can easily inspect which content is inserted in HTML via these pseudos.
And Yes its on each browser how the implement and show the pseudos.
good luck!
It is stating that you have a pseudo element in your html. Since it is not a 'real' element, you can't physically manipulate it like you can do with 'real' elements like div's and buttons.
You may also see ::after appearing in places, representing somewhere for either your id="headerId" or class="headerClass" has a ::before element declared.
the whole reason they are not declared like <after></after> or anything like this is because it is 'a ghost' or 'shadow' of a 'real element', and hence can only be styled/manipulated in the css before the html is rendered.