Drupal uses icons in many places in its administrative UI, but provides no theming mechanism to render such a common UI element. For example:

  • The new toolbar introduced custom icons
  • Action links have been visually emphasized with custom icons in core themes since D7, implemented in a different way.
  • Our refactored buttons markup and CSS allows for icons, but we don’t want to invent yet another way of doing the same thing.

Proposed resolution

Provide theming infrastructure for displaying icons in a consistent, accessible way while not limiting the exploration of this space in contrib modules and themes. Adding, changing or removing actual icons is out of scope for this issue.

Markup in common use today (Twitter Bootstrap, Zurb Foundation) has stabilized. A definitive exploration including accessibility implications was done at CSS Tricks. We should adopt this markup pattern as a sensible default:

<!-- icon used with a visible label, e.g. icons inside a button -->
<i class="{{ classes }}" aria-hidden="true"></i> Icon label

<!-- icon used with a hidden, but accessible label, e.g. contextual edit icon -->
<i class="{{ classes }}" aria-hidden="true"></i> <span class="visually-hidden">Icon label</span>

Displaying the icon itself would be left to CSS, which can use:
- CSS background images (jpg/png/gif/svg, single or sprite)
- CSS generated content to insert icon font glyphs

Whatever infrastructure is chosen, it should be extensible or overridable to allow less-common techniques using <img>, <svg> or others to be used without much difficulty.

We should consider merging all or key parts of the existing Icon API module to solve this issue.

Remaining tasks

Blocked by:
#939462: Specific preprocess functions for theme hook suggestions are not invoked
This issue are critical in allowing this new icon theme hook the ability to extend itself for various types of icons:
icon__css or just icon as a fallback?

  1. Determine if and how to merge Icon API module with core.
  2. (Note: The following may be solved by the previous item)
  3. Determine what classes are required to potentially support icons of different types/sizes or different sources on a single site
  4. Determine how CSS and assets (images, font files) are attached to the page with the icon markup.
  5. Determine the API changes requied to render the icons: theme function(s) or other machanisms.
  6. Write and test a patch.

User interface changes


API changes


#956520: Available theme hook suggestions are only exposed when there are preprocess functions defined
#2004872: [meta] Theme system architecture changes
#1804614: [meta] Consolidate theme functions and properly use theme suggestions in core

Original report by @sun


  • Drupal is a user-facing application framework, but provides no way to achieve a consistent iconic language.
  • The new toolbar introduced custom icons, completely detached from the rest of the application.
  • Action links have been visually emphasized with custom icons in core themes since D7, implemented in a completely custom way.
  • Our refactored buttons markup and CSS allows for icons, but we don't a have framework for that.
  • Previous efforts to add icons to Drupal failed, because there is no theme/markup framework for handling icons in a consistent way.


  • Implement a theming function/template/infrastructure to handle icons in a consistent, application-wide way.


  • Adding actual icons to Drupal core is NOT within the scope of this issue.

    Any comment which proposes that will be unpublished. This issue is about icon infrastructure, not actual icons.


  • There's absolutely nothing to re-invent here — the web design community beyond Drupal has figured this out in a clean, standardized, and universal way already.
  • Various web services exist to auto-generate icons as icon fonts, including the necessary CSS (e.g., Fontello).
  • Framework themes like Bootstrap follow the standard, too.

Proposed solution

  • Merging in Icon API module - This provides the necessary markup and API for theming icons from various providers.

Related Issues

#32 theme_icon_1849712_32.patch1.05 KBry5n
PASSED: [[SimpleTest]]: [MySQL] 55,804 pass(es). View
Members fund testing for the Drupal project. Drupal Association Learn more


ry5n’s picture

Generically, the markup I’d like to see would be something like this:

<i class="icon icon-cog">Cog</i>

Where the content of the i tag is hidden via text-indent or similar CSS. But I really don't know how this markup should be produced. Twig macros come to mind, or a function like l(); either way, this may not need to go through the theme layer. I'm really curious to see how others would like to implement this.

I'd also like to see this solution support both icon fonts (my preferred approach) and sprites (useful when icon fonts aren't appropriate) and allow using both in the same theme.

cweagans’s picture

-1 to having anything inside the i tag. Screen readers will read that, won't they?

I'm very much in favor of handling this exactly as Bootstrap does it.

ry5n’s picture

@cweagans It depends on whether you want screen readers to read the icon or not. In cases where the icon is used with a visible equivalent word, you're right, we can leave the i tag empty (and possibly use aria-hidden=true). If used alone, however, it should be audible. Actually I'm not sure my suggestion in #1 is a good solution to that. Some food for thought from Chris Coyier on this:

I don't really like his solution to the second use-case, it seems awkward to me with two separate elements.

I want to keep an eye on the overview here, too. What are the bare fundementals we need to support core and contrib? Base markup? Any CSS or classes at all? How to call this in templates?

sun’s picture

I don't see a difference between @ry5n's suggestion in #1 and what Bootstrap is doing.

  • The <i> markup technique is part of the common approach. It can be used to output an icon as a standalone element.
  • Screen-readers do not give special meaning to the <i>, because like <b>, the HTML element has visual meaning only.
  • For stand-alone icons without label, Chris Coyier's 3rd technique works. It boils down to <i class="icon-foo"><span>Accessible label</span></i>.
  • Note that pretty much all usability gurus across the board discourage usage of stand-alone icons though, because there is hardly an icon that has a truly universal meaning for all users and languages around the world. Usability studies commonly arrive at the same conclusions: Always use a compound icon + label, and don't over-use icons. Recommended reading: UX Exchange, UX Myths, etc.pp.
  • The .icon-* classes can also be used on other elements though. However, since the icon is injected via :before, it is not always possible to achieve the desired styling on other elements. Whether this works usually depends on other factors, such as font-size, line-height, paddings, and margins. Thus, it can typically work very well on simple links. But not necessarily on buttons, etc. For Drupal, it might be too risky to apply icon classes on other elements.

