Dokuwiki: Use web fonts instead of images

Created on 21 Jun 2015  路  23Comments  路  Source: splitbrain/dokuwiki

In the template I'm working on, I've replaced all the href images, action images (edit, view, subscribe revisions) and editor buttons with a web font I constructed from free icons on icomoon.io. Since the editor icons are tags instead of css backgrounds, I had to override createToolButton() and dw_editor.initSizeCtl().

The result is a cleaner-looking UI (in my opinion) which scales correctly on high-resolution displays, and much faster loading of the editor.

Web fonts work correctly in IE 8 and up, and it might be possible to make them work in IE 6-7 as well if the Doku team still cares about those browsers (which account for roughly 0.3% of traffic in the US and Europe, and a much high percentage in China).

I'd be happy to share the new JavaScript code (it's not complicated -- just add a class to the button objects instead of an img tag). As for icomoon.io, you might have to look into the licensing on various fonts, since some Doku users might have commercial sites.

CSS XHTML JS Browsers Design Template Feature

Most helpful comment

for reference: https://speakerdeck.com/ninjanails/death-to-icon-fonts

I agree with Anika, however svg makes it possible to do:

<a><svg xmlns="http://www.w3.org/2000/svg" width="497" height="470">
<title>Like</title>
<description>'heart' (like) this...  </description>
<g stroke="#f00" stroke-width="20" fill="none">
<path d="M140,20C
73,20 20,74 20,140
20,275 156,310 248,443
336,311 477,270 477,140
477,74 423,20 357,20
309,20 267,48 248,89
229,48 188,20 140,20Z"/></g></svg>
<span class="">like</span></a>

which will then also show properly in Opera mini

the problem here ofcourse is that you have a localized graphic, but the good thing is it has a built-in alternative representation.

All 23 comments

Related issue about high resolution icons: #812

The most recent published template Writr uses also webfonts, so far I have seen:
wiki: https://www.dokuwiki.org/template:writr
code: https://github.com/selfthinker/dokuwiki_template_writr/

Pointers to real code are helpful for discussion, in general. So sharing your fork is welcomed!

Nice to know. My code also replaces editor buttons and link modifiers (external, doc etc). I might extract the code from my template and turn it into a plug-in, so it can be applied to any template, or possibly integrated into Doku core.

As you read in the #812 there is surely interest in the webfonts. Therefore a pull request for implementation in the core is interesting.

But I think an important question to address together with implementing this technical in the core, is how do _we_ and how do _plugin developers_ create the icons for this webfont.

Providing at least good documentation or, even better, tools which cover some of the conversions steps (or whatever is required) is a big plus for switching to the use of webfonts. Do you have experience and ideas on this as well?

There are multiple online tools to create web fonts from SVGs, or from free icon collections, and export them to all the formats needed by various browsers, so customizing the font to fit DokuWiki's requirements would be easy. Templates and plugins would be more difficult, because they'd have to copy Doku's fonts and add their own icons, which would mean that updates to the core fonts wouldn't be reflected in plugins and templates.

I think the simplest solution is just to expose the class names used for these web fonts. For example, an "external link" icon might have class="dokufont externallink". A plugin or template developer could override externallink to point to a new web font or image, or override dokufont to use an entirely new web font for all the icons in the wiki. By including the original font in the font-family, you could fall back to the core font if core adds a few new icons that aren't in the template yet.

Here's an example:

// HTML:
<span class="dokufont externallink">This has an external link icon</span>
<span class="dokufont video">A link to a video</span>

// Core CSS:
.dokufont:before {
  font-family: 'Dokuwiki Web Font';
}
.dokufont.externallink:before {
  content: '\e600';
}
.dokufont.video:before {
  content: '\e601';
}

// Override one icon:
#my_plugin .dokufont.video:before {
  font-family: "My Plugin Font";
  content: '\e699';
}
// Or with an image:
#my_plugin .dokufont.externallink:before {
  content: '';
  width: 20px;
  content: url(whatever.png);
}

// Override the entire set:
.my_template .dokufont:before {
  font-family: "My Template Font", "Dokuwiki Web Font";
}

In my template, I use the trick from the Vector template, detecting file extensions to determine which icon is used. Since the content properties aren't in a central place in this case, it would be more difficult for plugin developers to override without overriding the entire font. However, it could still be done by using a less mixin to define the font family and content values. Plugins could then override the mixin:

