Please consider the following HTML markup:
<label class="required" for="email-address">
Email Address
<span class="audible">Required</span>
</label>
<input type="text" id="email-address" placeholder="Company#address.com">
Along with that I have the following CSS:
.required:after {
color: red
content: "*";
/* ... */
}
When I focus the field a screen reader will read out: Email Address required "star". I'd like to use CSS only to display a visual *, but I don't want that read by screen readers. Is this possible?
Or is this scenario common enough that screen readers and users would ignore the star or adjust the settings. I.e., is this not a real problem?
Try this, it targets screen readers with a media query and hides the star
#media reader, speech, aural {
.required:after {
display: none;
visibility: hidden;
}
}
Update:
As the support for my initial solution doesn't seem to be that good I have thought of a alternative. It occurred to me that the only way to ensure that its not read by a screen reader (w/o extra markup) would be to have no asterisk at all! However you could add a image with css to look like a asterisk like so:
.required:after {
content:'';
display: inline-block;
width: .5em;
height: .5em;
background-image: url(http://upload.wikimedia.org/wikipedia/commons/b/b5/Asterisk.svg);
background-size: .5em .5em;
vertical-align: top;
margin-left: .15em;
margin-top: .1em;
}
http://jsfiddle.net/3a1dvdag/
Gonna throw this out here as there's no final answer highlighted and it's a much discussed topic.
The above solution given by #Sam will be in the near future the best option to go for. No browsers thus far that have the #media aural, speech media query so, if you provide it, it will only work in the near future.
Is there any other way to hide pseudo elements from screen readers?
Yes, with limits. You can use the "private use Unicode character set".
Because the characters are private use, screen readers cannot pronounce them and therefore ignore the character.
If that's not an option try to stick to <span> or <i> elements with aria-hidden="true" on them. It's not as clean as pseudo elements, but at least you have full control of the content.
<button type="button">
<span class="i i-arrow-down" aria-hidden="true">Label
</button>
There's this syntax where one can set the alt text for pseudo elements using slash as delimiter. We can leave it blank to indicate the element should be ignored (the same way it is usually done with img tags), like this:
.required:after {
color: red
content: "*" / "";
......
}
This source indicates there was an 'okay' browser support on 2020. I've tested in Chrome with VoiceOver on MacOS and it works now (as opposed to what the table indicates), so hopefully support may already be very good by now.
https://a11ysupport.io/tests/tech__css__css_generated_content_alt
Right now I think there only exists either workarounds like using a combination of HTML elements and aria-hidden, or limited support from browsers that implement the CSS3 speech module.
Note that this module is still at Candidate Recommandation level, but should provide a more accurate control on what should be read aloud or not.
If browser support was perfect, a good answer would be:
Use CSS3 speech module.
But yeah, this is the Web, and browser support isn't perfect, so I'd recommend using some combination of span with aria-hidden="true" even 4 years after this question was asked.
But one should know that although the aria-hidden property indeed prevents the element content from being read, it also hides its presence to the user. The difference is subtle, but the speak property will not hide the element presence by mentioning it when saying how many children belong to an element.
For instance, let's consider this code:
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>What a beautiful day!</title>
<style type="text/css">
body {
counter-reset: headers;
}
h2::before {
counter-increment: headers;
content: counter(headers, upper-roman);
speak: none;
}
</style>
</head>
<body>
<h2>Early morning</h2>
<h2>Lunch</h2>
<h2>Before dinner</h2>
</body>
</html>
And this is what Voice Over reads for the Lunch element, on a supporting web browser (Firefox 59 here):
It counts the speak: none; element in (pseudo-elements count for one), but doesn't read it alound.
Using aria-hidden leads the element not to be counted at all.
I haven't tried other screen readers, and your mileage may vary.
If you use a separate span for your icon you could apply an aria hidden tag to prevent screenreaders from reading it. I'm not sure what the support is for this though.
<label class="required" for="email-address">Email Address
<span class="icon" aria-hidden="true"></span>
<span class="audible">Required</span> </label>
<input type="text" id="email-address" placeholder="Company#address.com">
More info in the W3C spec
Related
I have a glyph font and want to use it to achieve this effect:
My code so far:
<div class="ico linkedin">linkedin</div>
.ico {border-radius:10em; background:black; color:white}
.linkedin {visibility:hidden;}
.linkedin:first-letter {
font-family:'JustVector';
font-size:900%;
text-indent:1em;
visibility:visible
}
This does the trick in Chrome, but not in Firefox or Internet Explorer 9. Also, this isn't accessible, because JAWS doesn't read the hidden or display:none elements.
So, I tried something like:
.linkedin {position:absolute; left:-5em}
.linkedin:first-letter {/*etc*/ position:absolute; left:6em}
But it doesn't work. Is there a proper and accessible way to achieve this?
The accessible way to use icons is to use img elements with adequate alt attributes, e.g.
<img src=smiley.gif alt="Just joking!">
Icon fonts (which is what you probably mean by “gliph font”) have inherent accessibility problems. Using e.g. letters and trying to fool browsers into rendering them as icons with CSS means that with CSS turned off, there are just the letters, which are wrong information. Using elements with empty content and CSS-generated content suffers from the same problem, except that instead of wrong information, there is no information, when CSS (or at least the visual part of CSS) is off.
I don't think there is a truly accessible way of using icon fonts currently. I know it's a bit span-tastic but this what my approach to this would be.
Firstly wrap the text in a span so we can hide it. And add another span for the icon
<div class="ico">
<span aria-hidden="true" class="linkedin"></span>
<span class="hide">linkedin</span>
</div>
Notice I've added aria-hidden="true" to my icon span. This is to prevent the letter (used to render the icon) from being read out by the screen reader.
Now you can safely hide the text so it is accessible by screen readers and apply your icon using the before selector.
.linkedin:before {
font-family: 'JustVector';
content: 'l';
}
.hide{
position: absolute;
top: -9999px;
left: -9999px;
}
Thanks for the answers, they present me a few questions about how to deal with this.
Well, finally I go with the easy one. I think it's accesible and more semantic, also works if there's no CSS in the page, also it's possible to be printed.
I have separated the first letter (the icon) with a margin of surrounding text, and I left the layer with overflow:hidden;. Then, have adjusted margin and line-height, to focus well the character/icon inside the circle.
The final code:
.ico {background:black; border-radius:10em; height:5em; overflow:hidden; position:relative; width:5em; color:white;}
.linkedin:first-letter {font-family:'JustVector'; font-size:400%; line-height: 1.3em; margin-left:0.2em; margin-right:1em;}
With that solution, screenreaders reads "linkedin" and it only display the icon for other users giving them enough information.
I'm working on a site which has line breaks inserted as <br> in some of the headings. Assuming I can't edit the source HTML, is there a way with CSS I can ignore these breaks?
I'm mobile optimising the site so I don't really want to use JavaScript.
With css, you can "hide" the br tags and they won't have an effect:
br {
display: none;
}
If you only want to hide some within a specific heading type, just make your css more specific.
h3 br {
display: none;
}
Note: This solution only works for Webkit browsers, which incorrectly apply pseudo-elements to self-closing tags.
As an addendum to above answers it is worth noting that in some cases one needs to insert a space instead of merely ignoring <br>:
For instance the above answers will turn
Monday<br>05 August
to
Monday05 August
as I had verified while I tried to format my weekly event calendar. A space after "Monday" is preferred to be inserted. This can be done easily by inserting the following in the CSS:
br {
content: ' '
}
br:after {
content: ' '
}
This will make
Monday<br>05 August
look like
Monday 05 August
You can change the content attribute in br:after to ', ' if you want to separate by commas, or put anything you want within ' ' to make it the delimiter! By the way
Monday, 05 August
looks neat ;-)
See here for a reference.
As in the above answers, if you want to make it tag-specific, you can. As in if you want this property to work for tag <h3>, just add a h3 each before br and br:after, for instance.
It works most generally for a pseudo-tag.
If you add in the style
br{
display: none;
}
Then this will work. Not sure if it will work in older versions of IE though.
This is how I do it:
br {
display: inline;
content: ' ';
clear:none;
}
You can use span elements instead of the br if you want the white space method to work, as it depends on pseudo-elements which are "not defined" for replaced elements.
HTML
<p>
To break lines<span class="line-break">in a paragraph,</span><span>don't use</span><span>the 'br' element.</span>
</p>
CSS
span {white-space: pre;}
span:after {content: ' ';}
span.line-break {display: block;}
span.line-break:after {content: none;}
DEMO
The line break is simply achieved by setting the appropriate span element to display:block.
By using IDs and/ or Classes in your HTML markup you can easily target every single or combination of span elements by CSS or use CSS selectors like nth-child().
So you can e.g. define different break points by using media queries for a responsive layout.
And you can also simply add/ remove/ toggle classes by Javascript (jQuery).
The "advantage" of this method is its robustness - works in every browser that supports pseudo-elements (see: Can I use - CSS Generated content).
As an alternative it is also possible to add a line break via pseudo-elements:
span.break:before {
content: "\A";
white-space: pre;
}
DEMO
For me looks better like this:
Some text, Some text, Some text
br {
display: inline;
content: '';
}
br:after {
content: ', ';
display: inline-block;
}
<div style="display:block">
<span>Some text</span>
<br>
<span>Some text</span>
<br>
<span>Some text</span>
</div>
For that you can just do like this:
br{display: none;}
and if it is inside some PRE tag, then you can and if you want the PRE tag to behave like a regular block element, you can use this CSS :
pre {white-space: normal;}
Or you can follow the style of Aneesh Karthik C
like :
br {content: ' '}
br:after {content: ' '}
I think you got it
As per your question, to solve this problem for Firefox and Opera using Aneesh Karthik C approach you need to add "float" right" attribute.
Check the example here. This CSS works in
Firefox (26.0) , Opera (12.15), Chrome (32.0.1700) and Safari (7.0)
br {
content: " ";
float:right;
}
I hope this will answer your question!!
While this question appears to already have been solved, the accepted answer didn't solve the problem for me on Firefox.
Firefox (and possibly IE, though I haven't tried it) skip whitespaces while reading the contents of the "content" tag. While I completely understand why Mozilla would do that, it does bring its share of problems.
The easiest workaround I found was to use non-breakable spaces instead of regular ones as shown below.
.noLineBreaks br:before{
content: '\a0'
}
Have a look.
Yes you can ignore this <br>.
You may need this especially in case of responsive design where you need to remove breaks for mobile devices.
HTML
<h2>
Where ever you go <br class="break"> i am there.
</h2>
CSS for mobile example
/* Resize the browser window to check */
#media (max-width: 640px)
{
.break {display: none;}
}
Check out this Codepen:
https://codepen.io/fluidbrush/pen/pojGQyM
You can usedisplay:contents
br {
display:contents;
}
see https://developer.mozilla.org/en-US/docs/Web/CSS/display-box
[display:contents;] These elements don't produce a specific box by themselves. They are replaced by their pseudo-box and their child boxes [...] most browsers will remove from the accessibility tree any element with a display value of contents. [...] no longer be announced by screen reading technology.
You can simply convert it in a comment..
Or you can do this:
br {
display: none;
}
But if you do not want it why are you puting that there?
Is there anyway to change a text input's value (the default text that displays) with CSS?
I'm optimizing a site for mobile and I want the text 'search this site' to be shortened to 'search'.
That really isn't what CSS is for.
CSS is for styling your content; HTML is for the actual content itself.
If you need to modify the content after the HTML has loaded, then that's what Javascript is for.
So the real answer to your question is: either modify the HTML directly, or use Javascript.
There are some things you can do with CSS that affect the content, such as adding additional text in-front of or behind an element using the :before and :after pseudo-selectors, but that won't help you in this case, and shouldn't be used for the kind of content change work that you're talking about.
By the way, slightly off-topic, but if you're using input field value as a prompt text, you may want to consider looking into the HTML5 placeholder attribute instead. This also doesn't address your question, but it does sound like it might be something that could be useful to you.
No, CSS cannot change the value attribute of an input, or indeed any attribute of any element.
Late to the party but using "content" attribute, within element:before will accomplish what you need as seen in http://www.w3schools.com/cssref/tryit.asp?filename=trycss_content_string
I was able to manipulate a button content value via jQuery toggleClass, switching between the following classes:
.open_button:before{
content:"open";
}
.close_button:before{
content: "close";
}
I understand the qualms, but I do feel like toggleClass provides an elegance that justifies the CSS trick. Otherwise one would be using a toggle function with nested css switch functions. I personally think avoiding the nested jQuery functions is better looking.
If you want to change the value use the HTML "value" attribute;
example:
<input type="submit" value="ENVIAR">
that will change the default "submit" value to "enviar"
For me the solution was
<button type="submit" class="mybutton" name="add">
<span class="add">Add new</span>
</button>
therefore the css will be :
.mybutton:hover .add:after{content="0"}
This solution is little bit tricky,
but it's always work for me.
/*CSS Code*/
#media screen and (max-width: 768px) {
.showondesktop {
display: none !important; }
}
#showonmobile {
display:none;
}
#media screen and (max-width: 767px) {
#showonmobile {
display:block; }
}
<!--HTML Code->
<div class="showondesktop"> search this site </div>
<div id="showonmobile"> search </div>
When the website is visited from Mobile it will be displayed "search", but when visited from Desktop it will be displayed "search this site".
Image Preview:
Output-Desktop-view.jpg
Output-Mobile-view.jpg
so easy, just type in for example:
button {
color: red;
font-family: sans-serif;
}
there you are,
the buttons take all the inputs with values with for example submit/reset/.etc..
I'm trying to find some uptodate info about various possible uses for content: property in css but only find stuff in the ancients dungeons of the web dating from 2004 orso so I thought I have to ask this in 2011 again:
p:before {
content: url(dingdong.png);
}
p:before {
content: "some text ";
}
I'm very new to both the :before selector as well as the content: property and heard of it accidentally on this question which was answered very creatively by a lovely lady:
How to set Bullet colors in UL/LI html lists via CSS without using any images or span tags
Only to find out that some problems might occur concerning the actual encoding of the content:
li:before{ content: "■"; } How to Encode this Special Character as a Bullit in an Email Stationery?
And so my concrete question is: besides url() and "text", are ther other possibilities?
Thanks very much for your suggestions and ideas.
Oh, too many to list. Some of the most common cases are:
Special numbering, with the counter() function, along with the counter-reset and counter-increment properties
Pure CSS clearfix with:
.foo:after {
content: "";
display: block;
clear: both;
}
Display attributes, eg to print URLs for hyperlinks in a print stylesheet
a[href]:after {
content: ' (' attr(href) ') ';
}
Add typographic ornaments that shouldn't be in the HTML because they're presentational. For example, in my blog, I've used it for the ornaments between posts or sidebar links.
Add icons to hyperlinks, depending on where they point, like
a[href^="http://twitter.com/"]:before {
content: url('twitter-icon.png');
}
Adding a pointer to make a CSS-only speech bubble:
.bubble {
position: relative;
background: silver;
}
.bubble:after {
content: "";
border:10px solid transparent;
border-top-color:silver;
position: absolute;
bottom:-20px
}
And many, many other.
Just beware: If something is not presentational, it should probably be in your HTML. Users will not be able to select CSS generated content, and screen readers will ignore it.
You can also use a counter.
See http://www.w3schools.com/css/tryit.asp?filename=trycss_content_counter
You can also display a certain attribute of the element selected.
See http://jsfiddle.net/EcnM2/
You can also add or remove opening and closing quotes.
w3schools content property list: http://www.w3schools.com/css/pr_gen_content.asp
Generated content won't be perceived by screen readers so beware of accessibility issues.
content is very useful but there are cases where this text should be in the HTML code because it conveys information and isn't only decorative (a bit like background images in CSS vs informative img with a non-empty alt attribute)
:after and content can be used as a clearfix with no extra div
:before and :after bring multiple backgrounds (up to 3 w/ the element itself) to browsers that don't understand the CSS3 feature.
EDIT: forgot about Eric Meyer's article in A List Apart about printing the href attribute of links along with their text with the help of content (it was followed by a JS improvement, fyi)
I would like all "®" on a site to be in superscript. Can I do that with CSS?
AverageAdam's answer will work fine, but if you for some reason wanted a CSS version, you could do this:
.sup { vertical-align: super; }
and
<span class="sup">®</span>
From here.
add this to your html file <sup>your mark here</sup>
then add this to your css
sup {
position: relative;
font-size: 40%;
line-height: 0;
vertical-align: baseline;
top: -1.2em;
}
You can adjust the height of the mark using "top" in the css and the size with "font-size". This will also work for any TM, SM, or symbol you want. It will not effect any of your spacing or typography.
<sup>®</sup>
Unfortunately CSS doesn't have a way to specify superscript's. You can however simulated it using a span and some tags.
Correction 2021: As others have mentioned there are many ways including using CSS. Based on the various options and issues presented in this question I've created a pen to demonstrate options for superscript styling and line-height fixes.
My personal favorite is position:relative since it doesn't require the line-height:0 fix. Thanks #osuthorpe
use the CSS below to create a tag that doesn't mess with your leading. Adjust values as needed. Font-size is optional, I used it to make my r-balls a little smaller than the registered trademarked text.
sup{
vertical-align: 75%;
line-height: 5px;
font-size:11px;
}
I know you asked CSS but this jQuery code worked for me, hope it helps you
<html>
<head>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js">
</script>
<script type="text/javascript">
$(document).ready(function() {
$("body").html(
$("body").html().replace("®", "<sup>®</sup>")
);
});
</script>
</head>
<body>
Some text here ®
</body>
</html>
Victor's answer only worked for the first Reg mark on my page. I found this code to work on the entire page. Hope it helps someone:
$("body").html(
$("body").html().replace(/®/gi, '<sup>®</sup>').replace(/®/gi, '<sup>®</sup>')
);
found it here: http://www.cmexsolutions.com/blog/use-jquery-to-superscript-all-register-marks-reg-or-%C2%AE
I've used the CSS below for positioning the trademark registration symbol ® in HTML whereby the result is the ® symbol with a link, smaller and above the normal text. Note there are two links in the example. The reason for this is because I wanted the main anchor link to be underlined and the ® symbol to be not underlined.
.trademark {
position: relative;
font-size: 40%;
top: -1.2em;
}
.no-style {
text-decoration: none !important;
}
Example with CSS using JSX in React:
Photo Prints Now<a
href="https://www.photoprintsnow.com" className="no-style"><span
className="trademark">®</span></a>
Example in HTML with CSS where the syntax is class instead of className:
Photo Prints Now<a
href="https://www.photoprintsnow.com" class="no-style"><span class="trademark">®</span>
</a>
Example in HTML with STYLE:
Photo Prints Now
<a href="https://www.photoprintsnow.com" style="text-decoration: none; ">
<span style="position: relative;font-size: 40% ;top: -1.2em;">®</span>
</a>
Further to the previous answers, I'd suggest that superscript is presentational rather than semantic, and therefore styling the registration mark should be done using CSS. Whether superscripted or not, a registration mark is still a registration mark, and would be recognised as a registration mark by humans/computers. The symbol itself may be considered semantic, in that it gives a 'special' meaning to the object to which it relates, but the styling of it is entirely presentational. By convention the registration mark is often (but not always) superscripted, as is the trademark symbol.
The only issue with some of the scripts above is that they don't deal with the fact that there might already exist some ® elements on the page. In this case, they will be replaced with: ®.
I think a solution like this might make more sense.
$("body").html(
$("body").html().replace(/<sup>®<\/sup>/gi, '®').
replace(/®/gi, '<sup>®</sup>').
replace(/®/gi, '<sup>®</sup>')
);
if you don't mind using jQuery:
$("p,h1,h2,h3,h4").each(function(){
$(this).html($(this).html().replace(/®/gi, '<sup>®</sup>').replace(/®/gi, '<sup>®</sup>'));
});
it works much faster than modyfying whole body tag (as in Robert's and Victor's answers)
If you are going to use regex, why not clean it up with one call
$("p,h1,h2,h3,h4,h5,h6,li,dd,dt,a").each(function(){
var $this = $(this);
$this.html($this.html().replace(/(<sup>)?(®|®)(<\/sup>)?/gi, '<sup>®</sup>'));
});
I don't recommend doing this on the body like the OP ended up doing. It could interfere with inline javascript that might have the symbol in it.