Regarding the overview/fundamentals:

  1. We need to decide on which markup to use for the two main cases of 1) iconic labels and 2) stand-alone icons. The latter has to be accessible.
  2. Drupal is modular and extensible, so we cannot use an icon font by default (unless we're able to merge individual glyphs into various web font formats via PHP), and need to use images (potentially SVG) instead. Due to how this standard icon pattern works, this does not prevent anyone from replacing the CSS with an icon font on your own site though. That's important.
  3. I personally thought of introducing the markup/CSS infrastructure as a tool only, leaving the actual implementation to either pure HTML strings, and at maximum, attempt to provide some integration with render arrays in a follow-up issue (so one would be able to specify '#icon' => 'cog' on a render element to produce the necessary markup).
  4. It's important to understand that we won't be able to solve this in a complete, universal, and bullet-proof way. IMHO that does not matter, but what matters is that we start somewhere. This means that there will be some hate by themers/designers caused by the incomplete system/solution in D8. However, if we never start somewhere, then we can't learn and we won't ever advance on it. The common markup/CSS approach at least delivers a standardized way to achieve the basics — we should adopt it and learn from there.

What do you think?

gausarts’s picture

Forgive me, but would love -1 on stand alone icons approach, it adds extra markups while you can achieve cleaner via pseudo selectors:

Data attributes, #attributes' => array('data-icon' => '$'), and pseudo selectors combo are much cleaner IMHO. But perhaps needs a more intuitive way to this, if simpler, like your #icon which translates to data attributes.

...Thus, it can typically work very well on simple links. But not necessarily on buttons, etc.

Unfortunately it has such issue, like the rest of CSS works. But to clarify a bit, pseudo selectors only work at non-self-closing elements, like <button></button>, but not <input />. But that can be achieved easily by adding a container only if on a massively complex button (hence <input />) design. Fortunately, usually, not too many void elements need extra work with pseudo selectors, like <img />, etc:

ry5n’s picture

@gausarts I'm not usually one to disagree with Jon Hicks, but in this case we’re trying to accommodate more than just icon-font based solutions. Where that 24 Ways article starts to fall down is when using image sprites for icons. A sprite-based icon needs to be clipped to very specific boundaries or else adjacent images in the sprite start to show at the edges (or the icon gets cut off if the containing element gets too small). I've seen both things happen in core, and it's really hard to fix across the board, because you're intertwining the container and the icon. The container may need different custom padding depending on the icon, the icon itself has no width or height, etc.

What this comes down to is a full separation of concerns: icons go in the icon component, and are rock-solid and reliable wherever they're put and no matter what type of asset is used to render them. And all we need is one (in rare cases, two) additional elements in markup. I've implemented icons both ways, and it’s my experience that using separate markup is just so much easier to deal with that it's more than worth it.

That said, it's always good to question adding more markup to core :) And also I'm glad you brought up the data-attribute solution. It's elegant and I think has a lot of promise for font-based icons; I'm not sure if it hurts or helps for sprites. I need to think a bit more about it…

ry5n’s picture

@sun I basically agree with everything in #4. I'm not sure I understand your reasoning for 2) though. Why can't core use whatever solution we decide on to implement font-based icons? Is there really a use case for adding icons directly to Core's own icon font?

I'd also like to get a better idea of what the minimal, string-based solution would be. I'm still foggy on how this would actually work, since a lot of Drupal's internals is still a black box to me. Perhaps we could use our action-links (e.g. '+ Add Content') as an example?

ry5n’s picture

@gausarts Wait, I think I am wrong on the generated content thing, and you are right. We could use :before for sprites, too. For some reason I was thinking of background images on the containing element. So, sorry. My bad. We can consider using generated content, that's an option I think.

LewisNyman’s picture

Based on previous experience using icon fonts I back the the implementation sun proposed in the issue summary. Pseudo elements are the way to go. Whether we use am <i> or not is beyond the scope of this issue, the whole point of standardising the icon classes is so it can be used on any element that is appropriate for that particular context, I think it's a per case decision.

sun’s picture

With the minimal infrastructure and string solution, I essentially meant "nothing" ;)

You're right that an example is helpful. So for action links, the minimal thing would just say and do:

<ul class="action-links">
<li><a class="button" href="/node/add"><i class="icon-add"></i>Add content</a></li>

i.e., just setting up the standard. We can explore whether we can add render array properties and helper methods so developers don't have to write the markup by hand, but I'd almost prefer to move that into a separate follow-up issue, since it's an implementation detail that is detached/independent from the overall infrastructure/standard work and issue.

ry5n’s picture

@sun OK. So it would be a matter of writing out the icon markup in a template file, or as '#markup' in a render array?

ry5n’s picture

I realized that I needed to do some more research on this. I've done a first pass, looking at various blog posts from this year, looking at font-icon vendors' implementations and reading more about the accessibility issues. I've got a couple of options to present in a day or so once I gather everything together. Nothing unexpected, actually I think it will be a synthesis of many ideas fielded here already.

dodorama’s picture

Do we access to vector version of the toolbar icons to make a font out of them?

ry5n’s picture

I’m still working on figuring out markup, and have been doing some of my own accessibility testing. For now, I wanted to expand on what we need for modularity and extensibility.

We want core and contrib modules and themes to be able to use the icon infrastructure easily, but also without conflicting with one another. In terms of css, I think we can tweak existing patterns to achieve this, and even support both class-based and data-attribute-based assignment. The basic idea is that each icon font or image-based solution should namespace its styles with an .iconset-{name} class, so that icons are always applied as class="iconset-{name} icon-{name}". This should allow two icons with the same class name (e.g. "icon-cog") to co-exist on the same Drupal site.

Example CSS:

