Dynamic Full Page Background Images in Rails

Dynamic Full Page Background Images in Rails


rails css helpers
Last updated on

Note (Updated 2025): This post was originally written in 2020. The CSS approach using background-size: cover is still valid. For modern projects, you can also use CSS variables, utility frameworks (TailwindCSS), or inline style bindings (via Stimulus/React/Vue) to dynamically manage backgrounds more flexibly.


You can set a background image purely through CSS thanks to the background-size property in CSS3. Using the html element is better than body, as it’s always at least the height of the browser window. You set a fixed and centered background on it, then adjust its size using background-size: cover.

html {
  background: asset-url('background.png') no-repeat center center fixed;
  -webkit-background-size: cover;
  -moz-background-size: cover;
  -o-background-size: cover;
  background-size: cover;
}

Background Image Per Layout

You can use a view helper to conditionally set the background per layout:

module ApplicationHelper
  def html_background
    # Add logic here if some layouts shouldn’t have a background
    "background-image: url('background.png');"
  end
end

And then in your layout:

doctype html
html style=html_background
  head
    meta http-equiv='X-UA-Compatible' content='IE=edge'
    meta name='viewport' content='width=device-width, initial-scale=1'
    title = t('.meta_title')
    = csrf_meta_tags
    = stylesheet_link_tag    'application', media: 'all'
    = javascript_include_tag 'application'
  body
    = yield

Randomizing Backgrounds

You can also cycle background images automatically (e.g., one per day). First define a helper:

def background_images
  Array.new(7) { |i| "backgrounds/background-#{i}.png" }
end

To avoid randomness on every re-render, base the selection on today’s date:

def randomized_background_image
  background_images[Date.today.day % 7]
end

Full Example

module ApplicationHelper
  RANDOM_BACKGROUND_IMAGES_COUNT = 7

  def html_background
    "background-image: url('assets/#{randomized_background_image}');"
  end

  def randomized_background_image
    background_images[Date.today.day % RANDOM_BACKGROUND_IMAGES_COUNT]
  end

  def background_images
    Array.new(RANDOM_BACKGROUND_IMAGES_COUNT) { |i| "backgrounds/background-#{i}.png" }
  end
end

Testing the Helpers

require 'spec_helper'

describe ApplicationHelper do
  describe '#background_images' do
    it 'returns an array of 7 image paths' do
      images = helper.background_images
      expect(images).to be_a(Array)
      expect(images.size).to eq(7)
    end

    it 'returns images in sequence with path' do
      image = helper.background_images.first
      expect(image).to match('backgrounds/background-0.png')
    end
  end

  describe '#randomized_background_image' do
    it 'returns expected image path' do
      image = helper.randomized_background_image
      expected_image_path = "backgrounds/background-#{Date.today.day % 7}.png"
      expect(image).to eq(expected_image_path)
    end
  end
end

Modern Alternatives (2025)

  • TailwindCSS utilities: apply dynamic backgrounds with bg-[url(‘/path/to/image’)].
  • CSS variables: set --bg-url dynamically and use it in your CSS.
  • Stimulus/React/Vue: bind styles to state for runtime control.
  • Randomization: use JS (Math.random) if you want different images per refresh, instead of per day.

Wrap-up

  • In 2020, CSS3’s background-size: cover combined with Rails helpers was a clean solution for full-page backgrounds.
  • Today, frameworks and modern CSS features make it easier to apply and rotate dynamic backgrounds with less custom code.
  • The idea of date-based cycling remains a neat trick if you want predictable but changing visuals.

Quick Comparison

ApproachWhere it ShinesProsCons
Rails Helper (this post)Simple, works server-sideNo JS required, predictable, testableLimited flexibility, page reload needed
Stimulus ControllerRails 7+ apps using Hotwire/TurboDeclarative, client-side updates, reusableSlightly more setup, JS knowledge needed
TailwindCSS UtilitiesApps already using TailwindOne-liner backgrounds, responsive utilitiesStatic unless paired with JS/variables
CSS VariablesModern CSS-driven design systemsEasy theming, works with any frameworkRequires careful setup and browser support
React/Vue/JS BindingSPA or component-driven UIsFull dynamic control at runtimeOverkill for simple Rails views

You might also like

© 2025 Syed Aslam