skip to Main Content

I am unable to put a background image into the <style> tags and I don’t know why it’s not working.

All of the following was done on my local machine. My website is also hosted on a Linode server.

I have the following code, which works fine. It sets the background image in a style directly in the div within the body (via Django):

<body>
    <div class="scroll-container" style="background-image: url('{% static 'myapp/scroll-L.jpg' %}');">
    </div>
</body>

And when I load the page you can see the scroll image loads fine (image1 https://i.imgur.com/T75mFyl.png)

However when I put the background image into the <style> tag in the <head> everything starts to go wrong:

<style>
    .scroll-container {
        background-image: url("../../static/myapp/scroll-L.jpg")
    }
</style>

When I load the page you can see the scroll image doesn’t load (image2 https://i.imgur.com/RCsWhE7.png)

I can’t use Django’s {% static ... %} within the head style tags so that didn’t work.

It’s clearly something to do with the object storage (eu-central-1.linodeobjects) but I don’t know what. Why would it work when using the image in the div style and not within the style tags?

I’ve searched around for about 2 hours trying to find a fix but I can’t figure it out.

The file path is correct however just for confirmation I have tried the following with no success:

.scroll-container {
    background-image: url("static/myapp/scroll-L.jpg")
}

.scroll-container {
    background-image: url("/static/myapp/scroll-L.jpg")
}

.scroll-container {
    background-image: url("/../../static/myapp/scroll-L.jpg")
}

{% load static %}
.scroll-container {
    background-image: url("{% static 'myapp/scroll-L.jpg' %}")
}

And I need to do something other than put the background image directly in the div because I am sorting out the CSP for my site, and I can’t set a nonce or hash for it if it is a style set directly to the div.

I also tried putting the image directly in the templates folder so that I could just call:

.scroll-container {
    background-image: url("scroll-L.jpg")
}

However that didn’t work either. I also tried putting it into the master.css with little success.

EDIT: Here is the code for my object storage in settings.py:

# Object Storage for Django static files (https://www.codingforentrepreneurs.com/blog/linode-object-storage-for-django-static-files/)
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
}

LINODE_BUCKET = os.environ.get('LINODE_BUCKET', 'hmst-bucket')
LINODE_BUCKET_REGION = os.environ.get('LINODE_BUCKET_REGION', 'eu-central-1')
LINODE_BUCKET_ACCESS_KEY = os.environ.get('LINODE_BUCKET_ACCESS_KEY', '#')
LINODE_BUCKET_SECRET_KEY = os.environ.get('LINODE_BUCKET_SECRET_KEY', '#')

AWS_S3_ENDPOINT_URL = f'https://{LINODE_BUCKET_REGION}.linodeobjects.com'
AWS_ACCESS_KEY_ID = LINODE_BUCKET_ACCESS_KEY
AWS_SECRET_ACCESS_KEY = LINODE_BUCKET_SECRET_KEY
AWS_S3_REGION_NAME = LINODE_BUCKET_REGION
AWS_S3_USE_SSL = True
AWS_STORAGE_BUCKET_NAME = LINODE_BUCKET

AWS_DEFAULT_ACL = None

2

Answers


  1. Chosen as BEST ANSWER

    Here was a fix for anybody that has the same problem in the future.

    Instead of calling the file path to the background image, I instead called the image from my Object Storage bucket directly:

    <style>
        .scroll-container {
            background-image: url("https://hmst-bucket.eu-central-1.linodeobjects.com/myapp/scroll-L.jpg");
        }
    </style>
    

    This then gave a 403 (Forbidden error) with the following message when I tried to open the image:

    This XML file does not appear to have any style information associated with it. The document tree is shown below.
    <Error>
    <Code>AccessDenied</Code>
    <BucketName>hmst-bucket</BucketName>
    <RequestId>#</RequestId>
    <HostId>#</HostId>
    </Error>
    

    So I then needed to change the permissions of the Access Control Lists (ACLs). I changed the Bucket Level ACLs and the Object Level ACLs of my object storage from Private to Public Read.

    I use Linode, so to do this I followed this guide: https://www.linode.com/docs/products/storage/object-storage/guides/acls/. To change the Object Level ACL the guide says you'll need to click the more options ellipsis and select Details, however this is out-dated and you'll need to click the actual object itself.

    Changing these permissions fixed the issue.


  2. You want to use s3 storage as CloudFront(CDN). So you need to config AWS_S3_CUSTOM_DOMAIN variable.

    AWS_S3_CUSTOM_DOMAIN = 'cdn.mydomain.com'
    

    Official django-storages documentation. Click to check

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search