Skip to content
Go back

Dynamic Full Page Background Images in Rails

Updated:
Dynamic Full Page Background Images in Rails

Note (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)


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

Wrap-up


You might also like


Share this post on:

Previous Post
Keeping Array Elements Unique in Ruby
Next Post
Highlighting Current Link in Rails Navigation