Rails:如何在Rails 4中引用CSS中的图像

215

在Heroku上,Rails 4存在一个奇怪的问题。当图像被编译时,它们会添加哈希值,但是在CSS中对这些文件的引用没有正确地调整名称。我是这个意思。我有一个名为logo.png的文件。但是当它出现在Heroku上时,它被视为:

/assets/logo-200a00a193ed5e297bb09ddd96afb953.png

然而CSS仍然声明:
background-image:url("./logo.png");

结果是:图片没有显示。有人遇到过这种情况吗?如何解决?

1
只是提供信息,Heroku已经确认这是一个bug...他们正在努力解决。 - Nick ONeill
你能否更新一下这个问题吗?我也遇到了同样的问题。 - Minh Danh
17个回答

408

Sprockets与Sass一起提供了一些实用的辅助功能,可以帮助您完成工作。只有当您的样式表文件扩展名为.css.scss.css.sass时,Sprockets才会处理这些辅助功能。单击此处了解更多信息。


特定于图像的辅助功能:

background-image: image-url("logo.png")

不可知论者助手:

background-image: asset-url("logo.png", image)
background-image: asset-url($asset, $asset-type)
如果您想在css文件中嵌入图像数据:
background-image: asset-data-url("logo.png")

23
在我将Rails 4应用程序中的.css文件更改为.css.scss文件后,asset-data-url对我有用。谢谢! - fatman13
@fatman13 是的,据我所知,这只适用于 .scss 和 .sass 文件。 - zeeraw
Jeff:只要您的资产URL选项设置正确,其他人就可以正常工作。这不适用于“asset-data-url”,因为它将整个文件嵌入样式表中。 - zeeraw
1
与@fatman13类似,由于我正在使用sass-rails,最终我添加了文件扩展名.scss到有问题的.css文件中,以便它们都以.css.scss结尾,然后将所有url('blah.png')的实例替换为url(asset-path('blah.png'))(在我的情况下,所有的blah.png都在一个/vendor文件夹中)。 - likethesky
asset-url($asset) 应该用于 Sprockets 3,带 $asset-type 的版本可能适用于一些旧版本。 - prusswan
使用 image-url 相对于 asset-url 有什么好处? - Joshua Pinter

60

不知道为什么,但对我起作用的唯一方法是使用asset_path而不是image_path,即使我的图像位于assets/images/目录下:

示例:

app/assets/images/mypic.png

在 Ruby 中:

asset_path('mypic.png')

在 .scss 文件中:

url(asset-path('mypic.png'))

更新:

找到解决方法- 结果发现这些资产助手来自sass-rails宝石(我已将其安装在我的项目中)。


2
对我来说很有效,真的是非常好的Rails解决方案。感谢@Yarin。 - AMIC MING
1
是的!在我苦思冥想了数小时之后,你提供的“asset-path”解决方案终于在我的.css.scss文件中奏效了!background-image: url(asset-path('off.png')) - Raymond Gan
对于使用Rails 6构建应用的开发者来说,你不需要安装sass-rails gem。这些helpers已经可以直接使用了。 - Promise Preston

37

在Rails 4中,您可以轻松地在.SCSS文件中引用位于assets/images/的图像,如下所示:

.some-div {
  background-image: url(image-path('pretty-background-image.jpg'));
}

当你以开发模式启动应用程序(localhost:3000)时,你应该看到类似于:


background-image: url("/assets/pretty-background-image.jpg");
在生产模式下,您的资产将具有缓存辅助数字:
background-image: url("/assets/pretty-background-image-8b313354987c309e3cd76eabdb376c1e.jpg");

1
@MikeLyons:我刚在一个全新的Rails 4.1项目上测试了它,并部署到Heroku,对我来说运行良好。你一定是在production.rb上做了什么。 - sergserg

25

在您的情况下,文件扩展名应该是什么?只有 .css 对我来说不起作用。 - Arup Rakshit
为我工作!谢谢,兄弟! - Julian Alejandro Sosa

11

在 CSS 中

background: url("/assets/banner.jpg");

尽管原始路径为/assets/images/banner.jpg,但按照惯例,在url方法中只需添加/assets/。


