|
4 | 4 |
|
5 | 5 | > HTML5-like responsive background images in CSS (sort of …)
|
6 | 6 |
|
7 |
| -## Documentation |
| 7 | +## About |
8 | 8 |
|
9 |
| -Please find the [project documentation](doc/index.md) in the `doc` directory. |
| 9 | +The purpose of *responsive-images-css* is to ease the creation process of responsive background images in CSS. It provides similar semantics as responsive images via `<img srcset="…" sizes="…">` in HTML5. |
| 10 | + |
| 11 | +The rendering sequence of a standard HTML5 responsive (foreground) image is a highly complex process. It's impossible to fully predict which exact image candidate a browser will pick as some decisions may depend on environment settings that are only available at runtime (such as the network performance). |
| 12 | + |
| 13 | +In contrast, *responsive-images-css* generates CSS code on the server-side — that is, long before the browser gets to interpret the generated output. To make this work, some asumptions have to be made: |
| 14 | + |
| 15 | +* The generator needs a fixed **em to pixel ratio** in order to predictably deal with `em` / `rem` values. |
| 16 | +* The generator utilizes the **specified breakpoints** only, even if the image candidates suggest additional steps. |
| 17 | +* The **device densities** (resolutions) for which the CSS should be rendered must be explictly provided. |
| 18 | + |
| 19 | +## Usage |
| 20 | + |
| 21 | +### The generator |
| 22 | + |
| 23 | +Creating a responsive background image always starts with a fresh `Generator` instance: |
| 24 | + |
| 25 | +```php |
| 26 | +use Jkphl\Respimgcss\Ports\Generator; |
| 27 | + |
| 28 | +$breakpoints = ['24em', '36em', '48em']; // CSS Breakpoints |
| 29 | +$emToPixel = 16; // EM to PX ratio |
| 30 | + |
| 31 | +$generator = new Generator($breakpoints, $emToPixel); |
| 32 | +``` |
| 33 | + |
| 34 | +As you see in the example, the `Generator` accepts a list of **CSS breakpoints** and an **`em` to `px` ratio** as constructor arguments. The latter defaults to `16` if omitted. The breakpoints only get used in combination with a width based image candidates set and [a `sizes` specification](#using-sizes) (you can pass in an empty array in all other cases). |
| 35 | + |
| 36 | +### Image candidates |
| 37 | + |
| 38 | +Next, you have to register a couple of **image candidates** for the various states of the responsive image. The file names don't get validated in any way — they will be used as-is for the generated CSS. |
| 39 | + |
| 40 | +```php |
| 41 | +// Use a `srcset`-like combined file name + width descriptor string ... |
| 42 | +$generator->registerImageCandidate('small-400.jpg 400w'); |
| 43 | + |
| 44 | +// ... or an explicit width / resolution descriptor as second argument |
| 45 | +$generator->registerImageCandidate('medium-800.jpg', '800w'); |
| 46 | +$generator->registerImageCandidate('large-1200.jpg', '1200w'); |
| 47 | +``` |
| 48 | + |
| 49 | +As with HTML5 responsive images, you can use **resolution** or **width based descriptors** for the image candidates, but be aware that you're not allowed to mix them within a single image candidate set. |
| 50 | + |
| 51 | + |
| 52 | +```php |
| 53 | +$generator->registerImageCandidate('small-400.jpg', '1x'); |
| 54 | +$generator->registerImageCandidate('medium-800.jpg', '2x'); |
| 55 | +``` |
| 56 | + |
| 57 | +### Compiling the CSS ruleset |
| 58 | + |
| 59 | +Finally, to create the responsive image CSS, call the generator's `make()` method and apply a **CSS selector** of your choice to the resulting CSS ruleset: |
| 60 | + |
| 61 | +```php |
| 62 | +$cssRuleset = $generator->make([1.0, 2.0]); |
| 63 | +echo $cssRuleset->toCss('.respimg-container'); |
| 64 | +``` |
| 65 | + |
| 66 | +The list of floating point numbers passed to the `make()` method are the **device pixel densities / resolutions** you want the CSS to be rendered for. If you omit this argument, only the default density `1.0` will be considered. The output will look something like this (not pretty-printed): |
| 67 | + |
| 68 | +```css |
| 69 | +.respimg-container { |
| 70 | + background-image: url("small-400.jpg"); |
| 71 | +} |
| 72 | +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi),(min-resolution: 2ddpx) { |
| 73 | + .respimg-container { |
| 74 | + background-image: url("medium-800.jpg"); |
| 75 | + } |
| 76 | +} |
| 77 | +``` |
| 78 | + |
| 79 | +As you see in the example, **only the `background-image` property is specified** for the image candidates. For a fully functional responsive image you will need some more lines of CSS — in order to give you full control, however, it's up to you to add this to your overall CSS. |
| 80 | + |
| 81 | +### Example |
| 82 | + |
| 83 | +A minimal, all-things-inlined HTML / PHP example document with responsive background image could look like this: |
| 84 | + |
| 85 | +```php |
| 86 | +<!DOCTYPE html> |
| 87 | +<html lang="en"> |
| 88 | + <head> |
| 89 | + <title>Example document with responsive background image</title> |
| 90 | + <style> |
| 91 | + .respimg { |
| 92 | + padding-bottom: 75%; /* 4:3 aspect ratio */ |
| 93 | + background-repeat: no-repeat; |
| 94 | + background-position: top left; |
| 95 | + background-size: cover; |
| 96 | + } |
| 97 | + <?php |
| 98 | + |
| 99 | + $generator = new Jkphl\Respimgcss\Ports\Generator(); |
| 100 | + $generator->registerImageCandidate('small-400.jpg', '1x'); |
| 101 | + $generator->registerImageCandidate('medium-800.jpg', '2x'); |
| 102 | + echo $generator->make([1, 2])->toCss('.respimg'); |
| 103 | + |
| 104 | + ?> |
| 105 | + </style> |
| 106 | + </head> |
| 107 | + <body> |
| 108 | + <div class="respimg"></div> |
| 109 | + </body> |
| 110 | +</html> |
| 111 | +``` |
| 112 | + |
| 113 | +### Using `sizes` |
| 114 | + |
| 115 | +A very powerful feature of HTML5 responsive images is the [`sizes` attribute](http://w3c.github.io/html/semantics-embedded-content.html#ref-for-viewport-based-selection%E2%91%A0) which lets you further describe the way your image gets displayed. *responsive-images-css* aims to support the `sizes` specification to a reasonable extent so that you can use the same values as you would for `<img srcset="…" sizes="…">`: |
| 116 | + |
| 117 | +```php |
| 118 | +$cssRuleset = $generator->make( |
| 119 | + [1, 2], // Device resolutions |
| 120 | + '(min-width: 400px) 50vw, (min-width: 800px) 33.33vw, 100vw' // Image sizes |
| 121 | +); |
| 122 | +``` |
| 123 | + |
| 124 | +The `Generator` will try to calculate the anticipated image sizes for the registered breakpoints and select the appropriate image candidates accordingly. Please be aware that |
| 125 | + |
| 126 | +* `sizes` may only be used in combination with **width based image candidates sets**, |
| 127 | +* you **must provide breakpoints** to the `Generator` constructor when using `sizes` and that |
| 128 | +* the breakpoints used for the `sizes` value **should match** the registered global breakpoints. |
10 | 129 |
|
11 | 130 | ## Installation
|
12 | 131 |
|
|
0 commit comments