Как использовать ссылочные изображения в Sass при использовании Rails 3.1?
У меня есть проект Rails 3.1, работающий отлично. Проблема в том, что мне нужно ссылаться на изображения в моем Sass, но Rails вычисляет URL-адреса изображений. (Это особенно важно при производстве, когда Rails добавляет хэш файл Git изображения к его имени файла для перебора кешей.)
Например, в app/assets/stylesheets/todos.css.scss
:
.button.checkable { background-image: url(/assets/tick.png); }
Когда я развертываю (или запускаю rake assets:precompile
), файл app/assets/images/tick.png
перемещается в public/assets/tick-48fe85c0a.png
или что-то подобное. Это нарушает CSS. Этот пост содержит два предложения:
- не используйте конвейер объектов для изображений - вместо этого разместите их в
public/images/
и обратитесь к ним напрямую
- используйте ERB для вашего CSS и пусть Rails разработает URL-адрес изображения.
Номер 1 - это, конечно, возможность, хотя это означает, что я не получаю кэширование на своих изображениях. Номер 2 отсутствует, потому что я использую Sass, а не ERB для обработки файлов.
Ответы
Ответ 1
Следующее должно сделать трюк:
.button.checkable { background-image: url(image_path('tick.png')); }
Рельсы на самом деле предоставляют кучу помощников для ссылки на активы:
image-url('asset_name')
audio-path('asset_name')
В общем
[asset_type]-url('asset_name') #Becomes url('assets/asset_name')
[asset_type]-path('asset_name') #Becomes 'assets/asset_name'
asset_type может быть одним из следующих: образ, шрифт, видео, аудио, javascript, таблица стилей
Ответ 2
sass-rails gem определяет функции Sass, которые могут использоваться от Sass без обработки ERB.
https://github.com/rails/sass-rails
Ответ 3
Для тех, кто выступает за более быстрое время загрузки для пользователей, могу ли я предложить следующий совет Стива Соудерса для загрузки изображений в CSS в base64.
активов данных URL ( 'путь')
https://github.com/rails/sass-rails#asset-helpers
Ответ 4
Вариант варианта 2 будет работать. Если у вас есть что-то вроде этого:
app/assets/stylesheets/pancakes_house.css.less.erb
И вы require
в свой application.css
файл. Затем pancakes_house
сначала проходит через ERB, и этот выход проходит через процессор LESS, и все, что выходит из этого, входит в ваш CSS. Ввод ERB внутри вашего SCSS может показаться немного странным, но, эй, он будет работать и выполнять работу без излишней странности.
Итак, вы должны иметь возможность получить необходимые методы для создания путей кэш-распаковки изображений через ваш ERB.
Я только пробовал это с файлом Less, но он также должен работать с .css.scss.erb
.
В качестве альтернативы вы также можете добавить свои собственные функции в SASS:
Методы в этом модуле доступны из контекста SassScript. Например, вы можете написать
$color = hsl(120deg, 100%, 50%)
и он вызовет Sass::Script::Functions#hsl
.
Есть даже некоторые инструкции по написанию собственных функций чуть дальше в руководстве. Однако я не уверен, как заставить Sprockets загружать ваши патчи Sass::Script::Functions
, поэтому я не могу назвать это практическим решением; кто-то с более сильным Sprocket Fu, чем я, мог бы заставить этот подход работать, хотя я бы назвал это более элегантным, чем ERBified SCSS.
Ответ 5
Вы можете легко использовать номер 2, просто добавьте расширение .erb
в файл .scss
:
app/assets/stylesheets/todos.css.scss.erb
и используйте метод asset_path
, чтобы получить путь к изображению с хешем:
.button.checkable { background-image: url('<%= asset_path 'tick.png' %>'); }
этот файл будет обработан erb, а затем sass.
Ответ 6
При использовании конвейера ресурсов пути к активам должны быть переписаны, а sass-rails предоставляет помощники -url и -path (переносимые в Sass, подчеркнутые в Ruby) для следующих классов активов: изображение, шрифт, видео, аудио, JavaScript и таблицы стилей.
image-url ( "rails.png" ) возвращает url (/assets/rails.png) image-path ( "rails.png" ) возвращает "/assets/rails.png"
Можно также использовать более общую форму:
asset-url ( "rails.png" ) возвращает url (/assets/rails.png) resource-path ( "rails.png" ) возвращает "/assets/rails.png"