@font-face {
  font-family: 'FontAwesome';
  src: url('../font/fontawesome-webfont.eot');
    url('../font/fontawesome-webfont.eot?#iefix') format('embedded-opentype'),
    url('../font/fontawesome-webfont.woff') format('woff'),
    url('../font/fontawesome-webfont.ttf') format('truetype'),
    url('../font/fontawesome-webfont.svg#FontAwesome') format('svg');
  font-weight: normal;
  font-style: normal;

.iconset-fontawesome:before {
  font-family: FontAwesome;
  font-weight: normal;
  font-style: normal;
  display: inline-block;
  text-decoration: inherit;
  speak: none;

 * Sample icon display class
.iconset-fontawesome.icon-cog:before {
  content: "\f013";

 * Display icons using data-attributes
[data-icon]:before {
  content: attr(data-icon);
ry5n’s picture

I’m not sure this is possible for D8 at this point. Still, I wanted to share my research. Here's the summary:

Using generated content with no extra markup for icons is the ideal solution, but isn't possible today for accessibility reasons. Basically, we need the aria-hidden attribute to even have a chance of screen-readers not tripping all over icon fonts, even with generated content. In future, using the CSS speak: none declaration will allow us to remove extra <i> tags from markup. But not today.

Here's the markup I’d recommend, to go along with the CSS from #14:

<!-- Icon paired with text equivalent. Screen readers should ignore <i> tag completely but read the label -->
<i class="iconset-fontawesome icon-cog" aria-hidden="true"></i> Configure

<!-- Stand-alone icons use the same markup, but with the icon label hidden visually -->
<i class="iconset-fontawesome icon-cog" aria-hidden="true"></i> <span class="visually-hidden">Configure</span>

<!-- Alternate markup with icons assigned by data-attributes can also be supported -->
<i class="iconset-fontawesome" data-icon="&#xf013;" aria-hidden="true"></i> Configure

Here's my test page. I tested in Chrome using VoiceOver, but testing in additional browser/screen-reader combinations would be super useful.

I think this takes care of #4 points 1 and most of point 2. I'm fine with using SVG icons in Core if using an icon font is really going to be a problem for collaboration; it may well be but I'm still not sure.

What do you think?

jwilson3’s picture

#1836160: Support icon fonts in menu links points out the same thing the issue summary states. Should that be marked as a duplicate or postponed until a resolution is decided here?

YesCT’s picture

Any advice regarding the question in #16?

YesCT’s picture

Can this still be done in 8.x? (hopefully supporting icon fonts would be great)
Or does it need to move to 9.x?

ry5n’s picture

There is a chance this might go in as part of refactoring the new toolbar; we could check with webchick or another core maintainer. RE: #1836160: Support icon fonts in menu links, this issue seems to be more comprehensive; probably move focus here.

dasjo’s picture

i recently tested the IcoMoon App which allowed me to put an icon font together based on various open source icon fonts in a very easy and convenient way. you are also able to add custom SVGs :)

sun’s picture

re: #15 / :

  1. 1.B looks like the way to go for me, and actually is the standard approach. +1 for that.
  2. 2.C also works, but is not fully functional yet. I do not get a tooltip when hovering of the icon. Essentially, the invisible label has to work for both tooltips as well as screen-readers.

    Aside from that, +1 for a subsequent SPAN element. (Btw, I've used a .icon + span sibling selector in my projects with great success; i.e., the literal .icon class denotes an element that represents a stand-alone icon.)

  3. Not sure on the idea of iconsets though. If we want to take a full modular approach, then that is probably the right solution. However, I don't know whether that is a good idea.

    You normally want a consistent iconic language. 10 different icon fonts would be horror, IMHO. I rather thought of going with a single default icon set + classes provided by core, which logically would have to contain a larger set of base icons then. Also, this would inherently set up some base guidelines for appropriate icon usage — if there is no icon for something in the default set, then you should better think thrice whether you aren't overloading the UI.

  4. Missing test cases: .icon-unmapped classes for which no icon exists.
  5. I'm not sure whether data-icon attributes for random character points are a good idea. If people need that, then they can always add that themselves, me thinks.
ry5n’s picture

@sun, #21: Sorry it took me so long to get back to this. I agree with your assessment of the test cases.

1. we agree. check!
2. For 2.C, we can add a `title` attribute to the <button> element to get the tooltip, although I am not sure how that will affect screen readers.
3. Iconsets: a single theme should not mix and match iconsets, that would be horrible. What I am looking for is a way to control which icons get used per-theme, especially to help with logged-in pages, where Drupal mixes styles from the default and admin themes. Perhaps there is a better way to achieve that?
4. I’m not sure I understand what mechanism would exist to detect 'unmapped' icons. Sounds complicated. The simplest thing to me would be a theme utility, vaguely like l() that outputs an icon, so conceptually you might do icon('cog') and you’d get icon container markup with an icon-cog class, and it would be up to the theme to make sure there was some CSS that made that work.
5. Cool, let’s nix code points as data attributes.

dcrocks’s picture

I'm not sure if I understand some of the comments here but I do wonder how all this is going to be implemented. Are all menus going to be modified to add icon supporting classes? Is menu markup going to be modified to add i and/or span elements as well as aria attributes everywhere? Are they going to be 'standard' only or will there be a way to modify them. Is this going to be a dynamic system rather than a static one?

After you are done with all the core menus what about adding new menus or menu items? How will these be 'iconified'? Using per-icon classes and css tends to produce large css files, and though they are always available to any themer to modify or override, this could be a challenge for lengthy menus.

I have played with this and there are a lot of nice examples out there, but most of the time they are nice because they deal with small examples. Do this for the administration menu or the navigation menu with every module plus a few more enabled. And implement it so it is dynamic and flexible. I know the toolbar has been using classes to select individual icons images but look at what you have to do to change it.

markcarver’s picture

I'm not proposing anything for core at the moment, just thought I'd give a heads up here so you know I'm going to be tackling a solution for D7. Referencing:
#1948240: [icon] Request re-purpose/ownership change
#1929416-4: [Duplicate] Mark Fonticon module unsupported and obsolete and a duplicate of Icon API/Icomoon modules

dcrocks’s picture

Have you developed a set of icons already to represent drupal concepts in a standard way? The toolbar project has a set of icons to visually represent concepts such as 'Extend', 'Configuration', 'Content', etc. Do you have images for other drupalisms like 'Add content, 'Recent content', 'Forum', etc. I think, for core, the icon ui should be consistent. Themers may change it of course but drupal should have a consistent ui out of the box. If you have these can you share them?

markcarver’s picture

Icon API - 7.x-1.0-beta1 has been released.
Fontello - 7.x-1.0-beta4 has been released.

ry5n’s picture

@dcrocks What we’re trying to do in this issue is come up with a general solution for implementing icons in Drupal, not necessarily a specific icon set.

@Mark Carver the Icon API module looks very full-featured! It might include more than we need for core, but would you be interested in working on a subset of the functionality for D8? The goal as noted in the summary is:

Implement the necessary markup/CSS infrastructure to handle icons in a consistent, application-wide way.

That involves dealing with the following:
- Icons can be images (png, svg, sprites) or fonts.
- It should be easy for core modules to implement.
- It should be extensible in contrib, both in terms of enhancing the core infrastructure and also to handle additional icon sets (core may include more than one as well)


markcarver’s picture

@ry5n yes, that is exactly what I am trying to and have accomplished with the API. As mentioned in my previous comments, I really do not think icon support will (or should) be added to D8. This is mainly just due to time constraints and lack of conceptional realization/real world implementations. Also, the whole API isn't even fully stable in D7 yet, I'm sure a lot of the components will change before a full release is made. Once that has been accomplished a D8 port of the module will commence and then extraction of the various components to hopefully be put in D9 core is my goal.

It might include more than we need for core

I'm curious to know what exactly it is you are referring to here. The base module itself only provides the necessary API, icon bundle/provider management and administrative UI. The sub-modules are simply extensions of existing core functionality (which would/should be migrated into those core modules if this were to get in core). Any additional providers (such as Fontello would remain as a contrib module since it integrates a 3rd-party service.

Implement the necessary markup/CSS infrastructure to handle icons in a consistent, application-wide way.

That involves dealing with the following:
- Icons can be images (png, svg, sprites) or fonts.
- It should be easy for core modules to implement.
- It should be extensible in contrib, both in terms of enhancing the core infrastructure and also to handle additional icon sets (core may include more than one as well)

Everything that you mentioned above is in and is supported by the Icon API. The goal that is mentioned in the summary is actually the inspiration for this entire API. I'm actually rather confused with your comment, have you even taken a look at the API?

- Icons can be images (png, svg, sprites) or fonts.

The API supports both image files/SVG files in an image tag and HTML/CSS class based markup which encompasses both sprites and fonts.

- It should be easy for core modules to implement.

This of course would be easy once it were actually in core. But that's down the road. Until then any module can easily theme an icon if they knew the bundle and icon names (which are not hard to obtain if you're storing them somewhere, examples are in the sub-modules):

  print theme('icon', array('bundle' => 'my_bundle', 'icon' => 'my_icon'));
- It should be extensible in contrib, both in terms of enhancing the core infrastructure and also to handle additional icon sets (core may include more than one as well)

I have already documented a very extensive API that allows for contrib modules to hook into (which is evident by the two supported projects, Fontello and Bootstrap, listed on the Icon API's project page). Icon "bundles" are "sets". You can have as many bundles as you want as long as the machine name for each bundle is unique. Core, in theory, could provide as many icon bundles as they needed. But that's a different issue, especially considering the GPL licensing around it (#13911: Drupal GPL icons & #606490: Drupal GPL icons - a softfacade initiative).

ry5n’s picture

@Mark Carver I might have miscommunicated #27. I did review the API, and in concept (and in many of the details) it’s exactly what we need. The features I am not sure we need in core are: 1) an admin UI, and 2) quoting the project page: the ability to import archived files and dynamically create icon bundles. In retrospect, when I said it might include more than we need for core, I should have asked a question instead, like “what is the most minimal version of this API, and can we try to do that for D8?”.

BTW, I think we really are on the same page. Before posting earlier today, I had already written some basic code, including:

theme(icon, array('set' => 'iconset_name', 'icon' => 'icon_name'));

D8 core really does need a solution for this, but my expertise is markup and CSS, not PHP or Drupal’s internals. Is there anything at all we can do for D8, to make working with icons in core themes less painful?

markcarver’s picture

Hmm, maybe what I am trying to accomplish is what is being misunderstood. Sorry everyone for the long winded essays, I'm just very familiar with the whole icon topic at large since I've done a lot of R&D around it. So bear with me ;)

Also please note I'm no longer directing any of this to any individual as I don't want anyone to take anything I'm saying personally. Instead please take it from a very knowledgeable and modular/extensible standpoint.

Expanding on my explanation here, #1929394-4: Merge Font Awesome into Icon API, icons have always been an evolutionary element in websites. We started out using static image files for icons. Then we quickly adopted the Sprite CSS method which is still used today. Whether it's an image file or a font file, the method is the same. What we actually are including in the CSS or HTML markup, that is what a lot of this debate is about (much of which has already been established and answered).

The problem in the aforementioned issue is wasted bandwidth and multiple HTTP requests. This typical [standard] approach to using icon sets/bundles as a whole is also rather cumbersome from an management workflow and is often complicated. Which is where font icons and services like Fontello or IcoMoon have helped us, refactoring this workflow and making it extremely easy to include only the selected icons we actually use.

The whole goal behind what I am trying to do, from a front end perspective, is to reduce the amount of bandwidth required and only load the icons when necessary. Given that CSS can include base64 data encoding (in modern browsers, ugh IE) we could, in theory, embed the font file data so there's no extraneous and unnecessary HTTP requests for external files (image or font) and thus increasing page load time. This is actually already a possible generating option for both the Fontello and IcoMoon services.

What this means for us in Drupal is that we, for once, can finally have a modular and dynamic approach to adding icons to a site. Using the theming function I mentioned in my previous comment, or something similar, would make adding icons rather painless. We would only invoke the necessary resource when it is actually needed (ie: on that page). No longer are the days of loading an entirely verbose icon library that isn't being used except for a one off page or admin areas.

Yes, one might think that adding some sort of icon support would be a simple addition to core, but in all reality it really isn't. There are long term and often unforeseen ramifications. The majority of which would probably be the simple fact that we don't know what should go in core just yet. The contrib API would also be affected since it would then have to work within the limitations of what would be in core. It would make development painstaking slow and completely reliant on core.

Also, if it were in core and once D8 is released making changes (aside from bug fixes) is probably not going to happen. Any major changes (for whatever reason that might arise) would probably have to wait until D9 anyway. A perfect example of what I'm talking about: #445990: [META] Refactor color module. I really want to avoid having something in core before it is fully realized and people can making their claims of what "should" or "shouldn't" be in core. It will ultimately become stagnant if we do. We see this all the time in core and it is often problematic and annoying to work around this hacked "solutions".

To answer the question about the admin UI and importing functionality, that's the whole purpose of an API. We have to manage multiple icon bundles (from core, modules and themes) somehow. You might not need a packaged bundle with a theme (say Bootstrap) to show up in any icon selection list. We also need a way for 3rd-party service sub-modules like Fontello to easily import the archive file that was generated by the service into Drupal. The API is there to extract it and record it in the databse, nothing more. It's the sub-module that is responsible for parsing the archive file once it's been extracted because it's specific to that service. This is how an API should function.

These types of questions or debates are yet another example of the type of things that will be discussed back and forth (probably a while) and be refined over time. So, again, putting anything in core now would be absolutely futile since no one really has real data to say what should go in or shouldn't... this will only ever come once we have some good use cases (with real sites, developers and users) and at least a dozen or more releases have been made on the contrib side.

On a slightly lighter note, I have already been working diligently with the maintainers over at Fontello (great guys BTW, very helpful!) to help extend their service to include an API that allows 3rd-party systems to modify existing bundles and "re-export" it back the the callback url (ie: a drupal site). What this now allows us to do is provide a way for users to "add an icon to an existing bundle" through say an IFRAME or something dynamically without ever having to leave the icon selection on the form for a block, menu or field item.

I'm really excited with the amount of effort Fontello has put into making their service extensible for allowing a much more seamless integration workflow. Not much can be said for IcoMoon, I tried to ask for that support and the maintainer really wasn't interested. Seemed to have an anti-developer and pro id10t-proof mindset. I'll eventually have to just work around IcoMoon limitations, but that shouldn't be hard... just not fully flushed out integration functionality like Fontello.

All in all, I know this is a really long comment and hopefully you read it. I'm really just trying to help everyone understand the larger scope of what is/should be to come with icons. There has already been a lot of discussion back and forth of what should be done, this way or that, but in reality we can just keep talking about it or we can start actually using an existing framework that solves a lot of what keeps getting discussed in circles. We will never get anything into core if all we ever do is just talk about something.

So to be quite frank and at the risk of sounding callas, the "getting icon support into D8" bandwagon is the wrong approach. It's human nature to want something now, we're an impatient lot to say the least (myself included) ;) But we need to look at the bigger picture. I will say this again, I want icon support in core too, but please, please, please... I'm begging everyone... let's get this one right! It doesn't take much to add a contrib module to a site or a distro. So whether it's in core a just a contrib module, the end-user wouldn't know the difference.

@sun can you please provide feedback since you originally opened this issue. Also is there a way we can tag this to get core maintainer feedback. I postponed this issue for D9, but it got reverted. Edit: sorry, got this issue confused with #1836160: Support icon fonts in menu links.

ry5n’s picture

@Mark Carver I’ll try to summarize your points as I understand them:

1. Sprites and especially icon fonts are best-practice for front-end performance;
2. Working with icon fonts is hard, hence services like Fontello;
3. The safest, most future-proof approach for getting these benefits in Drupal core is a complete, end-to-end icon module or nothing at all, because minimal or early solutions in core can hamper both core and contrib efforts going forward;
4. There’s no time for such a complete icon module for Drupal 8
5. (Implicit) The primary audience for this functionality is site builders (they don’t care if it’s core or contrib)

I disagree with 5 and the conclusion of 3. Assuming I’ve understood, I do think we have different goals, now. There’s overlap, but the audiences and scope are different. Right now in D8 there is no consistent (default) method for theming icons. We need that not because it’s fancy but because it’s an extremely common need. I think that’s all we need for D8. If we can get a basic theming mechanism right, modules that do more shouldn’t be hamstrung.

ry5n’s picture

Status: Active » Needs review
1.05 KB
PASSED: [[SimpleTest]]: [MySQL] 55,804 pass(es). View

So the attached patch is a very bare-bones implementation. It outputs something like:

<i class="iconset-druplicons icon-configure" aria-hidden="true"></i>

Along with this theme function implementation (ultimately Twig), core would define a library (?) for a core icon set, consisting of asset(s) and an associated css file. The library could be a sprite or an icon font implementation. The classes on the markup and the loaded library determine which icon is displayed. Contrib modules or themes would simply supply their own icon assets as a library and use them by calling the theme function with their iconset and icon names.

Would something like get us to the goal of the issue? Would it cause problems for Icon API or contrib in general?

markcarver’s picture

Status: Needs review » Needs work

1. Yes, but more importantly the fact that they can be base64 embedded in the CSS.
2. No, icons in general are hard (or more complex rather). Font based icons are actually the easiest to implement, IMHO.
3. No, I think you're confusing the word "wait" with "no". I'm not saying icon support shouldn't be in core, in fact quite the opposite. I will agree that we desperately need a solution. But where it differs is that I understand if we were to put this in core now, we will be sorry for doing so in long haul.
4. Correct. D8 is now in feature freeze and now code cleanup, please read Drupal core release cycle. That is the nature of this issue, a new feature. Period. This entire concept has not been fully flushed out.
5. No. The primary audience is (and should be) everyone: developers, site-builders, themers (specifically), non-technical site admins, etc. What you're proposing would only be for developers. There wouldn't be any integration, no hook/theming API for contrib modules to alter or extend. That is the entire point of this issue:


  • API - Implement the necessary markup/CSS infrastructure
  • Administrative UI (core module support, like menus and fields) - to handle icons in a consistent, application-wide way.

In regards to your patch, the reason I am marking this as "needs work" is because you are assuming WAY too much as well as some very fundamentally flawed decision making going on:

+++ b/core/includes/
@@ -1887,6 +1887,30 @@ function theme_image($variables) {
+  $set = $variables['set'];

I really don't like using the term "set" in PHP, especially when in Drupal it is used more of an action word than a descriptive word (ie: variable_set). This is why I decided to call them bundles, to keep in line with the concept of a container of something in Drupal (ie: entity bundles).

+++ b/core/includes/
@@ -1887,6 +1887,30 @@ function theme_image($variables) {
+  $label = $variables['screenreader_label'];

You're assuming this exists here.

+++ b/core/includes/
@@ -1887,6 +1887,30 @@ function theme_image($variables) {
+  $output = "<i class=\"iconset-$set icon-$icon\" aria-hidden=\"true\"></i>";

This is a completely static "solution". Especially when there should be a drupal_attributes() here. Also the icon being themed is only a sprite using an <i/> tag with a custom class. An icon could theoretically still be one of the following: <img/>, <svg/> or <canvas/>. You're already boxing contrib in by using a limited theming hook. Take for instance the approach in the Icon API. It allows dynamic theming based on the render hook specified by the bundle. This way the icon can be rendered how it needs to be, without making assumptions.

+++ b/core/includes/
@@ -1887,6 +1887,30 @@ function theme_image($variables) {
+    $output = '<span class="element-invisible">' . $label . '</span>';

You are completely overriding the entire $output variable here if it is set.


Ultimately this patch wouldn't allow icons to change/grow to include more support for various needs. The problem here is that you're wanting to limit the availability of (put in core, same thing) what is supported in the variables array and ultimately the theming hook. Where this also gets hairy is that if for whatever reason a bug comes up (because we haven't fully realize all use cases yet), it will be harder to change in core than contrib. A perfect example of this is theme_username(). Read the comments about how template_preprocess_username() overrides the $variables['name'] property. Stuff that hasn't been fully realized allows for things like that to happen.

markcarver’s picture

Version: 8.x-dev » 9.x-dev
Status: Needs work » Postponed

In retrospect and per my comment in point number 4 I am marking this for D9 and as postponed. Please don't change it back. That should be left to core maintainers if they really want to pursue this or not.

D8 is now in feature freeze and now code cleanup, please read Drupal core release cycle. That is the nature of this issue, a new feature. Period. This entire concept has not been fully flushed out.

ry5n’s picture

Version: 9.x-dev » 8.x-dev

Core is in feature freeze but Dries has said that there is some flexibility there. We need a basic consistent implementation for icons in D8, period. I don’t see why a theme function and some libraries (or something similar) is not overridable. (BTW thanks for the code review, obviously there’s stuff there that would need fixing).

droplet’s picture

markcarver’s picture

Version: 8.x-dev » 9.x-dev

Then if Dries (or another core maintainer) wants to make this an effort, then I will gladly defer to their judgement. Until then, this issue is postponed for D9.

I don’t see why a theme function and some libraries (or something similar) is not overridable.

Sorry, that was another one of my points that I left out (I was trying to keep the comment short). By putting something in core now, you would effective limiting what I or others would be able to do in contrib.

Yes, overriding a core theming function is possible in a contrib module. However, this creates more confusion and problems than it's really worth. If we decide the Icon API should have a different theming method (which I have already done), then John Smith who developed the "His awesome icon provider" contrib module or theme would have to essentially support both the "core" theming method and the "Icon API" method with something like:

  if (module_exists('icon')) {
    // Icon API method here
  else {
    // Core method here

While this may seem trivial, it actually causes more of headaches and extraneous code that has to be maintained. Meaning that contrib modules would suddenly get issues like "Support Icon API" or "Support core theme_icon()"... or both. This is the point I am trying to instill: you think this is a simple solution, but it's not. There are many ramifications to consider, many of which haven't even been thought of/encountered yet. This, along with the GPL issue mentioned in my previous comment, is why this task has failed in the past.... miserably. I do not want to repeat this, I want to solve it. Iterating over and improving it while in core is not the solution.... how many times do I have to say this?

PS: Your patch also doesn't add the necessary hook_theme() implementation in drupal_common_theme(), so it effectively wouldn't even work at all.

ry5n’s picture

(I know the patch in #32 is incomplete.)

I would like to hear from a core maintainer on this. If it’s not deemed possible in general for D8, I would still like to implement a markup/css pattern for icons specifically for the Seven theme, even if it is simply a markup convention with no API. I would consider such an effort part of core markup/css cleanup, not a feature.

droplet’s picture

Version: 9.x-dev » 8.x-dev
Component: CSS » markup
Category: feature » task
Status: Postponed » Needs work

I think Drupal needs an approach to reuse the CSS style on icon buttons.

It helps developers to use:
- icon fonts
- css sprites
- add retina supports
- replace with a custom icon sets.

Let's back to D8-dev. Maintainers could put it back to D9 if they decline this approach.

ry5n’s picture

Title: CSS Icons » Provide consistent markup/CSS for icons
Issue tags: +styleguide

@droplet Thanks. At this point I would still like input from a core maintainer (or Spark team member, since they’ve been working on similar things).

Retitling to something a little more descriptive.

markcarver’s picture

Title: Provide consistent markup/CSS for icons » Add hook for theming icons (standardize markup)
Version: 8.x-dev » 9.x-dev
Component: markup » theme system
Category: task » feature
Priority: Major » Normal
Status: Needs work » Postponed
Issue tags: -Needs themer review, -styleguide +accessibility, +Needs committer feedback

What part of "feature freeze" is unclear to y'all? That is what you're asking, to implement a theming hook to provide "standardization" for icons. This is a feature. Re-titling to what is actually wanted from the prior comments.

Also, if you are referring to the Admin Icons, that is also a contrib module and part of the Spark distribution.... not core.

This issue needs actual data and real world use cases (in Drupal as a contrib module) before we can even attempt to "standardize markup" or put in core. Why do you think that it's only now that a lot of contrib modules are finally getting put into D8, instead of being put in when D7 was being developed? Because the concept was yet fully realized and there were still too many fundamentally unresolved issues.

Please just stop.

markcarver’s picture

Adding some more tags

xjm’s picture

Title: Add hook for theming icons (standardize markup) » Provide consistent markup/CSS for icons
Version: 9.x-dev » 8.x-dev
Status: Postponed » Needs work
Issue tags: -Needs committer feedback +Needs issue summary update

Hi @Mark Carver,

Thanks for all your input on this issue! See this blog post:

That policy was established by @catch and @Dries. Small new features that do not disrupt other parts of core are acceptable throughout the D8 release cycle, and even after code freeze if they do not break the backwards compatibility of APIs, so long as we are under issue thresholds. UI and markup changes are also still allowed after code freeze.

This feature looks fairly non-disruptive, and it also appears to be an accessibility enhancement, so we can keep this filed against Drupal 8. My gut feeling is that this is even something that's backportable, so we don't need to push it to D9 yet.

Let's update the issue summary here to describe all of the several proposed approaches, rather than just the one approach. The title can be the goal of the issue, generally, and we'll change it once we have consensus if appropriate.

P.S.: I'm not a core maintainer, but I work for one. ;) If you disagree with my assessment here, we can run it by catch or Dries, but they will likely say the same thing.

Edit: We discussed this a bit in IRC, and ry5n and Mark Carver are going to discuss it a bit and then write an up-to-date summary. Even if we do end up moving this to D9, getting consensus in the core queue will be beneficial for the D8 contrib module as well.

pmelab’s picture

I have not seen fontcustom being mentioned in all the icon-discussions.
I'm quite happy working with it. Its an idiot-proof wrapper around fontforge and ttfautohint. Basically you throw a folder with svg files at it, and it'll create all necessary font files and stylesheets. Since 1.0.0, the stylesheet output is templateable.
Also it could be a solution for licensing problems?

ry5n’s picture

@pmelab Fontcustom is probably what we’d want to use for a Drupal core icon font. However, this issue is about coming up with a default markup/css pattern for icons of all kinds (generally, fonts and sprites). An actual icon set is out of scope.

Since #43, I've reached out to @Mark Carver a couple of times but have not received a reply. EDIT: My bad, I was using a wrong email address. My hope is to have an updated issue summary within a week.

markcarver’s picture

@pmelab: I agree with @ry5n, Font Custom is a CLI application for creating icons, which does not pertain to this issue. Per the current issue summary:

Adding actual icons to Drupal core is NOT within the scope of this issue.

That being said, IcoMoon already has SVG Import capability and Fontello will soon have it as well. Font Custom is more if you're a die hard fan for doing everything locally or you're a terminal junkie (like me). But even I will probably stop using this since there's already the web services to accomplish this type of task.

Had a nice chat with @ry5n today about all this. I'm hopeful we can come to a general consensus on how to proceed with this issue and update the summary soon.

pmelab’s picture

I'm sorry, I totally agree that this is not part of this issue. I was reading all the issues regarding icon fonts, opened in different tabs, and managed to pick the wrong one to add my 2 cents.

Just one last thing:
I don't think that FontCustom is just for die hard terminal fans. IcoMoon and Fontello are more comfortable (if you get all icons at once). But we should at least provide an alternative that we have so kind of control of. We don't know if IcoMoon and Fontello will be there forever. But we could fork FontCustom.

And now to the real topic.
Does it make sense to unify markup for font- and sprite-icons? They behave completely different in the document flow, and even have a different interface. Since fonts are lossless resize- and recolorable, which and sprites are not. Using rasterized icons or sprites is quite easy, while font icons need a lot of fine tuning. I think It would help more people if the solution focuses them.

markcarver’s picture

There will always be different ways to produce icons, be it a web service or some GUI/CLI application. How the icons are produced is really kind of irrelevant since, like you said, this will always change. I can't remember the issue where I read this, but core really needs to get out of the business of assuming what will be provided and simply provide the tools (aka: APIs) necessary to get the job done.

I've kind of already ran into this dilemma with the Icon API. As far as I can tell, there are primarily two types of icons: CSS based and static images. However in theory, we could also have <svg/> icons or some other technique that I'm not yet aware of or hasn't be invented yet. Let's focus on the two most commonly used though:

Sprites/Font Icons
Should we standardize the markup for these? Yes. All that's really needed for these type of icons is a tag (doesn't really matter which one, preferably inherently inline) with a unique class name to identify the icon. The responsibility for correctly displaying the icon falls back to the CSS at that point (which unfortunately, falls outside the scope of this issue). Currently the most common tag used for icons tends to be <i/> (the link includes a lot of points for why this is).

Static Image Icons
These are pretty straight forward and simple, it is just an <img/> tag. The only difference is that an additional $variables['src'] attribute needs to be provided. In theory, we could easily create a toggle between these two markups based on this attribute. Assuming that these are the only two types of icons we're going to support (for core, which would lock us down until the next release cycle or version).

Given the possibilities of <svg/> icons or some other type we're not fully aware of yet. What we really need is a way for extending the icon theming process via theming suggestions. I've already tried doing this (something like: theme_icon__svg()), but ran into issues with #956520: Available theme hook suggestions are only exposed when there are preprocess functions defined. Once this gets fixed (probably by #2004872: [meta] Theme system architecture changes), then it would make this a lot easier to provide a "core" standard that can be easily extended (and would probably shut me up about why we should wait lol).

axel.rutz’s picture

8.x or 9.x?

* i think it's a good idea to leave this issue as 8.x to stay in the discussion scope.
* i reviewed and tested iconfonts.module and share the view it's the right-thing-to-do(tm): a completely drupaly api to abstract icons and their css selectors
* i share the view of #41 that (most of) this api should mature in contrib-land and this issue will be 9.x at some point in time

markcarver’s picture

@axel.rutz: I'm a little confused, are you referring to the Icon Fonts module or did you mean to say the Icon API module in your second point?

markcarver’s picture

Title: Provide consistent markup/CSS for icons » Add theming function/template for icons
Status: Needs work » Postponed

Per my conversation with @ry5n on IRC, we've concluded this issue needs to be postponed until the aforementioned issues are resolved.

Also updated the issue summary.

markcarver’s picture

Issue summary: View changes

Updated issue summary.

ry5n’s picture

Issue summary: View changes

Updating the issue summary to better reflect current state, including resolved markup pattern, discussion around Icon API module, and possible blockers.

tkoleary’s picture

@Mark Carver

Can you list the specific issues that require resolution? I think it would be a shame if we didn't get this in, at least in some form, before feature freeze.

markcarver’s picture

@tkoleary: see #48, the last paragraph.

tkoleary’s picture

Right. Anything I can do to push that forward?

markcarver’s picture

Title: Add theming function/template for icons » Add theming template and prepare logic for rendering icons
Assigned: Unassigned » markcarver
Issue tags: +Needs tests, +Twig

Just an update.

Per my original "extensibility" section in #48, this issue is still blocked until the following two issues get fixed:

#1751194: Introduce hook_theme_suggestions[_HOOK]() and hook_theme_suggestions[_HOOK]_alter()
#2035055: Introduce hook_theme_prepare[_alter]() and remove hook_preprocess_HOOK()

To answer why this is blocked by these two issues:

There are primarily two types of icons: CSS based and static images. However in theory, we could also have icons or some other technique that I'm not yet aware of or hasn't be invented yet.

These two issues would give us the ability to utilize theming hooks for extensibility purposes, like:
icon__css or just icon as a fallback?

I would again like to stress that this is still just a feature request. We have soooo much to do still with Twig:

Tagging this for Twig and assigning to myself since I'll probably be the main one spearheading this once we're go for green. I'll also add this under the "Nice-to-have" section of the above link.

markcarver’s picture

Issue summary: View changes

Add back #2004872 into related issues section

tkoleary’s picture

There are primarily two types of icons: CSS based and static images. However in theory, we could also have icons or some other technique that I'm not yet aware of or hasn't be invented yet.

I think technically there are more than two (depending on where you draw category lines):

  • Inline image in markup
  • Inline PNG in markup with CSS link embedded in the PNG (for effects)
  • Inline image in CSS using :before or :after pseudoclass on the link
  • Background image in CSS
  • PNG as data URI in CSS (either background or :before)
  • Icon fonts

I'm not a CSS guru but I *think* a good approach would be to always use CSS and the :before pseudoclass regardless of whether the icon is an image, a data URI or a character in an icon font. Also if we default to a character then even if the webfont does not load for whatever reason, a good icon font will map most characters to existing UTF symbols

markcarver’s picture

@tkoleary: Yes, there's different ways to do it in CSS, but I was referring to which actual markup will be used per theme hook suggestion:

CSS/Font (class) based: <i class="..." aria-hidden="true"></i>
Image based: <img src="..." alt="..." aria-hidden="true" />
Or even possibly SVG: <svg>...</svg>

All three of these require different markup. The reason it's blocked has nothing to do with the different internal variations of a given "type".

tkoleary’s picture

I think we can get away with none of the above and produce more semantic code with less markup if we use pseudo elements, but I'm not certain.

This is how I imagine it:

There's no markup for icons
icons use the before pseudo element like this:

<a href="/shortcuts" class="icon" id="shortcuts">Shortcuts</a>

.icon {
   whatever attributes you need to position and style all icons
#shortcuts:before {
  content: '\2605'; */this is the UTF8 symbol for star/*


#shortcuts:before {
  content: 'link to any kind of image';


#shortcuts:before {
  content: 'a data URI';

Now the themer never needs to leave the CSS file which—I think—is what they want

markcarver’s picture

No... I get what you're saying, but I think that completely defeats the whole point of this issue. What you're proposing is: to do it like we've always done it in the past.... make it the "themes" responsibility to modify the CSS... then make sure your site is "built" to use these special classes you have to remember...... or yell at the dev guys because they forget to utilize this "awesome theme you built".... sigh it's a vicious cycle and one I'd like to end.

You're proposing "no markup". Yes, many themers know _how_ to insert icons in CSS with different methods... but you're also assuming that we want to use CSS or even touch if we do....

For example: the Fontello module is a wrapper for the Fontello service, an online CSS/Font based icon "packager". It comes bundled with it's own CSS, Fonts and config. Now consider utilizing this "icon" theme hook with something like: icon__fontello. This would allow us to attach the necessary CSS to the page for these icons. We don't _ever_ have to touch these and they get update each time (automatically).

You're also limiting themers to use CSS based icons having to manually create additional CSS to support <img/> based icon sets like: (and COUNTLESS others that people _will_ use). Now, I'm condoning actually _using_ outdated technology... (hell, I haven't used used images in years), but we can't expect everyone to be expert themers.... we have to give options.

markcarver’s picture

The other reason for doing it the way I'm proposing is for future extensibility:

or some other technique that I'm not yet aware of or hasn't be invented yet

tkoleary’s picture

@Mark Carver

So I think we have the same goal but we're coming at it from different directions. What I have been working on—along with others like ry5n—is a font that covers every single icon that is currently used in Drupal core plus a great many others that are common and may be used in the future.

Though we are working on different icon sets, both ry5n and myself share the goal of sandardizing the UTF8 character mappings so that a themer could take the font and replace it with their own icon set, using a service like icomoon or fontello or locally with open source font software. That way all any themer would need to do is replace the font and the proper icons would automatically load. This may sound a bit ambitious but in fact there are very few icons in core that cannot be mapped to an existing UTF8 symbol. Icon fonts found in other libraries often use the private use area and are not following any standard for what is rapidly becoming a standard language (interface icons). In my opinion this is an opportunity for Drupal to lead the way on a sensible standard for the web in general.

One of the big issues for me has been just hunting around for all of the icons in Drupal. I would suggest that the whole process would be easier if we moved all of the icons from every module in core into a single, well commented, icons.css file (I know I just gave many people a heart attack). Then in cases where a themer doesn't want to use a font it would be relatively trivial to replace each icon with an image.

ry5n’s picture

@tkoleary I have to correct a few things you’re attributing to me that I never said.

1) It is true that I made an icon font to cover all of the icons currently in use by core. However, I had nor have any intention of including “a great many others that are common and may be used in the future”. I simply wanted to create a unified icon set to go along with my work on the Seven Style Guide, and to use what I consider to be the most flexible implementation currently available (icon font).

2) “both ry5n and myself share the goal of sandardizing the UTF8 character mappings”. That is absolutely false. I do not believe it’s useful, or even possible, to do this. There are a couple of reasons the Private Use Area is used by most icon fonts: first, it means the icon set can do whatever it wants. For example, it can define several variations on a single icon or add icons that do not have associated code points in Unicode. There are also accessibility concerns with using non-PUA mappings: some screen readers will read out non-PUA glyphs (even in CSS generated content) which they may or may not read out correctly. Even if the screen reader does render them in some intelligible way, if the icon has an HTML text label it will end up being read out twice – which is annoying. So using the PUA prevents screen-readers reading garbled or duplicate content. If an icon is used alone, the best way to provide a screen-reader alternative is with an HTML label hidden using a traditional technique (.element-invisible or similar). [Edited for clarity RE: PUA.]

tkoleary’s picture


Sorry. I misinerpreted your work there. When I saw that you had covered many of the common HTML special characters in your font I mistakenly assumed that you would be mapping them to UTF8 cells. I have been working on mapping my set to UTF and I think it's both possible and a good idea, given that there are relatively few of them that do not already have at least one possible analog and mapping them to the cells standardises them so that they become swappable just like any other font.

To your other points:

first, it means the icon set can do whatever it wants. For example, it can define several variations on a single icon

Fonts already have methods of dealing with these types of issues, like alternate characters and ligatures if the meaning is changing or hinting if the variation is for clarity at different sizes.

or add icons that do not have associated code points in Unicode.

Certainly those would need to be outside existing cells, however there are many icons that are currently under review but which already have assigned cells. I *think* these can be dealt with in the same way as prefixed CSS ie. use them as a de-facto standard until they become part of the standard.
On the accessibility front I'm going to have a talk with JesseBeach today and explore the issues you bring up.

Can I say at least that we are agreement on the following?

  • We would both love to see iconfonts in core
  • Icon fonts are gaining popularity all the time
  • New services to produce icon fonts are popping up regularly
  • Designers and front-end developers are gravitating towards icon fonts
  • The explosion of webfonts will have a knock-on effect of improving performance for iconfonts
  • If we could document an iconfont solution that uses UTF8 and deals with the issues of variation and accessibility that would be preferrable to uniquely mapped, non-swappable icon fonts
markcarver’s picture


No one is disagreeing with you "per say". Yes, webfonts (the most preferred and more commonly used method now perhaps) is where we're headed. However it's not the only method and I think you are mistaking this issue for something else. This issue is about the markup for all types of icons and it's API/implementation in core, from the issue summary:

Adding, changing or removing actual icons is out of scope for this issue.

Removed tag because I updated it in #55.

tkoleary’s picture

@Mark Carver

No problem. Moved the icon discussion here: #2032773: Use Libricons (icon font) in Seven, consider using it more broadly in core

My final thought on the markup is to keep it simple and use a span. That doesn't conflict with the :before approach and also allows us to add aria-hidden="true" so the name of the icon is not read out. We should not use i because it's not semantic, and svg and image won't work for fonts.

<span class="icon" id="shortcuts-icon" aria-hidden="true"></span>

tkoleary’s picture

Issue summary: View changes

Updated issue summary.

mgifford’s picture

Should the status of this issue changed from postponed since #1751194: Introduce hook_theme_suggestions[_HOOK]() and hook_theme_suggestions[_HOOK]_alter() is marked as fixed?

EDIT: Or is it waiting on #2004872: [meta] Theme system architecture changes

markcarver’s picture

No we're waiting on this issue, which allows us to actually invoke specific suggestions in the prepare (preprocess) phase. Regardless though, I still think this should be postponed since it's a feature request. We have more pressing concerns ATM. There is nothing preventing us from adding this to core after release since it's just a simple addition.

#939462: Specific preprocess functions for theme hook suggestions are not invoked
This is the D7 issue that would allow us to move forward with backporting.

no2e’s picture

I agree with tkoleary (#65): don’t use the i element, use the span element instead.

Using a HTML element for "decorative" icons is a hack (it should be CSS’s job). If, for whatever reason (e.g., backwards compatibility), we need a separate HTML element, don’t use one with a different meaning (↓), use a meaningless one: span.

The i element is not appropriate for icons (bold by me):

The i element represents a span of text in an alternate voice or mood, or otherwise offset from the normal prose in a manner indicating a different quality of text, such as a taxonomic designation, a technical term, an idiomatic phrase from another language, transliteration, a thought, or a ship name in Western texts.

FWIW, Bootstrap 3 changed from i to span, too.

tkoleary’s picture

@pixelwhip did a great session at badcamp 2014 after which we batted around some good ideas for how this can be done. I'll let him flesh out the details :)

dcrocks’s picture

The i element was originally proposed by some because of the way screen readers handled that element as opposed to the span element. I can't find the original article that explained it anymore. In any case the bootstrap reference doesn't indicate there was a change or why. I'd argue that an icon does represent a different quality of text and I is therefore more correct, but I don't want to start bike shedding over semantics.
It really isn't that important unless you are concerned about accessibility. Perhaps testing with a screen reader would settle it.

LewisNyman’s picture

Status: Postponed » Active

This issue came up again in #2209063: Fix the flicker of the "active" icons when a high-latency user clicks on toolbar items.

It would be really great if we could get some kind of icon API in 8.0.x or 8.1.x because otherwise it makes it really hard to change how icons are implemented all over the place.

We shouldn't get caught up on which element is the best, because once we have a consistent implementation it's easy to change. Maybe we should just focus on consolidating icon implementation rather than changing implementation in this issue?

Wim Leers’s picture

Maybe we should just focus on consolidating icon implementation rather than changing implementation in this issue?

Sounds like a great plan to me.

markcarver’s picture

Version: 8.0.x-dev » 8.1.x-dev
Issue summary: View changes
Status: Active » Postponed

Given that this is a feature request, this can be added in 8.1.x. As for why it's postponed, please see #55. It's now actually blocked on #939462: Specific preprocess functions for theme hook suggestions are not invoked given that it moved back to 8.0.x. I've updated the issue summary accordingly.

I'm very familiar with this topic and have already gone through great lengths to consolidate existing implementations and foresee new ones:

Regardless of whether or not it's an <i> or <span> tag is irrelevant. Those last few comments aren't the real reason why this issue is postponed. There needs to be a proper theme hook system for this to work effectively given how many different ways there are to implement "icons" on a website.

I would love to see this in core ASAP, but I would also just like to ensure that we don't put something in core that really isn't usable or extensible. Core has often had a history of just adding new "theming" features without realizing how limiting they may actually be. This topic needs real world testing and implementation.

axel.rutz’s picture

We may also look at the iconfonts module (i took over maintainance of this lately), which adds a configurable indirection layer icon-class=> associated-icon, so we can easily swap out any icon.

Wim Leers’s picture

#74: icon fonts are highly problematic/tricky to make work with Drupal, because Drupal has such a rich contributed module ecosystem. It can only work if we have the ability to let Drupal core generate an icon font. Multiple fonts is terrible for front-end performance. A single font is very hard to get right: any contributed module might add additional icons, and should have their default icons moved into the generated icon font, but still allow themes to override those default icons. And so on. So unless we have PHP code that can generate icon fonts, I'm afraid that's off the table :(

markcarver’s picture

Re #75:

icon fonts are highly problematic/tricky to make work with Drupal

Not true. See:

It can only work if we have the ability to let Drupal core generate an icon font.

Also not true. Services like Icomoon and Fontello exist which can generate custom icon fonts. We just need a provider API, which is available in the project above, that allows contrib modules to import based on the zip/tar.gz file that's generated (hint, there are modules for each of those services).

Multiple fonts is terrible for front-end performance.

True. However, discarding the use of icon fonts by justifying that everyone will use poor FE development/choices isn't right either.

A single font is very hard to get right: any contributed module might add additional icons, and should have their default icons moved into the generated icon font, but still allow themes to override those default icons. And so on.

This issue isn't about the bad practices of contrib. This issue is really about adding a relatively stable API for rendering icons (of any kind) and actually establishing Best Practices™.

In all reality I would imagine that most contrib modules that add icons would be SVG or PNG based. I would also further venture that most backend devs aren't that familiar with icon fonts. That is more than fine. This allows the frontend to override said SVG/PNG icons with their custom single HTTP request icon font. Win win.

So unless we have PHP code that can generate icon fonts, I'm afraid that's off the table :(

The only PHP needed for this issue is just to provide an API to hook into core's theme system. There has never (and will never) be an issue about generating (or aggregating) icon fonts in PHP (that is a frontend development best practices issue). There are already multiple external services that do this. We don't need to reinvent the wheel here.

Wim Leers’s picture

Your first two rebuttals are only true because they reply to part of my statement… Those external services indeed solve it, but Drupal core can never depend on external services. That's why I wrote #75 at all.

You say there are modules for those services. In that case, I take back everything in #75. I remember from discussions a year ago that it was deemed a huge, nigh impossible undertaking to generate icon fonts in PHP.

This issue isn't about the bad practices of contrib.

I didn't say that. And adding additional icons is not a bad practice. It's something that this API should support, IMHO.

There has never (and will never) be an issue about generating (or aggregating) icon fonts in PHP (that is a frontend development best practices issue).

This is where I disagree strongly. It's the task of this API to take all the icons of core and contrib, plus the theme's overrides and spit out a single icon font. If it can't do that, we can't have Drupal core support an icon font-based approach out of the box because it's not complete enough, IMHO — then we should use an SVG-based approach instead, IMHO.

I was only reiterating key parts of earlier discussions, to make sure they're not forgotten. (I think mainly from #1963886: Use HiDPI icons in the toolbar.)

Sorry for bringing this up while it's postponed, I should have just linked to #1963886. I didn't want to derail this issue.

+100 for #73 :)

mgifford’s picture

Status: Postponed » Active
mgifford’s picture

Actually, probably not really active till January 6th or so based on

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.