google / material-design-lite

Material Design Components in HTML/CSS/JS
https://getmdl.io
Apache License 2.0
32.28k stars 5.05k forks source link

Icon font relative/absolute path issue #258

Closed surma closed 9 years ago

surma commented 9 years ago

Something we have to address before release is the way we include our icon font:

Right now we are using relative paths.

Relative paths are great as some pages are not hosted on root level (e.g: https://google.github.io/material-design-lite). However, with relative paths we have a problem with webpages that use multiple levels of directories (e.g: https://google.github.io/material-design-lite/components/button), as the relative paths won’t be resolved properly (except if the user has multiple copies of the font files lying around).

Suggestions? CDN?

addyosmani commented 9 years ago

I'm personally fine with a CDN based icon font for the short term. We'll be switching to the official Google CDN version of the Material icon font in a few months. Thanks for opening up the discussion on this.

Garbee commented 9 years ago

This could also apply to the SVG's for the checkbox. Maybe we should use an absolute path and have sass vars for the path. This would mean developers can easily override the paths in a compile and it would work out of the box if you put the assets in the right place according to the server document root.

Not sure if we should worry too much about getting subfolders working just right, afaik no real good way to handle that other than CDN.

surma commented 9 years ago

The checkbox SVG is inlined as a data-url in the production build. No need to worry about that. Sadly, that’s not a feasible solution for the font.

MikeMitterer commented 9 years ago

Here is the approach I took: _fonts.scss:

$icon-font-path : "packages/mdl/assets/fonts" !default;

@font-face {
    font-family : 'Material-Design-Iconic-Font';

    src         : url($icon-font-path + '/'  + 'Material-Design-Iconic-Font.eot?v=1.1.1');

    src         : url($icon-font-path + '/' + 'Material-Design-Iconic-Font.eot?#iefix&v=1.1.1') format('embedded-opentype'),
                  url($icon-font-path + '/' + 'Material-Design-Iconic-Font.woff?v=1.1.1') format('woff'),
                  url($icon-font-path + '/' + 'Material-Design-Iconic-Font.ttf?v=1.1.1') format('truetype');

    font-weight : normal;
    font-style  : normal;
}

/* ==========  TYPOGRAPHY  ========== */

/* We're splitting fonts into "preferred" and "performance" in order to optimize
   page loading. For important text, such as the body, we want it to load
   immediately and not wait for the web font load, whereas for other sections,
   such as headers and titles, we're OK with things taking a bit longer to load.
   We do have some optional classes and parameters in the mixins, in case you
   definitely want to make sure you're using the preferred font and don't mind
   the performance hit.
   We should be able to improve on this once CSS Font Loading L3 becomes more
   widely available.
*/

$preferred_font: 'Roboto', 'Helvetica', 'Arial', sans-serif;
$performance_font: 'Helvetica', 'Arial', sans-serif;

Easy to overwrite.

@surma I don't get why you need the build step for including the SVG. I added it to the SCSS and I'm done. Easy and clear.

surma commented 9 years ago

Your solution works with SASS, but not with the compiled CSS that we are going to distribute. We need to have a general solution for this problem.

Regarding the SVG: We wanted to keep the SVGs as individual files in the repository so they can be manipulated individually. Or am I misunderstanding you?

MikeMitterer commented 9 years ago

SVG: But why would you want to change or manipulate the SVG for the checkboxes for example? But if so this happens very rarely. In my opinion it's not worth to create an additional build step for such things - the benefits of including the SVG beats the "build step solution" by far.

surma commented 9 years ago

The checkbox SVGs are somewhat hacky right now, as Chrome and Firefox handle masks differently. @sgomes knows all about it ;) So right now each SVG contains two to three slightly different copies of itself to make it work across all browsers. Therefore, I do expect them to change once browser behavior converges.

In my opinion it's not worth to create an additional build step

It has already been created.

the benefits of including the SVG beats the "build step solution" by far

