Como referenciar imagens em CSS no Rails 4

205

Há um problema estranho com o Rails 4 no Heroku. Quando as imagens são compiladas, eles adicionam hashes, mas a referência a esses arquivos no CSS não tem o nome adequado ajustado. Aqui está o que eu quero dizer. Eu tenho um arquivo chamado logo.png. No entanto, quando aparece no heroku, é visto como:

/assets/logo-200a00a193ed5e297bb09ddd96afb953.png

No entanto, o CSS ainda afirma:

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

O resultado: a imagem não é exibida. Alguém encontrou isso? Como isso pode ser resolvido?

Nick ONeill
fonte
1
Apenas FYI, Heroku confirmou que é um erro ... eles estão trabalhando em uma solução
Nick ONeill
Você pode dar uma atualização sobre isso? Estou tendo o mesmo problema
Minh Danh

Respostas:

392

As rodas dentadas, juntamente com Sass, têm alguns ajudantes bacanas que você pode usar para fazer o trabalho. Rodas dentadas será única processar esses ajudantes se suas extensões de arquivo de estilo ou são .css.scssou .css.sass.


Auxiliar específico da imagem:

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

Auxiliar agnóstico:

background-image: asset-url("logo.png", image)
background-image: asset-url($asset, $asset-type)

Ou se você deseja incorporar os dados da imagem no arquivo css:

background-image: asset-data-url("logo.png")
Zeeraw
fonte
21
asset-data-urlfunciona para mim depois que alterei meu arquivo .css para o arquivo .css.scss em um aplicativo do Rails 4. Obrigado!
precisa saber é o seguinte
@ fatman13 Sim, isso funciona apenas com arquivos .scss e .sass até onde eu sei.
precisa saber é o seguinte
Jeff: Os outros funcionam, desde que as opções de URL do seu recurso estejam configuradas corretamente. Ele não se aplica, asset-data-urlpois incorpora o arquivo inteiro na folha de estilo.
zeeraw
1
Semelhante a @ fatman13 desde que eu estava usando sass-rails, finalmente acabei adicionando a extensão .scssao (s) arquivo (s) .css ofensivos, para que todos terminem .css.scsse substituam todas as instâncias de url('blah.png')with url(asset-path('blah.png'))(no meu caso, todos os blah.pngs estavam em um /vendored pasta).
likethesky
asset-url($asset)deve ser usado para rodas dentadas 3, a versão com $asset-typeprovavelmente funciona com alguma versão mais antiga
prusswan
59

Não sei por que, mas a única coisa que funcionou para mim foi usar asset_path em vez de image_path , mesmo que minhas imagens estejam no diretório assets / images / :

Exemplo:

app/assets/images/mypic.png

Em Ruby:

asset_path('mypic.png')

Em .scss:

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

ATUALIZAR:

Achei que esses auxiliares de recursos provêm da gema sass-rails (que eu havia instalado no meu projeto).

Yarin
fonte
2
funciona para mim, realmente muito boa solução rails way. Obrigado @Yarin
AMIC MING
1
Sim! Após várias horas batendo minha cabeça na parede, sua solução "caminho do ativo" finalmente funcionou para mim no meu arquivo .css.scss! background-image: url(asset-path('off.png'))
Raymond Gan
36

No Rails 4, você pode fazer referência a uma imagem localizada assets/images/nos seus .SCSSarquivos facilmente desta forma:

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

Ao iniciar o aplicativo no modo de desenvolvimento ( localhost:3000), você verá algo como:

background-image: url("/assets/pretty-background-image.jpg");

No modo de produção, seus ativos terão os números auxiliares de cache:

background-image: url("/assets/pretty-background-image-8b313354987c309e3cd76eabdb376c1e.jpg");
sergserg
fonte
1
@ MikeLyons: Acabei de testá-lo em um novo projeto do Rails 4.1 e implantado no Heroku, e está funcionando bem para mim. Você deve ter tocado em algo production.rb.
Sergserg #
25

O hash ocorre porque o pipeline de ativos e o servidor Optimize caching http://guides.rubyonrails.org/asset_pipeline.html

Tente algo como isto:

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

Boa sorte

Mauro Dias
fonte
Trabalhou para mim! Obrigado :) #
Daniel Daniel
No seu caso, qual deve ser a extensão do arquivo? Só .cssnão funcionou para mim.
Arup Rakshit
Trabalhe para mim! Obrigado mano!
AlejandroJSR7
11

Em css

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

embora o caminho original seja /assets/images/banner.jpg, por convenção, você deve adicionar apenas / assets / no método url

user2458192
fonte
1
Usando CSS simples, pensei que estava ficando louco - obrigado!
Craig McGuff
2
isso não será compilado na produção
dimitry_n
Uau, obrigado, isso não é muito intuitivo. Então eu acho que todos os ativos nos caminhos de ativos ( vendor/assets, app/assets, lib/assets, etc) se combinados em um único ativo pasta após prepossessing está completa?
ohhh
Isso não funcionará na Produção, porque na Produção seus recursos são compilados com um hash MD5 afixado no final do nome e, com configurações típicas, /assets/banner.jpgnão funciona. Em vez disso, será algo parecido /assets/banner-f719451f1e0ddd15f153c4eedde044b2.jpg. TL; DR Não use isso.
Joshua Pinter
10