// Core less:
.dokufont() {
  font-family: 'Dokuwiki Web Font';
}
.dicon_video() {
  content: '\e601';
}
a[href $= '.avi'], a[href $= 'AVI'] {
  &:before {
    .dokufont();
    .dicon_video();
  }
}

// Override:
.dicon_video() {
  font-family: "My Plugin Font";
  content: '\e699';
}

I don't think the first step is to discuss if the dokuwiki template needs an icon font or not, the first step is to make it easier for any template to use one!

As such, the only problem I came across while using an icon font in the Wrtir template was buttons! It's impossible to style buttons properly of the <input type="submit" value="foo" /> type (because inputs cannot have content). We should consider changing all of such buttons (<button type="submit">foo</button>). I think we only used inputs back then because there were compatibility issues with IE6 and under.

We should collect all of those issues and then open new issues (or PRs) per indentified issue which is preventing people to use icon fonts properly.

Yeah. In my version, I replace the buttons with spans.

Though even in IE 6, you could have used <button> instead of <input type="button">. They behave the exact same way in forms, but <button> is designed to be styled. The only reason you'd ever want <input> is if you want the button's value to be submitted with the form, which is not the case for edit buttons.

If the only goal is to make it easier for templates to use icon fonts, then the solution is to add classes to more elements. I found tons of elements, like the editor buttons, which have specific purposes, but which can't be identified in any reliable way in a stylesheet. This is a simple change with no negative consequences.

I found tons of elements, like the editor buttons, which have specific purposes, but which can't be identified in any reliable way in a stylesheet.

Do you have a list of those elements somewhere?

Which editor buttons do you mean? "Save/Preview/Cancel"? Two of those have IDs and all of them have names. Although those might not the best tools to use for styling, they are sufficient.

The ones I remember are:

  • All of the editor buttons (bold, italic, etc). The only way to identify these is by overriding createToolButton() and referencing them by image url.
  • The resize and word-wrap buttons in the editor. To change these, I had to override dw_editor.initSizeCtl().
  • The instructions above the editor. Since it's impossible for templates or plugins to modify the translation strings stored in text files, I had to add a parent div to the editor, and use the CSS "> p" selector to hide the text.

Save and Preview have ids. Cancel just has a name. This isn't a problem for developers, but it is inconsistent.

Step 1 of many: #1231

FWIW I just saw a presentation which showed how using web fonts for icons are an accessibility issue, specifically for dyslectic people that use their own fonts to improve readability, the suggestion was to use svg, with the added benefit that this also provides to screenreaders because it allows a description as part of the markup.

Interesting.

SVG fixes the scaling issue, but not the speed issue. Loading a row of icons is slow and jarring. I wonder if there's a way to use SVG icons as a fallback when accessibility features are enabled.

I think the main accessibility issue is that you should never use an icon on its own without any further explanation. The minimum should be a title tag, but it's much better to always have the icon only accompany the copy, not replace it. That is also true for other types of graphics.
Consider e.g. the following for liking something:

  1. <a>(heart)</a> or
  2. <a title="like">(heart)</a> or
  3. <a>(heart) like</a>.

When the font is not loading or a special different font overwrites the icons, you will see the following:

  1. "(?)" or whatever an unrecognised character looks like in your case => completely inaccessible
  2. "(?)" but you can see "like" when you hover over it => better, but not very user-friendly
  3. "(?) like" => that might disturb your aesthetics and will look slightly broken to the user but is otherwise very accessible

for reference: https://speakerdeck.com/ninjanails/death-to-icon-fonts

I agree with Anika, however svg makes it possible to do:

<a><svg xmlns="http://www.w3.org/2000/svg" width="497" height="470">
<title>Like</title>
<description>'heart' (like) this...  </description>
<g stroke="#f00" stroke-width="20" fill="none">
<path d="M140,20C
73,20 20,74 20,140
20,275 156,310 248,443
336,311 477,270 477,140
477,74 423,20 357,20
309,20 267,48 248,89
229,48 188,20 140,20Z"/></g></svg>
<span class="">like</span></a>

which will then also show properly in Opera mini

the problem here ofcourse is that you have a localized graphic, but the good thing is it has a built-in alternative representation.

It makes a huge difference what you use the graphic for. If it's just a decoration it should ideally not be in the markup at all (neither as SVG nor as PNG or an extra span for an icon from an icon font) and therefore don't need to attach any meaning to it. In the example of <a>(heart) like</a> it doesn't add anything to the content and is only a visual embellishment, the important thing here is the "like". (And it should only appear once in this case.)

