Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default theme: icon types #109

Closed
oleq opened this issue Jan 28, 2016 · 34 comments
Closed

Default theme: icon types #109

oleq opened this issue Jan 28, 2016 · 34 comments

Comments

@oleq
Copy link
Member

oleq commented Jan 28, 2016

There are 3 different types of icons default theme could use:

  1. PNG (bitmap)
    • Pros:
      • Pixel–perfect.
      • Sprite–ready.
    • Cons
      • A separate iconset needed for HiDPI.
      • Don't scale.
      • Hard to develop and extend, i.e. to change color, a complete re–write (re–render) is needed.
  2. SVG
    • Pros:
      • HiDPI–ready.
      • Easy to develop, it's an XML so it's possible to change colors without dedicated editor.
      • Scale out–of–the–box.
    • Cons
      • Harder to create sprites (but still possible).
      • Sometimes it's hard to make SVGs good–looking in different sizes (pixel–perfect).
  3. Icon fonts
    • Pros:
      • HiDPI–ready.
      • Scale out–of–the–box.
      • Changing color and size with CSS.
    • Cons
      • Rendering problems (pixel–perfect).
      • Monochromatic only.
      • Forcing developers to learn how to create and compile fonts.
      • Hard to extend (adding new glyphs to existing font?).
      • (?) a11y – what about screen readers?
      • (?) user styles – people use browser extensions and stylesheets which change webpage styles (reading mode, fonts for dyslexics), which would break the font icons

Resources:

@fredck
Copy link
Contributor

fredck commented Jan 28, 2016

I would definitely go with a deeper investigation around SVG. It seems to be the best option, especially taking in consideration the benefits it would bring to handle different DPIs and screen sizes.

@Comandeer
Copy link
Member

About icon fonts:

Forcing developers to learn how to create and compile fonts.

Hard to extend (adding new glyphs to existing font?).

Actually it is quite easy to generate font from SVG icons. There is of course gulp plugin for it ;) So by creating SVG icons, we could have both: SVG icons/sprites and icon font (AFAIR Google is using similar mechanism for their Material Icons).

(?) a11y – what about screen readers?

As I said, ligatures could be the answer to that question. It is probably even more accessible than SVG with some ARIA/alternative text, but I don't have any test to prove it.

@oleq oleq changed the title Default theme – icon types Default theme: icon types Jan 28, 2016
@oleq
Copy link
Member Author

oleq commented Jan 28, 2016

Actually it is quite easy to generate font from SVG icons. There is of course gulp plugin for it ;) So by creating SVG icons, we could have both: SVG icons/sprites and icon font (AFAIR Google is using similar mechanism for their Material Icons).

@Comandeer Good to know. But I'm more worried about the color limitations of icon fonts. And there are more questions:

  • How would independent developers provide icons for their plugins (i.e. UI components) if we decided to go with icon fonts? As a separate font? Or as SVGs, which then would be compiled by the builder into a "default icon font" of the editor?
  • How to avoid conflicts between plugins if using icons font? I mean, if each icon is associated with an unique character, then how to make sure there's no collision, when it comes from different sources?
  • How would it be possible to change a single icon in the toolbar (custom one)? Would it mean a re–compilation of the font? Because it's quite easy with PNG/SVG, you just override stuff with CSS.

@fredck
Copy link
Contributor

fredck commented Jan 28, 2016

I think that the "Resources" part of this issue has enough arguments to support SVG over Font.

@Comandeer
Copy link
Member

How to avoid conflicts between plugins if using icons font? I mean, if each icon is associated with an unique character, then how to make sure there's no collision, when it comes from different sources?

If font icon is using ligatures, then icons are connected with words/phrases, not unique characters – so when the font is switched, the text shows up.

How would independent developers provide icons for their plugins (i.e. UI components) if we decided to go with icon fonts? As a separate font? Or as SVGs, which then would be compiled by the builder into a "default icon font" of the editor?

As SVG with builder.

How would it be possible to change a single icon in the toolbar (custom one)? Would it mean a re–compilation of the font?

Well, there is also a possibility to create one-char fonts… ;) But yes, recompilation is probably the most sane way

But I'm more worried about the color limitations of icon fonts.