Nenhuma das respostas diz sobre o caminho, quando terei .css.erbextensão, como fazer referência a imagens . Para mim, trabalhei tanto na produção quanto no desenvolvimento :

2.3.1 CSS e ERB

O pipeline de ativos avalia automaticamente o ERB . Isso significa que, se você adicionar uma extensão erb a um ativo CSS (por exemplo application.css.erb), auxiliares como asset_pathestão disponíveis nas suas regras CSS:

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

Isso grava o caminho para o ativo específico que está sendo referenciado. Neste exemplo, faria sentido ter uma imagem em um dos caminhos de carregamento de ativos, como app/assets/images/image.png, que seria referenciado aqui. Se essa imagem já estiver disponível public/assetscomo um arquivo com impressão digital, esse caminho será referenciado.

Se você deseja usar um URI de dados - um método para incorporar os dados da imagem diretamente no arquivo CSS - você pode usar o asset_data_uriauxiliar.

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

Isso insere um URI de dados formatado corretamente na fonte CSS.

Observe que a tag de fechamento não pode ser do estilo -%>.

Arup Rakshit
fonte
5

Somente este trecho não funciona para mim:

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

Mas renomear stylename.scss para stylename.css.scss me ajuda.

s.vatagin
fonte
4

Fazendo referência aos documentos do Rails , vemos que existem algumas maneiras de vincular imagens a partir de css. Basta ir para a seção 2.3.2.

Primeiro, verifique se o seu arquivo css tem a extensão .scss, se for um arquivo sass.

Em seguida, você pode usar o método ruby, que é realmente feio:

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

Ou você pode usar o formulário específico mais agradável:

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

Por fim, você pode usar o formulário geral:

asset-url("rails.png") returns url(/assets/rails.png)
asset-path("rails.png") returns "/assets/rails.png"
Nick Res
fonte
3

O QUE EU ENCONTREI APÓS HORAS DE MUCKING COM ESTE:

TRABALHO :

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

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

O resultado acima gera algo como: "/assets/transparent_2x2-ec47061dbe4fb88d51ae1e7f41a146db.png"

Observe o "/" inicial e está entre aspas . Observe também a extensão scss e o auxiliar image_path em yourstylesheet.css.scss. A imagem está no diretório app / assets / images .

Não funciona:

background: url(image_path('transparent_2x2.png') repeat center center fixed;

não funciona, propriedade inválida:

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

Meu último recurso seria colocá-los no meu balde público s3 e carregar a partir daí, mas finalmente consegui algo.

Danny
fonte
Para quem vem aqui e ainda tem problemas: verifique se o seu arquivo css está atualizado e se você não pré-compilou seus ativos localmente e esqueceu de atualizá-los.
Hartwig
Hartwig - o que isso significa? Quer dizer que você precisa executar a pré-compilação novamente antes que esse método funcione? Eu tentei de tudo o que é sugerido neste post (tudo) e nada está funcionando para mim #
181
2

Curiosamente, se eu usar 'background-image', ele não funcionará:

background-image: url('picture.png');

Mas apenas 'background', ele faz:

background: url('picture.png');
AnderSon
fonte
mas isso só funciona a partir do arquivo SCSS, não quando colocado em uma atribuição de propriedade de estilo dentro de uma div ... eu sou confundir
Anderson
1

Ao usar o gem 'sass-rails', no Rails 5, bootstrap 4, o seguinte funcionou para mim,

no arquivo .scss:

    background-image: url(asset_path("black_left_arrow.svg"));

no arquivo de visualização (por exemplo, .html.slim):

    style=("background-image: url(#{ show_image_path("event_background.png") })");
Mehreen
fonte
0

Isso deve levá-lo lá todas as vezes.

background-image: url(<%= asset_data_uri 'transparent_2x2.png'%>);
Joshua Nathaniel
fonte
0

Por padrão, o Rails 4 não servirá seus ativos. Para habilitar essa funcionalidade, você precisa acessar o config / application.rb e adicionar esta linha:

config.serve_static_assets = true

https://devcenter.heroku.com/articles/rails-4-asset-pipeline#serve-assets

ksiomelo
fonte
1
Isso funciona, mas isso não desfaz os benefícios de pré-compilar os ativos?
Arcolye
0

No Rails 4, basta usar

.hero { background-image: url("picture.jpg"); }

no seu arquivo style.css, desde que a imagem de plano de fundo esteja dobrada em app / assets / images.

boussac
fonte
Leia a pergunta completa
Adriano Resende
0

Você pode adicionar à sua extensão css .erb. Ej: style.css.erb

Então você pode colocar:

background: url(<%= asset_path 'logo.png' %>) no-repeat;
Matias Seguel
fonte
0

Isso funcionou para mim:

background: #4C2516 url('imagename.png') repeat-y 0 0;
Tolome
fonte