What does ::before on its own line do in HTML? - html

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.

Related

How to overrlay a gradient over an image [duplicate]

Given the following scenario, why does the :after selector require a content property to function?
.test {
width: 20px;
height: 20px;
background: blue;
position:relative;
}
.test:after {
width: 20px;
height: 20px;
background: red;
display: block;
position: absolute;
top: 0px;
left: 20px;
}
<div class="test"></div>
Notice how you do not see the pseudo element until you specify the content property:
.test {
width: 20px;
height: 20px;
background: blue;
position:relative;
}
.test:after {
width: 20px;
height: 20px;
background: red;
display: block;
position: absolute;
top: 0px;
left: 20px;
content:"hi";
}
<div class="test"></div>
Why is this the intended functionality? You would think that the display block would force the element to show up. Oddly enough, you can actually see the styles inside web debuggers; however, they do not display on the page.
Here are some references to various W3C specifications and drafts:
Selectors Level 3
The :before and :after pseudo-elements can be used to insert generated content before or after an element's content.
The :before and :after pseudo-elements
Authors specify the style and location of generated content with the :before and :after pseudo-elements. As their names indicate, the :before and :after pseudo-elements specify the location of content before and after an element's document tree content. The content property, in conjunction with these pseudo-elements, specifies what is inserted.
The content attribute
Initial: none
This property is used with the :before and :after pseudo-elements to generate content in a document. Values have the following meanings:
none - The pseudo-element is not generated.
The styling applied to ::before and ::after pseudo-elements affects the display of the generated content. The content attribute is this generated content, and without it present, the default value of content: none is assumed, meaning there is nothing for the style to be applied to.
If you don't want to repeat content:''; multiple times, you can override this simply by globally styling all ::before and ::after pseudo-elements within your CSS (JSFiddle example):
::before, ::after {
content:'';
}
The reason you need a content: '' declaration for each ::before and/or ::after pseudo-element is because the initial value of content is normal, which computes to none on the ::before and ::after pseudo-elements. See the spec.
The reason the initial value of content isn't an empty string but a value that computes to none for the ::before and ::after pseudo-elements, is twofold:
Having empty inline content at the start and end of every element is rather silly. Remember that the original purpose of the ::before and ::after pseudo-elements is to insert generated content before and after the main content of an originating element. When there's no content to insert, creating an additional box just to insert nothing is pointless. So the none value is there to tell the browser not to bother with creating an additional box.
The practice of using empty ::before and ::after pseudo-elements to create additional boxes for the sole purpose of layout aesthetics is relatively new, and some purists might even go so far as to call it a hack for this reason.
Having empty inline content at the start and end of every element means that every (non-replaced) element — including html and body — would by default generate not one box, but up to three boxes (and more in the case of elements that already generate more than just the principal box, like elements with list styles). How many of the two extra boxes per element will you actually use? That's potentially tripling the cost of layout for very little gain.
Realistically, even in this decade, less than 10% of the elements on a page will ever need ::before and ::after pseudo-elements for layout.
And so these pseudo-elements are made opt-in — because making them opt-out is not only a waste of system resources, but just plain illogical given their original purpose. The performance reason is also why I do not recommend generating pseudo-elements for every element using ::before, ::after.
But then you might ask: why not have the display property default to none on ::before, ::after? Simple: because the initial value of display is not none; it is inline. Having inline compute to none on ::before, ::after is not an option because then you could never display them inline. Having the initial value of display be none on ::before, ::after is not an option because a property can only have one initial value. (This is why the initial value of content is always normal and it is simply defined to compute to none on ::before, ::after.)
Based on your comments on others' answers, I believe your question is actually:
Why must the content property for pseudo-classes be set in the CSS, as
opposed to the content of non-pseudo-classes, which may be set in
either HTML or CSS?
The reason is that:
by definition, pseudo-classes are dynamically created for every single element specified by a page's HTML markup
all page elements, including pseudo-classes, must have a content property to be displayed.
HTML elements like <p> do as well, but you can set their content property quickly using markup (or with CSS declarations).
Howver, unlike non-pseudo-class-elements, pseudo-classes cannot be given values in the markup itself.
∴ Therefore, all pseudo-classes are invisible (their 'content' properties have no value) unless you tell them not to be (by giving them value with CSS declarations).
Take this simple page:
<body>
<p> </p>
</body>
We know this page will display nothing, because the <p> element has no text. A more accurate way to rephrase this, is that the <p> element's content property has no value.
We can easily change this, by setting the content property of the h1 element in the HTML markup:
<body>
<p>This sentence is the content of the p element.</p>
</body>
This will now display when loaded, because the content property of the <p> element has a value; that value is a string:
"This sentence is the content of the p element."
Alternatively, we can cause the <p> element to be displayed by setting the content property of the <p> element in the CSS:
p { content: "This sentence is the content of the p element set in the CSS."; }
These two ways of injecting the string into the <p> element are identical.
Now, consider doing the same thing with pseudo-classes:
HTML:
<body>
<p class="text-placeholder">P</p>
</body>
CSS:
p:before { content: "BEFORE... " ; }
p:after { content: " ...and AFTER"; }
The result:
BEFORE... P ...and AFTER
Finally, imagine how you would accomplish this example without using CSS. It's impossible, because there is no way to set the content of the pseudo-class in the HTML markup.
You might be creative and imagine something like this might work:
<p:before>BEFORE... </p>
<p> P </p>
<p:after> ...and AFTER</p>
But, it doesn't, because <p:before> and <p:after> are not HTML elements.
In conclusion:
Pseudo classes exist for every markup element.
They are invisible by default, because they are initialized with no content property.
You CANNOT set the content property for pseudo classes with HTML markup.
∴ Therefore, pseudo-elements' content property must be declared with CSS declarations, in order to be displayed.
Until you add content: ..., the psuedo-element doesn't actually exist.
Setting other style properties is not enough to force the browser to create the element.
2020 Edit
:before
Is syntax from CSS2 for better practices you should write the newest syntax from CSS3 which is
::before
with double semicolons
Full answer and differences can be found here:
What is the difference between :before and ::before?

what does ::before really do?

So I read the docs and probably understand the purpose of ::before and ::after. If my understanding is correct, they should always work in combination with other elements. But the web page I'm looking at has got something like this:
<body>
<div class="container-fluid">
::before
<div> ... </div>
::after
</div>
<body>
I'm not able to understand what ::before and ::after are doing here?
::before and ::after refer to CSS pseudo-elements that are created before and after matching elements.
Pseudo-elements are typically not shown in HTML element trees. However, if you are using the right kind of a debugging tool (like Chrome inspector) you can see these special elements. As its nowadays very common to style a page using pseudo-selectors, it is very useful to have a debugging tool that can display them.
To verify this behaviour from your Chrome inspector (or other capable tool), try adding some content to some of those pseudo-elements with CSS, for instance:
h1:before {
content: 'before';
}
I assume you are seeing that, because chrome inspector shows it for inspection: http://www.youtube.com/watch?v=AcKlJbmuxKo
They are actually not in the original html served from the server but, added by Chrome Inspector there only.
You can use those to view their box model on screen and the styles declared for them.
Also check this: https://stackoverflow.com/a/19978698/774086
::before and ::after are pseudo elements as you can see on this example:
CSS:
.container-fluid>p::before{
content: "HI";
}
.container-fluid>p::after{
content: "Bee";
}
http://jsfiddle.net/vX2jW/
You can read more here: http://css-tricks.com/almanac/selectors/a/after-and-before/

What do ::before and ::after mean?

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.

Layout-neutral tag for CSS?