https://css-tricks.com/stackicons-icon-fonts/ ;) But that's totally insane and should be done with SVG.

@fredck I know that articles and I don't state that icon fonts are better than SVG. I'll rather see the "hybrid" solution: SVG and icon font generated from it. If we're going to switch to one of options, I'd stick to SVG as well.

@fredck
Copy link
Contributor

fredck commented Jan 28, 2016

Maybe I'm missing something. What would the "hybrid" solution solve? Lack of SVG support?

@Comandeer
Copy link
Member

Icon fonts can be better cached, as nearly all nice features that SVG has require to inline it AFAIR. Icon fonts are just easier to use – drop stylesheet and it's done. Fallback for font with ligatures is also nicer than for SVG: it's just plain text. I'd say that icon fonts are better suitable for "light" themes where inlining SVG, probably via Ajax, could be an overkill. Maybe not solving some big issues, but rather a nice added value.

I'm also wondering why Google still recommend icon font for their Material Icons as they provide SVG sprites.

@AlfonsoML
Copy link

The problem with ligatures is that you would need to create a font for each language, or every user would get the same English text and so any potential benefit from that usage goes away.

If someone wants to create a theme using an icon font it would be good if it's possible, but I find that it's hard to justify making the default theme that way.

It's important to think about 3rd party plugins, they will provide their icons and asking them to create a font (or even a SVG icon) might be an extra effort, so it should be possible to keep using png besides the main icons in whatever format you choose to go. At least I would have a very hard time to create a SVG icon for each of the plugins that I have.

@oleq
Copy link
Member Author

oleq commented Feb 1, 2016

I'm also wondering why Google still recommend icon font for their Material Icons as they provide SVG sprites.

Google Docs uses PNG sprites.

@fredck
Copy link
Contributor

fredck commented Feb 1, 2016

May this be related to the file size only? They're talking about 750+ icons after all.

@koleary
Copy link

koleary commented Feb 18, 2016

To take the burden of icon maintenance off of the CK team I recommend using Font Awesome.

In addition to over 500 general icons they have an editor specific set
They have already solved many of the problems discussed above.

If you don't want to implement Font Awesome icons as icon font you can use other tools Node-based like this to generate images at all sizes and change colors.

It's also open-source: https://fortawesome.github.io/Font-Awesome/license/

By the way, a plugin that let users add icons to their content from the font awesome set would also be pretty sweet, and if the library is already in CK that would be pretty trivial I imagine.

@koleary
Copy link

koleary commented Feb 18, 2016

Font Awesome also has some nice solutions for animated icons and for keeping code dry by re-using the same icon for multiple orientations (up, down, left, right).

@oleq
Copy link
Member Author

oleq commented Feb 18, 2016

It's also open-source: https://fortawesome.github.io/Font-Awesome/license/

Open source does not mean compatible with licenses used by CKEditor. AFAIR SIL OFL 1.1 is incompatible with *GPL.

@Reinmar
Copy link
Member

Reinmar commented Feb 18, 2016

I think it was compatible. cc @wwalc.

@wwalc
Copy link
Member

wwalc commented Feb 18, 2016

FortAwesome/Font-Awesome#1124

I have mixed feelings, in general Font Awesome does not provide all the icons we need anyway so I think we'd be much safer with creating all icons by ourselves.

@koleary
Copy link

koleary commented Feb 18, 2016

Why not just contribute those missing icons to font awesome? Seems like much less effort.

@koleary
Copy link

koleary commented Feb 18, 2016

I'm also curious to know which icons font awesome does not have. Their set is pretty massive.

@koleary
Copy link

koleary commented Feb 18, 2016

Just posted this on D.O. Hopefully we'll sees some movement. https://www.drupal.org/node/2139273#comment-10871158

@FinalAngel
Copy link

Contributing icons to or collaborating with FontAwesome would create great freedom for addon developers to just pick an icon from the full set. I would suggest contacting them for collaboration.

@Reinmar
Copy link
Member

Reinmar commented Feb 19, 2016

I don't know how FontAwesome works but what if we wanted some very specific icons for the features that makes sense only for us? I guess we would have to fork FontAwesome because contributing all of them to the official branch of the project would significantly slow us down?