I’m afraid I can’t quite follow. What are the benefits of inlining the SVGs manually on the source side over having it done automatically as a build-step?

sgomes commented 9 years ago

Regarding CDN stuff, we may want to delay that until we have an official Material Design icon font, and not the community one we're currently using.

Also, I've found that some web developers are extremely particular about their choice of CDN, so I'm not entirely sure forcing this choice on them would go down well. That said, we already use the Google Fonts CDN for Roboto...

addyosmani commented 9 years ago

Btw, do we know how other libraries (Bootstrap, Foundation etc) have traditionally handled this problem?

Official font update

Unfortunately there don't appear to be any docs available for the yet-officially-released icon font. I tried digging into the sources, but until google.com/design updates with new docs for icons, we're probably a few weeks out from being able to switch.

Garbee commented 9 years ago

Bootstrap just does a variable for the path and sets their default.

Foundation makes their icons a completely separate package. Within that they also have a variable for the path.

Summary: Simple path variable is the path forward it seems.

surma commented 9 years ago

Path variable are NOT a solution to this problem. I think I’m just failing at explaining this properly :smile: Let me try again:

We will be distributing a compiled CSS file (i.e. not SASS, so variables are not available). If the website that wants to use MDL has subdirectories (like our microsite does), relatives path obviously won’t reference the correct file anymore.

Absolute paths are not an option either as we can’t assume that all pages using MDL will be hosted at / (again, just like our microsite at https://google.github.io/material-design-lite/).

A CDN seems to be the only viable solution.

surma commented 9 years ago

I just remembered: Relative paths in CSS files will be resolve relative to the CSS file. So relative paths should work. I’ll have to take a look why it doesn’t.

I guess, Ignore this issue for now. Sorry for all the commotion.

Garbee commented 9 years ago

the website that wants to use MDL has subdirectories

That is where that site needs to take into account they are using subfolders and either: 1) Move the sources up higher 2) Run a build specific to their path needs.

Is the microsite code you are working on in the current branch on the main repo? If so I can clone and take a look.

Garbee commented 9 years ago

The problem with gh-pages is the references to the CSS/JS itself are hard-coded as from root. When they need the sub-directory on them.

surma commented 9 years ago

As of #284 I’m officially reviving this issue :D

With relative paths we are forcing our users to put the fonts in a specific location. Maybe one group of users want their CSS files in /css and the fonts in /fonts and others might wanna do /css and /css/fonts respectively or whatever. Also, if – for some reason – you have multiple versions of material.css on your site (think: A page that changes its theme while navigating), you have to either put the CSS files in the same location or have multiple copies of the fonts.

I think, bottom line, a CDN solves too many potential problems without any costs (even adds caching benefits) to not seriously consider it. WDYT?

Garbee commented 9 years ago

What CDN would we take advantage of? So long as we have a variable developers can swap out for a local version (or another CDN) a default sane CDN choice sgtm.

This also has some current advantages with existing HTTP 1.0/1.1 limitations in the connection limit space, so until HTTP 2.0 is more dominant we also reap a performance benefit right away.

surma commented 9 years ago

Good point. Sticking with relative paths and use the CDN resource as a last resort seems like a very good compromise.

The only downside of having 2 separate resources I can think of is version skew, but I don’t see the font being updated all that often.

Garbee commented 9 years ago

Well, CDN should be first choice right now for the given scenarios. But, given via a variable developers can override to set a local copy (relative/absolute/whatever) or their own CDN url.

We just update the CDN URL as the font is updated.

However, on the note of going to the upstream font, we ideally would do that before 1.x lands. After that depending on what all is needed it could be another major update to change fonts.

addyosmani commented 9 years ago

Just to check: with the icon font now being available on the Google CDN, are path issues still an issue for us? cc @sgomes @surma

sgomes commented 9 years ago

Nope, this is fixed since there should be no further references to any local fonts. If there are, it's a bug, so let me know.

addyosmani commented 9 years ago

Awesome! :star: