postcss / postcss-simple-vars

PostCSS plugin for Sass-like variables
MIT License
415 stars 36 forks source link

@font-face: Variable inside string is not working #55

Closed alansouzati closed 8 years ago

alansouzati commented 8 years ago

The following css works:

$fonts-path: "https://path.to.font/MetricHPE-Web-Regular.woff";  

@font-face {   font-family: "Metric";   src: url($fonts-path) format('woff'); }
 @font-face {   font-family: "Metric";   src: url($fonts-path) format('woff');   font-weight: 700; }  
@font-face {   font-family: "Metric";   src: url($fonts-path) format('woff');   font-weight: 600; }  
@font-face {   font-family: "Metric";   src: url($fonts-path) format('woff');   font-weight: 100; }

But this css does not work:

$fonts-path: "https://path.to.font/";  

@font-face {   font-family: "Metric";   src: url("$fonts-path/MetricHPE-Web-Regular.woff") format('woff'); }  
@font-face {   font-family: "Metric";   src: url("$fonts-path/MetricHPE-Web-Bold.woff") format('woff');   font-weight: 700; }  
@font-face {   font-family: "Metric";   src: url("$fonts-path/MetricHPE-Web-Strong.woff") format('woff');   font-weight: 600; }  
@font-face {   font-family: "Metric";   src: url("$fonts-path/MetricHPE-Web-Light.woff") format('woff');   font-weight: 100; }

No errors in the webpack console. the app just does not render the font. If I remove $fonts-path variable webpack complains about undefined variable which is good sign that simpleVars is actually trying to parse those variables inside the string.

I'm using the latest version of this plugin.

ai commented 8 years ago

Could you try $(hpe-fonts-path)?

alansouzati commented 8 years ago

thanks for the quick follow up. I've tried that no luck as well. as tried with and without the suffix.

$fonts-path: "https://path.to.font/";  

@font-face {   font-family: "Metric";   src: url("$(fonts-path)") format('woff'); }  
@font-face {   font-family: "Metric";   src: url("$(fonts-path)") format('woff');   font-weight: 700; }  
@font-face {   font-family: "Metric";   src: url("$(fonts-path)") format('woff');   font-weight: 600; }  
@font-face {   font-family: "Metric";   src: url("$(fonts-path)") format('woff');   font-weight: 100; }
alansouzati commented 8 years ago

I was trying to investigate the problem. I can send a PR if you think that's the fix.

https://github.com/postcss/postcss-simple-vars/blob/master/index.js#L18

In here, the string is represented as '"https://path.to.font/MetricHPE-Web-Regular.woff"'

I was not expecting to have the double quotes in there.

I'm not sure where is the best place to remove it.

alansouzati commented 8 years ago

I believe postcss is sending that over with the double quotes inside the string. I don't know if this is the expected behavior to allow more control from the plugin's end.

If this is the expected behavior, I think here is the spot to add the replace quote:

function definition(variables, node) {
    var name = node.prop.slice(1);
    variables[name] = node.value.replace(/'|"/g,'');
    node.remove();
}
ai commented 8 years ago

Very strange. It is night in Russia. I will look tomorrow.

Could you give me your plugin list?

alansouzati commented 8 years ago

This is my webpack config:

import webpack from 'webpack';
import path from 'path';
import simpleVars from 'postcss-simple-vars';

export default {
    entry: './src/index.js',
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'index.js'
    },
    resolve: {
        extensions: ['', '.js']
    },
    module: {
        loaders: [
      {
            test: /\.js$/,
            exclude: /node_modules/,
            loaders: ['babel']
        },
            {
                test: /\.css$/,
                exclude: /node_modules/,
                loader: 'style!css?sourceMap&modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss'
            }
    ]
    },
    postcss: () => [simpleVars]
};

you are the only plugin I'm using as of this moment. I've started playing with post css yesterday :)

I'm planing to migrate Grommet to use CSS Modules + PostCSS over Sass. BTW, great job on PostCSS.

We sync tmw. enjoy your evening.

ai commented 8 years ago

Problem is because of double ". You have "https://path.to.font/" in variable, not https://path.to.font/.

ai commented 8 years ago

But, you can’t unquote variable because of : in value.

alansouzati commented 8 years ago

correct :)

Why the restriction on " ?

ai commented 8 years ago

The best way is to replace variable to mixin:

@define-mixin metric-font $type, $weight {
  @font-face {
    font-family: "Metric";
    src: url("https://path.to.font/MetricHPE-Web-$(type).woff") format('woff');
    font-weight: $weight;
  }  
}

@mixin metric-font Regular, normal;
@mixin metric-font Bold, 700;
ai commented 8 years ago

@alansouzati because this variables are simple templates. In PostCSS we avoid programming language from CSS, CSS should be declarative.

alansouzati commented 8 years ago

well, even moving font-face to be inside a mixin it does not work. Whenever I take @font-face out of the root structure on the css file it stops working.

This does not work

@define-mixin metric-font $type, $weight {
  @font-face {
    font-family: "Metric";
    src: url("https://path.to.font/MetricHPE-Web-Regular.woff") format('woff');
    font-weight: normal;
  }  
}

@mixin metric-font Regular, normal;

@value font: 'Metric', Arial, sans-serif;

This does work:

@font-face {
  font-family: "Metric";
  src: url("https://path.to.font/web/MetricHPE-Web-Regular.woff") format('woff');
}

@value font: 'Metric', Arial, sans-serif;

You can see that even without any dynamic attribute inside the mixin, it does not seem to like it.

ai commented 8 years ago

Why it doesn't work? What is output?

ai commented 8 years ago

@alansouzati what is your output for this input:

@define-mixin metric-font $type, $weight {
  @font-face {
    font-family: "Metric";
    src: url("https://path.to.font/MetricHPE-Web-Regular.woff") format('woff');
    font-weight: normal;
  }  
}

@mixin metric-font Regular, normal;

@value font: 'Metric', Arial, sans-serif;

Why it doesn’t work?