In fact, forking would be necessary anyway, because I find some of the existing icons less readable than ours (I've said this many times so far – @oleq has done a tremendous job designing the current icon set). Perhaps some of our changes would be accepted by FontAwesome, but we cannot be blocked by some rejections.

If this can work and the license thing could be resolved, perhaps choosing FontAwesome would make some sense. It might give us good grounds for building the icon set.

@koleary
Copy link

koleary commented Feb 19, 2016

Update on Drupal license issue:

So far, this has happened:

2014-Dec-03: The LWG was established with the mission "to establish and enforce policies regarding license management for code and related assets hosted on Drupal.org and to communicate those policies to the community at large."
2016-Jan-26: A draft for a revamped Git repo policy (allowing "GPL friendly" font licenses) was published on GitHub.
It is not up to me to decide what happens next, but I presume it would be some variation of this:

The LWG officially announces that it recommends that Drupal.org adopt this new policy.
The community is invited to comment on this recommendation.
The result of this process (i.e. the policy proposal, which may include amendments requested by the community) is put before the DA and Dries for final approval.
The Git repo policy is changed.
Unfortunately, no dates have yet been set for getting the new policy officially announced, discussed and approved - and therefore I cannot give you an expected TOA.

Presumably if the Drupal LWG can work out an adequate compromise position then other GPL V2 projects may be able to as well.

@AlfonsoML
Copy link

Another little company that moves away from icon fonts: https://github.com/blog/2112-delivering-octicons-with-svg
Do you want to release CKEditor 5 with a technology that is seen as a hack of the past?

@fredck
Copy link
Contributor

fredck commented Feb 24, 2016

Much probably having font icons from an external source (like Font Awesome) is definitely a great idea. In the other hand, the way we deliver them still need to be defined as SVG may be a better fit. Therefore, if we are able to easily transform font icons into SVG we may have found the best approach for this.

@Reinmar
Copy link
Member

Reinmar commented Feb 24, 2016

I've never liked font icons myself simply because I don't like hacks. So I would vote for SVG.

As for Font Awesome, it's definitely useful if you can easily take icons from a nice library which Font Awesome is. We could have some tools which let's you use the icon font as a source of icons for the editor (or your editor feature which you develop). I'd guess though that there must be some nice SVG icon libraries as well. So if we'll go with SVGs, what does Font Awesome give us (other than headaches with the license :D)?

@fredck
Copy link
Contributor

fredck commented Feb 25, 2016

So if we'll go with SVGs, what does Font Awesome give us (other than headaches with the license :D)?

An extensive icon set which is extremely popular and hopefully well maintained in the long run. But ofc, any other library matching that same criteria would work.

@Comandeer
Copy link
Member

So maybe Material Design Icons? They're already in SVG format.

@koleary
Copy link

koleary commented Feb 27, 2016

@Comandeer

Sure, that is certainly going to be a well maintained repo. :) I have no particular loyalty to Font Awesome, my only points were 1. Recognition through ubiquity, and 2. Offloading tech debt, and Material certainly addresses both.

@oleq
Copy link
Member Author

oleq commented Mar 3, 2016

After some research I came up with an idea to use <symbol>–driven SVG sprites.

Details

The whole trick is that separate SVG icons

src/theme-default/assets/
├── align-center.svg
├── align-left.svg
├── align-right.svg
├── bold.svg
├── bulletedlist.svg
├── image.svg
...

are compiled into an inline SVG sprite which is injected into DOM:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="ck-sprite">
    <symbol viewBox="0 0 20 20" id="ck-icon-align-center">
        <title>align-center</title>
        <path d="M16 10v1H4v-1h12zm-1 6v1H5v-1h10zm3-3v1H2v-1h16zm-2-9v1H4V4h12zm2 3v1H2V7h16z" fill="#444" fill-rule="evenodd"/>
    </symbol>
    <symbol viewBox="0 0 20 20" id="ck-icon-align-left">
        <title>align-left</title>
        <path d="M3 10v1h12v-1H3zm0 6v1h10v-1H3zm0-3v1h15v-1H3zm0-9v1h12V4H3zm0 3v1h15V7H3z" fill="#444" fill-rule="evenodd"/>
    </symbol>
    ...