1
使用普通的CSS,我以为自己要疯了——谢谢! - Craig McGuff
2
这段代码不会在生产环境中被编译。 - dimitry_n
哇,谢谢,这不是很直观。所以我猜所有位于资产路径(vendor/assetsapp/assetslib/assets 等)中的资产在预处理完成后都会合并到一个单独的资产文件夹中? - ohhh
这段代码在生产环境下无法正常工作,因为在生产环境中,您的资源文件会被编译,并附加了一个MD5哈希值到文件名的末尾。一般情况下,/assets/banner.jpg将无法正常运行。相反,它会变成类似于/assets/banner-f719451f1e0ddd15f153c4eedde044b2.jpg的东西。 简而言之,请不要使用这个方法。 - Joshua Pinter

10

没有一个答案提到了我在使用 .css.erb 后缀时如何引用 图片。对我而言,在开发环境生产环境中都可以起作用:

2.3.1 CSS 和 ERB

资产管道会自动评估ERB。这意味着如果您将erb扩展名添加到CSS资产(例如application.css.erb),则可以在CSS规则中使用asset_path等帮助程序:

.class { background-image: url(<%= asset_path 'image.png' %>) }

此代码将写入引用的特定资源的路径。在此示例中,应该在资产加载路径之一中有一张图片,例如 app/assets/images/image.png,将在此处引用。如果此图像已经作为指纹文件可在 public/assets 中使用,则引用该路径。

如果您想要使用数据 URI - 将图像数据直接嵌入到CSS文件中的方法 - 您可以使用 asset_data_uri 帮助程序。

.logo { background: url(<%= asset_data_uri 'logo.png' %>) }

这会将正确格式的数据URI插入到CSS源代码中。

请注意,结束标签不能是样式为 -%> 的形式。


5

只有这段代码对我不起作用:

background-image: url(image_path('transparent_2x2.png'));

但是将 stylename.scss 重命名为 stylename.css.scss 对我有所帮助。

4
参考Rails文档,我们发现有几种在css中引用图片的方法。请转到2.3.2节。
首先,请确保您的css文件具有.scss扩展名(如果是sass文件)。
接下来,可以使用Ruby方法,这样做非常丑陋:
#logo { background: url(<%= asset_data_uri 'logo.png' %>) }

或者您可以使用更加美观的特定表单:

image-url("rails.png") returns url(/assets/rails.png)
image-path("rails.png") returns "/assets/rails.png"

最后,您可以使用通用表单:
asset-url("rails.png") returns url(/assets/rails.png)
asset-path("rails.png") returns "/assets/rails.png"

4
经过数小时的调试,我发现以下情况可行:
正常工作:
background-image: url(image_path('transparent_2x2.png')); 

// how to add attributes like repeat, center, fixed?

上面的代码会输出类似于:"/assets/transparent_2x2-ec47061dbe4fb88d51ae1e7f41a146db.png"
请注意前导斜杠引号内部的内容。 同时,请注意在你的 stylesheet.css.scss 中使用了 scss 扩展和 image_path 助手。图片位于 app/assets/images 目录中
以下代码无效:
background: url(image_path('transparent_2x2.png') repeat center center fixed;

无法工作,属性无效:

background:url(/assets/pretty_photo/default/sprite.png) 2px 1px repeat center fixed;

我的最后一招是将它们放在公共的S3存储桶中,并从那里加载,但最终我成功了。


对于任何仍然有困难的人:请确保您的CSS文件已更新,并且您没有在本地预编译资产并忘记更新它们。 - Hartwig
Hartwig - 这是什么意思?你的意思是在这个方法能够工作之前,你必须再次运行预编译吗?我已经尝试了这篇帖子中提出的所有建议(全部),但对我来说都没有用。 - Mel

4
有趣的是,如果我使用 'background-image',它不起作用:
background-image: url('picture.png');

但是仅仅是“背景”,它的作用如下:
background: url('picture.png');

但这仅适用于在scss文件中使用,而不适用于在div的样式属性分配中使用...我很困惑。 - AnderSon
背景:url('picture.png'); 适用于Rails 7 - valk
背景: url('picture.png'); 在Rails 7中有效 - valk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接