Is there an "invisible" tag in HTML (4) that I can use to make CSS distinctions
tag.myclass tag.mysubclass h1 { }
without having any visual impact on the HTML rendered?
My background is that I have areas in a form that belong to different groups. As I am opening those in lightboxes (long story involving DOM operations and such, not really important) I don't want to rely on the usual div class=x or span class=y to style the subsequent elements, as I would have to reset margins here, paddings there, and so on.
A layout-neutral wrapping tag would be just what I need in such situations.
No, there is not.
(And that's because such an element wouldn't really fit into the rest of HTML. The only reason DIV and SPAN affect the surrounding area is because they're block and inline elements, respectively. What would an 'invisible' element be? If you need something that's completely independent, absolutely (or relatively) position it and give it a higher z-index.)
If you want to group elements use a div or a span tag as a wrapper element. Apply your id or class to this, and style it accordingly.
EDIT
There isn't an 'invisible' tag - but margins and padding can be easily reset 'margin: 0; padding: 0;'
While all browsers give default styling to many HTML tags, at it's core HTML only describes data, it doesn't format it.
What you're probably looking for is a DIV tag, because no browser gives any default styling to that tag.
I think you want a <fieldset>.
I'd say a span tag is as neutral as they come. I don't think there's any browser that applies a margin nor a padding and it just wraps around it's contents.
I suspect you can use <object> tag without usual attributes for that purpose, but I haven't tested it thoroughly yet. It's even in HTML5 (unlike FONT tag).
The right answer is use a div tag and define a class for it. Here is an example:
<h2 style="font-size: 14px">Project 1 - Project 2
<div class="username">{% if request.user.is_authenticated%} Welcome {{request.user.username}} {% endif %}</div>
</h2>
then in your css file you can have a class like this:
.username {
color:white;
float:right;
padding-right: 100px;
}
voila!! It all belongs to h2 tag but the user name has a different css applied.
You can add display: none; to it. That won't display it (obviously).

Rewrite this code: clickable divs

I'd like to change this:
<a href='foo'>
<div> Moo </div>
</a>
to be standards compliant (you're not supposed to have block elements in inline elements). Wiring javascript to the divs just for navigation seems like a hack and degrades accessibility.. In this case, my requirements are for 2 sets of borders on my fixed-dimension links, so the above non-compliant code works perfectly after applying styles.
Also, is "a { display:block; }" a legal way to circumvent the validation?
Why not use a <span> rather than a <div> and set display:block on both elements?
Additionally, to answer your latter question: I don't believe adding display:block; to your anchor will make it pass validation. The validator checks to see if you're following (X)HTML rules, not how to present the page to the user.
You may want to consider putting the div outside the a if it is only for display purposes, unless it's important that the outer border be clickable. Either this:
<div class="dbl_border_links">Blah text</div>
or this:
<a class="dbl_border_links" href="blah"><span>Blah text</span></a>
will work and you can use something like this:
<style>
.dbl_border_links, .dbl_border_links>* {
display: block;
border: 1px solid;
padding: 1px;
}
.dbl_border_links {
border-color: red;
}
.dbl_border_links > * {
border-color: blue;
}
</style>
to specify the styles. Personally I'd go with the div containing the a but either approach works.
I normally consider the <a > tag to be a special case for this purpose. You ought to be able to apply that to just about anything- it is after kind of the whole point of hypertext (<tr > comes to mind a good example). But if you have to pass a validator somewhere I understand.
Could you use a javascript onclick handler for the div, and eliminate the anchor entirely?
Firstly, there is certainly nothing wrong with giving an anchor display:block; I'd say it's one of the more common things people do with CSS and is perfectly standards compliant. Secondly, there are a number of ways to achieve a double border on an HTML element. For one thing, check out the "outline" property:
http://webdesign.about.com/od/advancedcss/a/outline_style.htm
Admittedly, this will only work in the more modern browsers but should degrade gracefully as the outline doesn't take up any space in the page. If the contents of the link is to be an image you can simply give the <a> a little padding and a background colour as well as a normal border (in another colour) to create the impression of a double border. Or give the image a border of its own. Of course you can also do something along the lines of your original idea, though nesting your HTML the other way around, and simply assigning a different border to each element. Or you can use an inline element inside the link (like a <span> or an <em> or something) which you also set to display:block; (yes, this is also valid!). Happy coding!
If I understand correctly your intentions, you should place, as already mentioned, the div outside the anchor, and, to get the same presentation, make the anchor width:100%;height:100%. Cross Browser milage may vary.
Also, you could dump the div altogether and give the anchor display:block;
What are you exactly trying to do?