</svg>

Then a simple reference in HTML inserts the actual icon, i.e.:

<a href="#" class="ck-button">
    <svg class="ck-icon ck-icon-left">
        <use xlink:href="#ck-icon-align-center"></use>
    </svg> 
    Align center
</a>

The working example is in https://github.com/ckeditor/ckeditor5-design/tree/theme-architecture branch:

image

Advantages

The solution combines all the advantages of SVG backgrounds (CSS background: url( ...)) and icon fonts. The icons can be monochromatic, colorful and/or follow the color specified by CSS. Responsive scaling is also possible. The "compilation" (aggregation?) is pretty easy using https://github.com/jkphl/svg-sprite/ (https://github.com/jkphl/gulp-svg-sprite).

Unlike inline SVGs, generated SVG sprite is injected in DOM only once. Inserting an icon is pretty cheap (<svg><use xlink:href="#id"></use></svg>) and changing the icon from code is possible using setAttribute( 'xlink:href', '#new-id' ) on <use> Node.

I checked Chrome, Firefox, Safari (also iOS) and Edge and it seems that <symbol> works out–of–the–box.

Disadvantages

?

Future and MVC

The idea is that icon might become

  • a separate component (i.e. Icon component inside Button)
  • an internal logic of relevant components (like ButtonView, ToolbarView, etc.).

In the first approach, IconView has a Model, which drives the state of the icon, so i.e. switching from LTR to RTL icon is possible by changing IconView#model.name attribute. The disadvantage of this approach is that is bloats the memory with additional IconView+IconController pair for each icon used in the UI.

The later approach assumes that ButtonView.model.icon attribute is responsible for the state of an icon. However, it also indicates that each component must implement an interface for icons (toolbar, dropdown, etc.). I'd rather not go this way because it also means that it's quite impossible to use standalone icon not related to any UI component. On the other hand, IconView+IconController could be separate classes for standalone icons only while Button and similar would use internal interfaces to display and manipulate icons.

Either way, controlling icons with View#model attributes is what I'd like to use to handle LTR/RTL and more complex states (like text color icon following the actual color of the text).

@Reinmar
Copy link
Member

Reinmar commented Mar 3, 2016

Great job! Symbol-driven SVG sprites look great.

As for MVC, I'm for a separate component. This will allow replacing SVG icons with any other icons just by replacing that one component's view.

@Comandeer
Copy link
Member

are compiled into an inline SVG sprite which is injected into DOM:

Maybe we can consider external SVG? https://css-tricks.com/svg-use-with-external-reference-take-2/ The only big problem with it is probably lack of decent CORS support: https://bugs.chromium.org/p/chromium/issues/detail?id=470601

@oleq
Copy link
Member Author

oleq commented Mar 3, 2016

@Comandeer Though it looks nice (because there's no need to inject SVG into DOM) it would generate additional HTTP request IIRC, wouldn't it? The main advantage of direct injection into DOM handled by JS with pre–generated SVG string it that is spares us that request.

@Comandeer
Copy link
Member

Yes, it would generate additional request, but actually it can be very useful.

Inlining resources is an optimization technique good mainly for HTTP/1.x. Currently HTTP/2 is gaining popularity and with it that kind of resources can be pushed to the client – it's something like "server-side inline". But that kind of "inline" could be also cached ;) And changed on the fly. Inline SVG is bound to the build process AFAIK.

@Reinmar
Copy link
Member

Reinmar commented Mar 3, 2016

  1. http://engineering.khanacademy.org/posts/js-packaging-http2.htm. If I remember correctly:
    • turned out that combined size of gzipped files is worse than size of a combined, minified and then gzipped file because in the latter case the compression dictionary has more time to grow
    • HTTP2 servers have performance issues
  2. HTTP2 is still out of the scope of many developers in their environments

I would like to not think of bundling myself, because this gave me huge headaches when I've been thinking about ES6 modules, but so far bundling is must-have.

@Reinmar
Copy link
Member

Reinmar commented Apr 20, 2018

Cleaning up old discussions. See #186.

@Reinmar Reinmar closed this as completed Apr 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants