Display first letter only for glyph fonts (accessible way) - css

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.

Related

In CSS, granular control over where word wrapping occurs?

TL;DR: Wondering if there's a CSS property that can break content where HTML doesn't naturally:
Baby
Buggy Bumpers
instead of
Baby Buggy
Bumpers
The only way I can think of to do it is to add where you don't want the line to break, but I'm working in WordPress, which strips those.
This is to graphically style a site's name on the home page. The site name is part of the nav, so it's inside an <li>, using grid layout.
Luckily in my case, setting the width with a dimension that is relative to the font size seems to break the way I want at all viewport widths:
.my-brand a {
width: 16ch;
text-align: end;
}
white-space: nowrap and such elements won't work with the "baby buggy bumpers" example because the need is to break after one specific word. Just wondering if there's some way to specify in a way similar to nth-child(2).
Made a Codepen to play with.
If you can't use Javascript and can't add tags in the string like :
<div class='string'>
Baby<span>Buggy Bumpers</span>
</div>
It only remain "hacky" CSS solution. There is one using pseudo-elements :
HTML :
<div class='string'>
Baby
</div>
CSS :
.string{
width: 11ch;
text-align: end;
font-size: 2em;
}
.string::after {
content: "Buggy Bumpers";
color: red;
display:block ;
white-space:nowrap;
}
Live exemple : https://codepen.io/camillewemajin/pen/JjWzWzN
But that's not really clean for many reasons, like SEO...

Why use :before pseudo-elements to display glyph icons?

This question is haunting in my brain for a long time. Seem like all glyph icon libraries provide icon by this way, such as Font Awesome. Is this the only way to put glyph in css? or is this the best way?
a:before {
font-family: FontAwesome;
content: "\f095";
}
I feel this question can be divided into two separate ones:
Why use fonts for icons?
Why use :before pseudo-elements to display them?
For the first part, reasons are many, but it boils down to being easy to work with (as they are vectors, have transparent backgrounds by nature, can change colours easily) and had very good support even on older browsers.
For the second part, using pseudo-elements means that your icons can fully "live" in your CSS file. Apart from it being easier to edit there, that's also where they belong - they are not part of your content, but are rather something that affects the appearance of it and thus shouldn't be in your HTML. Think of it as the same distinction as between img tag and background-image CSS property (once again - design vs content).
In addition, this prevents some strange side-effects, for example, pseudo-elements can't be selected and thus can't be copied. If this weren't the case, all icons would, when copied, result in strange characters in the destination where you copy them.
You can also use them as 'i' tags. we can apply much more creative css that way. Here's a codepen:
http://codepen.io/anon/pen/gLdYqj
<script src="https://use.fontawesome.com/2d1d8af5b4.js"></script>
<div><i class="fa fa-user"></i></div>
div{
font-size:50px;
}
i{
color:blue;
}
i:hover{
color:red;
cursor:pointer;
}

How to do CSS text replacement using generated :before or :after without absolute positioning?

