How to load background-image into a <div>

hi there,

I want to fetch the first image (if there is one) that was uploaded to my page, and make a background-image out of it that repeats over the page.

The first puzzle piece I found in the docs.

HTML

<?php if($image = $page->image()): ?>
<img class="background-image" src="<?= $image->url() ?>" alt="">
<?php endif ?>

The code checks, if there is an image available, then fetches it and loads it in the src-attribute of the img.

It works, and gets displayed. But the image cannot be repeated. The following CSS works with the img, but it won’t repeat.

CSS

/* index.css — works but does not repeat */
.background-image {
height: auto;
repeat: repeat-x;
position: fixed;
z-index: -500;
}

I thought: okay, it has something to do with the img. I probably need to use a div instead. I tried it like that…

HTML

<?php if($image = $page->image()): ?>
<div class="background-image" style="background-image: url(<?= $image->url() ?>); background-repeat: repeat;" width="<?=$image->width()?>px" height="<?=$image->height()?>px"></div>
<?php endif ?>

Unfortunately the div does not display anything…which means that the background-image does not load, right? … But when I look into the source code, the URL is correct.

HTML

… < div class=ā€œbackground-imageā€ style=ā€œbackground-image: url(http://localhost/brachland/media/pages/arts/1116531670-1577032718/bckgrnd_test.png); background-repeat: repeat;ā€ width=ā€œ1280pxā€ height=ā€œ1024pxā€ >< /div >

If I type the URL into the browser, I can see the image.
Why can’t I see the background-image of my div?

Its possibly the z-index: -500;. They should start from 1. Negative numbers put it behind the page. Its also a large image, so you need a screen larger then 1280px by 1024px to see it repeat.

Why not do it on the body element instead? Using empty tags for things like this is bad practice.

The width and height also needs to be in the style attritbute, not as properties on the div. It might be because it has no height.

1 Like

The problem is that your width and height attributes are not correct, they should be part of the style attribute:

<div class="background-image" style="background-image: url(<?= $image->url() ?>); background-repeat: repeat; width:<?=$image->width() ?>px height:<?=$image->height() ?>px"></div>

The way you used the width and height attributes can also be used on images.

The img tag displays an image, not a background image, so the div approach with inline styles is correct.

Just noticed @jimbobrjames already wrote that above…

1 Like

Thanks you both! The solution is the following approach…

  1. Keep the width and height in the style.
  2. And in the sense of best-practice… define the background-image in the body instead of div.

This code-piece solved my question.

HTML

<?php if($image = $page->image()): ?>

< body style=ā€œbackground-image: url(<?= $image->url() ?>); background-repeat: repeat; width:<?=$image->width() ?>px height:<?=$image->height() ?>pxā€>

<?php endif ?>

CSS

body {
background-attachment: fixed;
background-position: left;
}

Oh no, don’t make the body tag depending on an image being present.

<?php $imageUrl = ($image = $page->image())? $image->url() : ''; ?>
<body style="background-image: url($imageUrl);" /* rest of styles */>

When I add a static URL of an image in the body, then it works like a fallback.

CSS

body {
background-image: url(ā€œhttp://localhost/brachland/assets/img/bckgrnd_test.pngā€);
background-repeat: repeat;
background-attachment: fixed;
background-position: left;
}

And when there IS an image uploaded on the page, this one gets displayed.

It works for me, but is there a better practice?
EDIT: Ah, you already written something.

The body tag is a required tag, and the way you had it means the page will only get an opening body tag if the image is available. If it’s not, then you will end up with invalid HTML.

Your inline CSS will not be overwritten with styles from the stylesheet. You have to add your fallback image inline in this case.

Aaaah, I see what you mean! Making the body dependable is a really, really bad idea… haha :smiley:

@texnixe Unfortunately, your last code did not work for me. Don’t know why.

I wrote it like this, and now logically, if there is no image for the background-image-code, there is an else in which the body-tag gets executed either way.

HTML

<?php if($image = $page->image()): ?>

< body style=ā€œbackground-image: url(<?= $image->url() ?>); background-repeat: repeat; width:<?=$image->width() ?>px height:<?=$image->height() ?>pxā€>

<?php else : ?>

< body class=ā€œfallbackā€>

<?php endif ?>

CSS

body {
background-repeat: repeat;
background-attachment: fixed;
background-position: left;
}

.fallback {
background-image: url(ā€˜http://localhost/brachland/assets/img/bckgrnd_test.png’);
}

Sorry, I forgot the PHP tags :see_no_evil:. Nevertheless, I’d do it differently:

<?php $imageUrl = ($image = $page->image())? $image->url() : 'http://localhost/brachland/assets/img/bckgrnd_test.png'; ?>
<body style="background-image: url(<?= $imageUrl ?>);" /* rest of styles */>
1 Like

Yes, that works and looks like eloquently written code. :slight_smile:
Thank you both very much! Most appreciated.

EDIT: I noticed that NOT the first image… that was uploaded to the page panel… gets selected and displayed, BUT the first image that comes first alphabetically, and numbers before letters . So image '1abc.jpg' gets selected, rather than 'acb1.jpg'. [!] It does not matter in what order they appear in the page panel.

To truly select the image that is at the top of the panel image-upload-list… I added a sortBy…
$image = $page->images()->sortBy('sort','1')->first())? $image->url() :

HTML

<?php $imageUrl = ($image = $page->images()->sortBy('sort','1')->first())? $image->url() : 'URL-to-fallback-image.jpg'; ?>

< body style=ā€œbackground-image: url(<?= $imageUrl ?>);ā€ />

Should be sortBy('sort', 'desc') or sortBy('sort', 'asc'), passing the string 1 as second parameter doesn’t make sense.

And yes, if you manually sort image in the Panel, you have to also sort them in the frontend, otherwise the standard sort order is the order in the file system.

1 Like

Thank you texnixe! :slight_smile: frohe Weihnachten!

Danke, @Huhnapfel, ebenfalls frohe Weihnachten! :christmas_tree: :gift: