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

Nested @font-face results in invalid syntax #1251

Closed
atombender opened this issue May 16, 2014 · 12 comments · Fixed by sass/dart-sass#1899
Closed

Nested @font-face results in invalid syntax #1251

atombender opened this issue May 16, 2014 · 12 comments · Fixed by sass/dart-sass#1899
Assignees
Labels
bug Something isn't working

Comments

@atombender
Copy link

Input:

.foo {
  @font-face {
   font-family: "Ionicons";
   src:url("../fonts/ionicons.eot?v=1.4.0");
   src:url("../fonts/ionicons.eot?v=1.4.0#iefix") format("embedded-opentype"),
    url("../fonts/ionicons.ttf?v=1.4.0") format("truetype"),
    url("../fonts/ionicons.woff?v=1.4.0") format("woff"),
    url("../fonts/ionicons.svg?v=1.4.0#Ionicons") format("svg");
   font-weight: normal;
   font-style: normal;
  }
}

Result:

@font-face {
  .foo {
    font-family: "Ionicons";
    src: url("../fonts/ionicons.eot?v=1.4.0");
    src: url("../fonts/ionicons.eot?v=1.4.0#iefix") format("embedded-opentype"), url("../fonts/ionicons.ttf?v=1.4.0") format("truetype"), url("../fonts/ionicons.woff?v=1.4.0") format("woff"), url("../fonts/ionicons.svg?v=1.4.0#Ionicons") format("svg");
    font-weight: normal;
    font-style: normal; } }

Could I put the font-face outside? Certainly, but what I am attempting here to wrap an entire stylesheet (imports and all) in an outer selector, to provide a stylesheet for an embeddable widget that must not clobber any other styles on the page. I can move fonts outside the top-level selector, but it does make my stylesheets more awkward, and I have to break them up more.

@nex3 nex3 added the Bug label May 16, 2014
@apfelbox
Copy link

Does this work for you?

.foo {
  @at-root {
    @font-face {
     font-family: "Ionicons";
     src:url("../fonts/ionicons.eot?v=1.4.0");
     src:url("../fonts/ionicons.eot?v=1.4.0#iefix") format("embedded-opentype"),
      url("../fonts/ionicons.ttf?v=1.4.0") format("truetype"),
      url("../fonts/ionicons.woff?v=1.4.0") format("woff"),
      url("../fonts/ionicons.svg?v=1.4.0#Ionicons") format("svg");
     font-weight: normal;
     font-style: normal;
    }
  }
}
@chriseppstein
Copy link

Why are you nesting this?

Edit: I see your explanation now. @apfelbox is right, you need to use @root with this.

@nex3 I think it's a bug that @font-face bubbles.

@atombender
Copy link
Author

First of all, it is a bug, so regardless of my use case, there is an issue to be fixed.

Secondly, the @at-root fixes things. Thanks, I didn't know about it.

As for my particular use case, yes: I can of course declare the font outside. In this particular case, I am using the Ionicons SASS package, which declares both classes (which need to be nested) and a font-face (which cannot). I prefer to rely on pristine thirdparty code, not fork it or copy it. I could import it piecemeal, but I think the best solution is to tell the Ionicons people to use @at-root. I'm going to do that.

@nex3
Copy link
Contributor

nex3 commented May 30, 2014

@chriseppstein Handling this is an interesting question. It's an intentional feature that unknown directives are bubbled (b8f4bab), and currently we have no special logic for @font-face so it falls into this category.

I'm a little leery of adding this sort of special logic; it violates our general policy of encoding the semantics of specific CSS identifiers as little as possible. If we add support for top-level-only directives, we'll need to do so for all directives that we currently know are top-level-only, which in turn means that new directives that are top-level-only may violate user expectations. I'd kind of prefer to just leave the behavior as-is.

@therealparmesh
Copy link

therealparmesh commented Sep 28, 2016

In a project with CSS/SASS modules, this can come back to bite you if your dependencies don't write good CSS/SASS. I recognize the wariness towards adding special logic, but this is a valid use case without a great solution right now.

@deser
Copy link

deser commented Jun 12, 2017

I'd kind of prefer to just leave the behavior as-is.

Hi Guys, this is abnormal behavior. Sometimes it's impossible to wrap directives into @at-root. Example: I'm using font-awesome and want to restrict it by wrapping into higher order css class to prevent css class name collisions ( I need to embed my site into another one where the same libraries could be used with different overrides).

@sass sass deleted a comment from deser Jun 13, 2017
@rdsedmundo
Copy link

Same here. I'm trying to import an external module that uses @font-face.

@sambhav-gore
Copy link

sambhav-gore commented Jan 19, 2018

Same here. Sometimes it is not possible to add the @root directive when importing a third-party lib for example, which has the font-face declaration.

@soanvig
Copy link

soanvig commented May 18, 2018

Bump, I would like during compilation step to scope my CSS to some class or ID. I cannot do it now, because simple wrapping produces invalid @font-face rules. It's a but, really.

@chriseppstein
Copy link

There is not currently a guarantee from Sass that any Sass file can be @imported into any context. For instance, if you try .foo { @import "some-module"; } you will get an error if some-module defines a mixin. In general, you should expect that to work exactly the same as if you wrote the same sass code inline where the import statement is.

Personally, I think it's ok to define logic specific to @font-face because we know what its definition and semantics are and they don't match the generic definition and it enables interesting use cases. At the very least, I think Sass should raise an error if the directive is used illegally. It would help users debug quicker.

@GottZ
Copy link

GottZ commented Oct 11, 2019

@keyframes will be placed in root no matter how you nest them.
@font-face results in invalid css and thus have no effect on the outcome.
why do they behave differently and not the same? in my opinion either both should fail or both should work. everything else is wrong.

why this problem is still relevant in 2019:

  • legacy code
  • trying to modularize legacy code for an attempted code base rewrite
  • continuing development on a legacy plugin for a random legacy cms with some kind of pseudo namespacing
  • using legacy libraries that fail to provide @at-root properly and cannot easily be replaced
  • 100% correct sass development is impossible to achieve at times. pareto principle should explain this well enough.

just let me drop this here to express what this issue can cause to many developers world wide that have to deal with bad code all the time: https://dilbert.com/strip/2000-05-21

this change would essentially help people to migrate legacy to new code with less headache

@GottZ

This comment was marked as spam.

@Goodwine Goodwine self-assigned this Mar 1, 2023
@Goodwine Goodwine reopened this Mar 1, 2023
Goodwine added a commit to sass/dart-sass that referenced this issue Mar 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working