I have an element
<div class="Test_then">The result is ...</div>
The Test_then class looks like this:
.Test_then::before {
content: 'Then';
}
My goal is to have the (The result is ...) appear below the Then content added by the Test_then class. So in other words in would render like this:
Then
The result is ...
If your generated content simply consists of the word "Then" inline, you can just add a newline with \a, and use white-space: pre-wrap (or pre) to cause the newline to render as an actual line break:
.Test_then::before {
content: 'Then\a';
white-space: pre-wrap;
}
An example of this is also provided in the spec.
If your generated content needs to be displayed as a block for any reason, then it becomes even simpler — display: block alone will have the same effect:
.Test_then::before {
content: 'Then';
display: block;
}
Related
I am using :before pseudo-elements bound to particular classes to add symbols in front of p tags, with CSS like this:
td > p.markerclass1:before {
position: absolute;
left: -1rem;
content: '*';
}
I am using this in a Wordpress theme where the user can select that class for a p tag in the editor, in order to to put that symbol to the left of the current paragraph.
However, the website should be accessible, and the screenreader (at least NVDA, with which I am testing this) is reading that pseudo element and the included symbol, which I don't want. But since this element is not in the HTML code, I cannot add aria-hidden = 'true' to hide it from screenreaders.
Any idea what i could do to get the screenreader to ignore those pseudo-elements?
Know this is old, but recently had to answer this too and eventually found a better answer to this question
pseudo-elements; alternative text can be indicated after a /:
td > p.markerclass1:before {
position: absolute;
left: -1rem;
content: "*";
content: "*" / "";
}
In this case the blank alt text will cause this content to be ignored.
Note not all browsers support this syntax (basically just Chromium based browsers at this time of writing) so make sure you add a fallback first that works for all browsers and is only overridden by those that support this new syntax as well. Otherwise, without this fallback, browsers like Safari just ignore the unrecognised CSS line and fail to display anything when you use an / for alt text!
You can try using the speak property:
CSS:
td > p.markerclass1:before {
position: absolute;
left: -1rem;
content: '*';
speak: none;
}
Pseudo-element inheritates from the main class their visibility for screen and screenreaders.
For instance, the following code will hide everything including the *
p:before {content:'*'}
p {display:none}
If you want the content of the pseudo element not to be read, you have to use an unprounounceable replacement like an UTF-8 equivalent :
td > p.markerclass1:before {
position: absolute;
left: -1rem;
content: "\2022";
}
EDIT: \2022 announces "bullet" with NVDA while another code like \2023 for instance announces nothing
The scenario was "Send Mail" link associated with "Click Here To" text, but Screen Reader reads the whole text, but i want it to read only "Send mail".
Here i have solved that issue using "aria-label" attribute.
a
{
text-decoration:none;
}
a::before
{
content:"Click here to - ";
color:Black;
font-weight:bold;
}
Send Mail
Hope this will work for you guys.
As part of some performance testing, I want to see how many DOM elements there are within a page at any given time.
Initially I used the console and manually typed: document.getElementsByTagName('*').length
But being that elements are dynamically added and removed, I wanted a way to show this automatically without having to do this manually.
Using CSS counters seemed to be the easiest way for me to do this:
(Here's a demo: see the yellow box in the top right)
html {
counter-reset: elems;
counter-increment: elems;
}
html * {
counter-increment: elems;
}
body:after {
content: counter(elems) ' elements';
position: absolute;
top:0;
right: 0;
padding: 0.5rem;
background-color: yellow;
z-index: 1000000000; /* make sure display appears on top */
}
html + head + body = 3... +
A section with 4 divs = 5..... 3 + 5 = 8
<section>
<div>div1</div>
<div>div2
<div>div3</div>
</div>
<div>div4</div>
<section>
The problem is that this technique is not working for some more complex websites, and i'm guessing that it's because it's somehow naive.
Take for instance wikipedia's main page - I used the browser inspector to add the above css-counter css and that produced "888 elements"
However when I used the console document.getElementsByTagName('*').length - it returned 975 elements.
So my question is:
What is causing this huge discrepancy in the number of DOM elements, is there something I haven't taken into account?
Can this be done reliably with CSS?
The reason you get different counts is because your counter-increment: elems; rule is lower priority than some existing counter-increment rules in Wikipedia's stylesheet, so there are elements which increment other counters (one example is named "listitem") but not yours.
You'd have to make your selector more specific and override Wikipedia's, or add the website's own counter (or write some JavaScript to add your own counter in the existing counter-increment rules, to avoid breaking the existing style).
What is causing this huge discrepancy in the number of DOM elements,
is there something I haven't taken into account?
Yes, elements which have display:none applied are ignored by css counters.
From the spec:
An element that does not generate a box (for example, an element with
display set to none, or a pseudo-element with content set to none)
cannot set, reset, or increment a counter. The counter properties are
still valid on such an element, but they must have no effect.
Demo:
html {
counter-reset: elems;
counter-increment: elems; /* Include the html element as well */
}
html * {
counter-increment: elems;
}
body:after {
content: counter(elems) ' elements';
position: absolute;
top:0;
right: 0;
padding: 0.3rem;
background-color: lightyellow;
z-index: 1000000000; /* make sure display appears on top */
}
.hidden {
display: none;
}
html + head + body = 3... +
A section with 4 divs = 5..... 3 + 5 = 8
<section>
<div>div1</div>
<div>div2
<div>div3</div>
</div>
<div>div4</div>
<div class="hidden"></div>
<div class="hidden"></div>
<div class="hidden"></div>
<div class="hidden"></div>
<div class="hidden"></div>
<div class="hidden"></div>
<section>
On the other hand document.getElementsByTagName('*').length WILL count elements with display:none
This may only be one of the differences which I hadn't taken into account, but I'd say it's probably the main culprit as to the discrepancy.
For example, something like:
HTML
<p>text</p>
CSS
p:before {
content: " 1";
}
p:before:before {
content: " 2";
}
Which would end up with something like this:
text 1 2
If this isn't possible, is there any way to emulate the same effect?
In my project I have the original text content hidden with font-size:0 and added coloured text in it's place with the :before pseudo-selector.
However, it's 2 words, so I'd like to be able to add more content AFTER the generated content to change the colour.
The "GLB Guide" is generated using :before, but I'd like to be able to make both words different colours.
Hope that made sense!
You want something like following which make you text with two different color:
p:before {
content: " GLB";
color: red;
}
p:after {
content: " Guide";
color: blue;
}
<p></p>
I would like to replace horizontal line rendered by default by the <hr> tag with three asterisks (horizontally centered). If possible, I want to achieve this with pure CSS, specifically:
I don't want to touch my markup, there should be just plain <hr>, no helper divs or anything like this (because I'm styling Markdown files);
no background images;
no Javascript.
First I tried:
hr {
width: 0;
}
hr:before {
content: "***";
}
and it almost does the trick, but I want it centered, and have no idea how to center it.
Browsers display <hr>s using borders, so:
hr {
border: none;
}
hr::before {
content: '***';
display: block;
text-align: center;
}
Slap a text-align:center on your psuedo-element.
I have tried to use display: run-in in order to create a semantic and nice-looking metadata name-value list, liks this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Run-in description list test</title>
<style>
dt {
font-weight: bold;
display: run-in;
}
dt:after {
content: ": "
}
</style>
</head>
<body>
<dl>
<dt>Subject</dt>
<dd>A Question</dd>
<dt>From</dt>
<dd>Mr Smith</dd>
<dt>Time</dt>
<dd>2013-08-05</dd>
</dl>
</body>
</html>
The expected result is
Subject: A Question
From: Mr Smith
Time: 2013-08-05
You can watch it live. (Actually, the idea to use display: run-in was given to me by Ian Hickson, after I started nagging about the di element from XHTML 2.0. One alternative is to use float, but that comes with a number of difficulties.)
Until recently, this worked wonderfully in every modern browser except Firefox (that is, it worked perfectly in Internet Explorer, Google Chrome, Opera, and Safari (I think)). But very recently I discovered that it doesn't work in Google Chrome anymore.
Question: Has Google Chrome dropped support for display: run-in? Is there an alternative that works the same way?
I'm not aware of any change to Chrome's support of display:run-in but the setting has always seemed unloved.
Hixie has been consistently opposed to <di> and I kind of understand why. HTML is a semantic language and the semantics are fully defined by dl/dt/dd. The only practical problems are presentational, and that makes it a CSS problem, not an HTML one.
Unfortunately, then current state of CSS doesn't seem up to the job. For dl/dt/dd, and for many similar problems, we really need a mechanism for wrapping groups of elements in a pseudo element which could then perform the role of the <di>.
Obviously, there is no current setting that does what display:run-in is supposed to do. Having said that, in your specific test case, you could achieve the same effect with this CSS:
dt {
font-weight: bold;
display: inline;
}
dt:after {
content: ": ";
}
dd {
display: inline;
margin:0;
}
dd:after {
content:'\0A';
white-space:pre;
}
I'd like to offer a different, more explicit approach to the solution. One that can be extended to a more general case of missing display:run-in behavior.
I.e. I'm using h4->p flow-in transition to compose a nicely formatted list of item properties:
h4 {
font-weight: bold;
display: inline;
}
h4::after {
content: ": ";
}
h4 + p {
display: inline;
}
h4 + p::after {
content: '\0A';
display: block;
}
Here, I'm using "immediate sibling" (+) CSS selector to select p elements immediately preceded by h4 elements. If h4 is followed by any other element, it will be displayed following the normal flow.
An alternate selector ~ will select not one but all elements of the said type, which is not what usually expected from run-in behavior, and will also extend to all tags of the same type in current scope regardless of the other intermixed tags, which could break the layout completely.