But if the graphic is actually (semantically!) part of the content, it should be in the markup in a way which is accessible. E.g. in I (heart) DokuWiki the heart icon would be essential because otherwise the sentence would not be understood. In that case you'd indeed have the issue of localising this graphic (either within the SVG or as alt parameter if it's a PNG etc) but the other big issue would also be that an icon can mean so many things. In this context the heart means "love", in the previous context it means "like" and not all cultures would understand it as such.

Anyway, I'm still for trying to give template authors the most possible flexibility, so they can use an icon font easily if they choose to. It's still good to educate people whenever possible, but there are much bigger concerns than icon fonts...

So... after playing around with the various icons for #874 and #812... I think I agree that a consistent web font would be a good idea.

The material design icons (https://materialdesignicons.com/) offer pretty much what we need. What is missing can be requested through a submission system, but we could also hire someone to create the missing few icons (thanks to the preexisting guidelines at https://www.google.de/design/spec/style/icons.html#icons-system-icons it should be relatively simple to brief a designer). We might even be able to create simple ones ourselves.

One question would be if we include the whole font or just a subset of what we need. The TTF, EOT and WOFF versions of the whole font are still reasonable small, but still considerably larger than our current icons:

  • MaterialDesingIcons.TTF: 163k
  • current pagetool sprite: 7.6k
  • current toolbar icons: 96k
  • current admin icons: 32k

Including the whole font would give plugin authors a resonable big selection of icons to work with. If we document how to add the CSS you need yourself we could skip the additional 49k of CSS that comes with the full font.

I would probably only choose the WOFF nowadays. Unless you want to support IE8 and under and older Android phones? The WOFF file is only 80k in this case.

I generally like the idea of providing one font in the core which template and plugin authors can then choose to use or not. If that should be the Material Design Icons or not should be up for debate (on the mailinglist perhaps?).
The good thing with most modern OpenSource icon fonts (including this one) is that they come together with their respective SVG sources. So, it would be possible to choose between icon font and SVGs and still stay consistent within the design.

As I mentioned earlier, there are first a few other steps to take before we could do this.
I started to write all the different DokuWiki icon types down, how they are implemented and if they need to change, etc: https://docs.google.com/spreadsheets/d/1QaVOicXMwjrNdwqvz--6vXR4HPK_WDbpvKK9z_So490/edit?usp=sharing
I planned to send an email to the mailinglist about that and/or create a wiki page but couldn't find the time yet.

I started to build a list of icons used in DokuWiki and what icons are available in the Materialfont here: http://www.splitbrain.org/_static/materialfont.html

It's mostly just missing our special header buttons for the toolbar and stuff for the media manager.

I only wondering whether the icons for msg() should have still colors? I think at that place the colors had meaning.

@Klap-in, you can give icons from icon fonts any (single) colour you'd like. Inline SVGs (unfortunately not background SVGs) are even styleable with multiple colours.

Regarding file size, an 80kb web font, or even 163kb for browsers that need it, will be much faster than the current icons. With the current icons, you either need to establish a ton of http connections, which is very slow, or encode all the images as background urls, which is 50% larger.

Oh and if you implement this in core Doku, I'll save you a huge pain I had in my template: font-face CSS (and keyframe, not that it matters for this discussion) must be the first thing in a CSS file, or IE 10+11 will ignore it. This can be addressed by modifying the CSS/LESS compressor to move those to the top.

We already use some sprites and DokuWiki has the cssdatauri option, so the number of HTTP connections is not as bad as it could be.
Regarding file size and fastness, you're right, of course. But I'd also like to point out that you make it sound as if icon fonts are the perfect solution. As far as I'm aware there is no perfect solution to the icon problem!
I'm not saying these should be reasons why we shouldn't use icon fonts, but at least we should be aware of all potential issues, e.g, those mentioned here: http://ianfeather.co.uk/ten-reasons-we-switched-from-an-icon-font-to-svg/ and here: https://www.filamentgroup.com/lab/bulletproof_icon_fonts.html.

A big sprite would solve the connection count problem just as well as an icon font, but we'd need both an svg sprite and a png sprite. Either way's okay with me, since I'm mainly concerned about speed.

While you do use a sprite for the default template, it's not being used for common things like the editor.

Have you considered using a sprite or icon font for smiles? That's one piece I haven't been able to override in my template because of the way smilies are inserted (with no identifying characteristics except their text node).

Was this page helpful?
0 / 5 - 0 ratings