I'm attempting to allow our CMS editors the ability to swap out the text used for a page title using only a css override.
<header data-alternate="An Alternate Title">
This Page's Default Title
</header>
Using the :before or :after tag, one could use one of many available alternate titles.
header:before {
content: attr(data-alternate);
display: inline-block;
}
If only we could also say,
header:text {
display: none;
}
Unfortunately, as far as I can tell, there is no good way to hide "This Page's Default Title" in order to replace it with "An Alternate Title". If this were a Sprite, we could use one of the well-worn image replacement techniques like Phark or otherwise. Not so much with text replacement generated by :before, because the :before is also affected by the CSS devices used to hide the default text so that, with Phark, for example, the :before content is also at -9999px.
There are solutions I'm trying to avoid.
Using the Phark method or somesuch to hide the default text and then using absolute positioning on the :before content to put it back at left: 0, top: 0. I want/need to preserve flow if possible.
Wrapping the "Page's Default Title" in a span and just setting it to display: none in the CSS when an alternate title is being used.
i.e.
<header data-alternate="An Alternate Title">
<span class="default">This Page's Default Title</span>
</header>
This works, but a span nested in a header is displeasing.
Is there a way to target a tag's text without also targeting its generated :before/:after content? Is there another way to do this?
I'm not sure if this is exactly what you want, but you could try something like this:
p {
visibility: hidden;
}
p:before {
content: attr(data-alternate);
display: inline-block;
visibility: visible;
}
http://jsfiddle.net/yJKEZ/
You can set the visibility of the p element to be hidden, and then set the visibility of the :before pseudo-element to be visible within it's parent (the p) despite it's setting.
If that doesn't quite work as expected, there isn't really anything tremendously wrong with adding an extra span in, to help the process. It might not be as clean, but it could work better.
I do, however, want to raise the question of why you might need to do this, and point out some concerns with an approach like this...
For starters, pseudo elements are not part of the DOM, so that alternate text can't be selected, and isn't as accessible to the browser (or the user). Screen readers or search engines will see the default text, and not pay any attention to the alternate text, but that's what your user will see... This could lead to some confusion.
While your question specifies that you want to be able to do this with CSS, and while it may be possible, it really isn't the best solution for doing something like this. Especially if your website is being viewed in an older browser which does not support pseudo elements (Now the user sees nothing at all!).
I would more recommend something like this for swapping an image out for alt text in a print stylesheet, or swapping a hyperlink's text for the full address that it links too (again, mainly for a print stylesheet). Changing important content like a heading in this fashion can cause a lot of other issues, especially in terms of accessibility.
Just something for you to consider along with my answer... I hope I've helped you with your problem!

CSS: is it possible to scale the image in a :before {content:url(..)} element?

ok, I admit I'm in the realm of playing around now...
What I want to achieve:
there should be a plus sign before utility links that are used to add some elements in our web application.
It would be good if this sign scales according to the font size the user has set.
What I've tried:
<style type="text/css">
a.addLink:before {
content: url('images/add.png'); height: 1.2em;
}
</style>
<a class="addLink" href="#" onclick="freakyJSFunction">testlink</a>
sadly, the height attribute is ignored.
I know i could just insert a normal <img../> before every link, but that's not as maintainable as we want it to be.
Or I can use one of the fancy unicode characters, for example
content: "\271a"; font-size:1.4em; color:green;
for now, I'll go with the unicode idea (just tested this in IE8...nope, IE 8 doesn't display that character ("greek cross")...:-( )...ok, I will go with the unicode idea if I find a suitable charakter that is displayed in IE8, FF and maybe chrome..
still, I wonder if my initial idea is somehow doable
In css3 you have a background-size property.
http://jsfiddle.net/jQgQv/7/
However background-image can't be applied trough content: so it won't work in your case using :before - only as a normal class.

What is the standard way to add an icon to a link with CSS?

I'm used to use padding + background-image to place an icon next to a link.
There are many example of this approach. Here is one from here:
<a class="external" href="http://www.othersite.com/">link</a>
a.external {
padding-right: 15px;
background: transparent url(images/external-link-icon.gif) no-repeat top right;
}
But most browser don't print background image, which is annoying.
What is the standard to place icon next to links which is semantically correct and works in all cases?
EDIT
What about CSS :before and :after? Is it a recommended practice?
a.test:after {
padding-right: 5px;
content: url(../pix/logo_ppk.gif);
}
I'd personally pad it and put a background image via a CSS class (just like your example). It's by far the lightest route, it keeps the document light and semantic.
If printing them really matters (and I do mean really matters) stick a real image in there but be aware that it does screw up markup from a semantic aspect.
Perhaps a better compromise solution would be to have a "printable version" which uses images instead (either by something server-size or some JS that replaces the CSS class with an actual image.
Although as OLi saying keep icon in css is best method and there is no way to print css backgrounds. (until you turned on css background printing from browser settings).
but if you can use javascript then this method will work for you
http://www.learningjquery.com/2008/08/quick-tip-dynamically-add-an-icon-for-external-links
you can add inline image to link.

Resources