retinajs
JavaScript, SCSS, Sass, Less, and Stylus helpers for rendering high-resolution image variants
Top Related Projects
JavaScript, SCSS, Sass, Less, and Stylus helpers for rendering high-resolution image variants
jQuery plugin for 'responsive cropping'. Dynamically crop images to fill available space without cutting out the image's subject. Great for full-screen images.
A responsive image polyfill for <picture>, srcset, sizes, and more
High performance and SEO friendly lazy loader for images (responsive and normal), iframes and more, that detects any visibility changes triggered through user interaction, CSS or JavaScript without configuration.
LazyLoad is a lightweight, flexible script that speeds up your website by deferring the loading of your below-the-fold images, backgrounds, videos, iframes and scripts to when they will enter the viewport. Written in plain "vanilla" JavaScript, it leverages IntersectionObserver, supports responsive images and enables native lazy loading.
A library for panning and zooming elements using CSS transforms :mag:
Quick Overview
RetinaJS is a lightweight JavaScript library designed to automatically replace images with high-resolution versions on devices with retina displays. It helps developers easily serve high-quality images to retina devices without affecting the experience on standard displays.
Pros
- Easy to implement with minimal configuration
- Automatically detects retina displays and serves appropriate images
- Supports various image formats and naming conventions
- Lightweight and has no dependencies
Cons
- May increase page load time and bandwidth usage on retina devices
- Requires preparing and storing multiple versions of each image
- Limited customization options for advanced use cases
- Not actively maintained (last update was in 2016)
Code Examples
- Basic usage with data attributes:
<img src="image.png" data-rjs="2" alt="My Image">
This example uses a data attribute to specify the retina image scale factor.
- Using custom naming convention:
<img src="image.png" data-rjs="image@2x.png" alt="My Image">
Here, a custom filename is specified for the retina version of the image.
- JavaScript initialization:
retinajs();
This code initializes RetinaJS, scanning the page for images with retina data attributes.
Getting Started
- Include the RetinaJS script in your HTML file:
<script src="https://cdnjs.cloudflare.com/ajax/libs/retinajs/2.1.3/retina.min.js"></script>
- Add the
data-rjs
attribute to your image tags:
<img src="image.png" data-rjs="2" alt="My Image">
-
Prepare high-resolution versions of your images (e.g.,
image@2x.png
for 2x resolution). -
Initialize RetinaJS (if not using the auto-initializing version):
document.addEventListener('DOMContentLoaded', function() {
retinajs();
});
RetinaJS will now automatically replace images with their high-resolution counterparts on retina displays.
Competitor Comparisons
JavaScript, SCSS, Sass, Less, and Stylus helpers for rendering high-resolution image variants
Pros of retinajs
- No pros can be identified as both repositories appear to be the same project
Cons of retinajs
- No cons can be identified as both repositories appear to be the same project
Code comparison
Both repositories contain identical code. Here's a sample from both:
(function() {
var root = (typeof exports === 'undefined' ? window : exports);
var config = {
// An option to choose a suffix for 2x images
retinaImageSuffix : '@2x',
// Ensure Content-Type is an image before trying to load @2x image
// https://github.com/imulus/retinajs/pull/45)
check_mime_type: true,
Additional notes
It appears that strues/retinajs and strues/retinajs> are the same repository. The comparison request might be a typo or misunderstanding. Both repositories contain the same Retina.js project, which is a JavaScript library for serving high-resolution images to devices with retina displays. The project aims to make it easy for web developers to serve retina images to high DPI devices, improving the visual quality of websites on such screens.
jQuery plugin for 'responsive cropping'. Dynamically crop images to fill available space without cutting out the image's subject. Great for full-screen images.
Pros of jquery-focuspoint
- Focuses on image cropping and positioning, allowing for responsive image layouts
- Provides a visual helper tool for setting focus points on images
- Supports both jQuery and vanilla JavaScript implementations
Cons of jquery-focuspoint
- Requires more setup and configuration compared to retinajs
- Limited to image positioning and doesn't handle high-DPI image swapping
- May have a steeper learning curve for developers new to the concept
Code Comparison
retinajs:
retinajs();
jquery-focuspoint:
$('.focuspoint').focusPoint({
reCalcOnWindowResize: true
});
Key Differences
- Purpose: retinajs is primarily for high-DPI image swapping, while jquery-focuspoint is for image positioning and cropping
- Functionality: retinajs is more plug-and-play, while jquery-focuspoint offers more customization options
- Dependencies: retinajs can work standalone, while jquery-focuspoint has a jQuery dependency (though a vanilla JS version is available)
Both libraries serve different purposes in responsive web design. retinajs is ideal for projects requiring simple high-DPI image support, while jquery-focuspoint is better suited for complex image layouts where precise positioning is crucial.
A responsive image polyfill for <picture>, srcset, sizes, and more
Pros of Picturefill
- More comprehensive solution for responsive images, supporting various use cases
- Better browser compatibility, including older versions of Internet Explorer
- Actively maintained with regular updates and a larger community
Cons of Picturefill
- Larger file size compared to Retinajs, which may impact page load times
- More complex implementation, requiring additional markup in HTML
Code Comparison
Retinajs:
retinajs();
Picturefill:
<picture>
<source srcset="large.jpg" media="(min-width: 800px)">
<source srcset="medium.jpg" media="(min-width: 400px)">
<img src="small.jpg" alt="Description">
</picture>
Retinajs focuses on serving high-resolution images for retina displays, while Picturefill provides a more comprehensive solution for responsive images across different screen sizes and resolutions. Retinajs is simpler to implement but has limited functionality compared to Picturefill.
Picturefill requires more markup in HTML and has a larger file size, but it offers greater flexibility and browser support. Retinajs is lightweight and easy to use but may not cover all responsive image scenarios.
Choose Picturefill for a more robust solution with wider browser support, or opt for Retinajs if you only need to handle retina displays with minimal overhead.
High performance and SEO friendly lazy loader for images (responsive and normal), iframes and more, that detects any visibility changes triggered through user interaction, CSS or JavaScript without configuration.
Pros of lazysizes
- More comprehensive lazy loading solution, supporting images, iframes, scripts, and more
- Extensive plugin ecosystem for additional features and customization
- Actively maintained with regular updates and bug fixes
Cons of lazysizes
- Larger file size (around 10KB minified) compared to retinajs
- More complex setup and configuration options may be overwhelming for simple use cases
Code comparison
retinajs:
retinajs();
lazysizes:
<img data-src="image.jpg" class="lazyload" alt="Lazy loaded image">
<script src="lazysizes.min.js" async></script>
Key differences
- retinajs focuses specifically on high-DPI image replacement, while lazysizes is a more comprehensive lazy loading solution
- lazysizes requires adding classes and data attributes to HTML elements, whereas retinajs can work with existing markup
- retinajs is simpler to implement for its specific use case, while lazysizes offers more flexibility and features
Use case recommendations
- Choose retinajs for projects primarily focused on serving high-DPI images with minimal setup
- Opt for lazysizes when requiring a full-featured lazy loading solution with support for various content types and advanced customization options
LazyLoad is a lightweight, flexible script that speeds up your website by deferring the loading of your below-the-fold images, backgrounds, videos, iframes and scripts to when they will enter the viewport. Written in plain "vanilla" JavaScript, it leverages IntersectionObserver, supports responsive images and enables native lazy loading.
Pros of vanilla-lazyload
- More actively maintained with frequent updates
- Supports modern lazy loading techniques like Intersection Observer
- Offers more customization options and features
Cons of vanilla-lazyload
- Slightly larger file size
- May have a steeper learning curve due to more configuration options
Code Comparison
vanilla-lazyload:
const lazyLoadInstance = new LazyLoad({
elements_selector: ".lazy",
threshold: 0,
callback_enter: (element) => {
console.log("Loaded:", element);
}
});
retinajs:
retinajs();
// Or with options
retinajs({
retinaImageSuffix: '@2x'
});
Key Differences
- vanilla-lazyload focuses on lazy loading images and other elements, while retinajs primarily handles high-resolution images for retina displays
- vanilla-lazyload offers more granular control over loading behavior
- retinajs has a simpler API and is easier to implement for its specific use case
Use Cases
- Choose vanilla-lazyload for general lazy loading of images and other content
- Opt for retinajs when specifically dealing with high-resolution images for retina displays
Community and Support
- vanilla-lazyload has a larger user base and more active community
- retinajs has fewer recent updates but remains a solid choice for its specific functionality
A library for panning and zooming elements using CSS transforms :mag:
Pros of Panzoom
- More comprehensive zooming and panning functionality, including programmatic control
- Active development with regular updates and bug fixes
- Supports touch events for mobile devices
Cons of Panzoom
- Larger file size and potentially more complex implementation
- May have a steeper learning curve for basic use cases
Code Comparison
RetinaJS:
retinajs();
Panzoom:
const elem = document.getElementById('my-element')
const panzoom = Panzoom(elem, {
maxScale: 5
})
elem.addEventListener('wheel', panzoom.zoomWithWheel)
Summary
RetinaJS is a lightweight solution focused specifically on handling high-DPI images, while Panzoom offers a more comprehensive set of features for zooming and panning elements. RetinaJS is simpler to implement for its specific use case, but Panzoom provides greater flexibility and control over zoom and pan behaviors. The choice between the two depends on the specific requirements of your project and the level of zoom/pan functionality needed.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
retina.js
JavaScript, Sass, Less, and Stylus helpers for rendering high-resolution image variants
retina.js
makes it easy to serve high-resolution images to devices with displays that support them. You can prepare images for as many levels of pixel density as you want and let retina.js
dynamically serve the right image to the user.
How it works
There are 4 ways to use retina.js
:
- Automatically swapping out
src
paths onimg
tags. - Automatically swapping out background image URLs in inline styles.
- Manually specifying the location of a high-res image variant (works for
src
attributes and inline styles). - Automatically creating media queries for CSS background images.
Img Tags
retina.js
assumes you are using Apple's prescribed high-resolution modifiers (@2x, @3x, etc) to denote high-res image variants on your server. It also assumes that if you have prepared a variant for a given high-res environment, that you have also prepared variants for each environment below it. For example, if you have prepared 3x variants, retina.js
will assume that you have also prepared 2x variants.
With this in mind, you'll specify your highest environment level with the data-rjs
attribute and let retina.js
take it from there.
Let's say you have an image on your page that looks like this:
<img src="/images/my_image.png" data-rjs="3" />
In this case, we've set our resolution cap at "3", denoting that we've prepared 3x and 2x image variants. When the page loads, retina.js
will check the actual resolution of the device environment to decide whether it should really serve up a 3x image. If the user happens to be in a 2x environment, retina.js
will serve up the 2x image instead, assuming it will find the image at /images/my_image@2x.png
.
If the environment does have 3x capabilities, retina.js
will serve up the 3x image. It will expect that url to be /images/my_image@3x.png
. If the environment has the ability to display images at higher densities than 3x, retina.js
will serve up the image of the highest resolution that you've provided, in this case 3x.
Inline Styles
Previous versions of retina.js
were unable to target background images set via inline styles. Now, if you apply a data-rjs
attribute to any kind of element other than an img
, the script will target inline background images instead of src
attributes.
So if you created an element like this:
<div style="background: url(/images/my_image.png)" data-rjs="3"></div>
retina.js
would convert it to something like this:
<div style="background: url(/images/my_image@3x.png)" data-rjs="3"></div>
The logic behind image swapping is exactly the same when dealing with background images as it is when dealing with src
attributes. If the user's environment only supports 2x variants, retina.js
will load the 2x variant instead of the 3x.
Note that it is up to you in a case like this to correctly apply background sizing and any other necessary background-related styles to the element. retina.js will not affect these.
Manually Specifying a High-Res URL
In previous versions, you could tell the script where to find your high-res file by using the data-at2x
attribute. Now, if you pass a URL to the data-rjs
attribute, retina.js
will use the image at the path you specify for all high-resolution environments instead of trying to dynamically serve an auto-suffixed image path based on the environment's capabilities. This will work for both src
attributes on img
tags and inline background images on all other tags.
For example, you might write something like this:
<img
src="/images/my_image.png"
data-rjs="/images/2x/my-image.png" />
<!-- or -->
<div
style="background: url(/images/my_image.png)"
data-rjs="/images/2x/my-image.png">
</div>
If the user then loads the page in any kind of high-resolution environment, they'll get the following:
<img
src="/images/2x/my-image.png"
data-rjs="/images/2x/my-image.png" />
<!-- or -->
<div
style="background: url(/images/2x/my-image.png)"
data-rjs="/images/2x/my-image.png">
</div>
Media Queries
retina.js
comes with mixins for SCSS, Sass, Less, and Stylus. These mixins work similarly to the JavaScript version in that they will dynamically serve images for as many high-res environments as you've prepared image variants for. Previously, these mixins were named "at2x" but because they now serve images for multiple environments, they have been renamed "retina".
In each language, the retina mixin allows 4 parameters:
path
- The path to your standard resolution image.cap
- Optional. The highest resolution level for which you have prepared images. Defaults to 2.size
- Optional. A value to be applied to thebackground-size
property. Defaults toauto auto
.extras
- Optional. Any other values to be added to the background property. Defaults to nothing.
Here is an example wherein we are specifying that we have prepared images for both 2x and 3x environments:
SCSS
#item {
@include retina('/images/my_image.png', 3, cover, center center no-repeat);
}
Sass
#item
+retina('/images/my_image.png', 3, cover, center center no-repeat)
Less
#item {
.retina('/images/my_image.png', 3, cover, center center no-repeat);
}
Stylus
#item
retina('/images/my_image.png', 3, cover, center center no-repeat)
Regardless of the dialect, the output is effectively the same:
#item {
background: url("/images/my_image.png") center center no-repeat;
background-size: cover;
}
@media all and (-webkit-min-device-pixel-ratio: 1.5),
all and (-o-min-device-pixel-ratio: 3 / 2),
all and (min--moz-device-pixel-ratio: 1.5),
all and (min-device-pixel-ratio: 1.5) {
#item {
background: url("/images/my_image@2x.png") center center no-repeat;
background-size: cover;
}
}
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
#item {
background: url("/images/my_image@2x.png") center center no-repeat;
background-size: cover;
}
}
@media (-webkit-min-device-pixel-ratio: 3), (min-resolution: 288dpi) {
#item {
background: url("/images/my_image@3x.png") center center no-repeat;
background-size: cover;
}
}
Compatibility
retina.js
is compatible with all modern browsers and should not throw errors in old browsers all the way back through IE6.
Installing & Launching
JavaScript
There are 2 ways to use the JavaScript version of retina.js
:
- The old-school way (manually dropping the script into an html file).
- The new-school way (importing it into a larger JavaScript build process).
Old-School
To use retina.js the old-school way, download retina.min.js and put it on your server. Then, include the script in your html file at the bottom of your template, before your closing </body> tag.
<script type="text/javascript" src="/scripts/retina.min.js"></script>
Using this technique, retina.js
will run automatically on page load. It will also create a globally available function called retinajs
. Whenever you'd like to manually re-initialize the script, simply call window.retinajs()
.
If you don't pass any arguments to the retinajs
function, it will only attempt to process images that have not previously been processed by the script. Optionally, you can pass a collection of HTML elements to the script, in which case it will only attempt to process elements in that collection, specifically the ones that have not been processed before. Your collection may take the form of an Array, NodeList, or jQuery selection.
retinajs();
// Finds all images not previously processed and processes them.
retinajs( [img, img, img] );
// Only attempts to process the images in the collection.
retinajs( $('img') );
// Same.
retinajs( document.querySelectorAll('img') );
// Same.
New-School
To use retina.js the new-school way, you'll want to require
it (or import
it if you're using ES6) into your Gulp/Webpack/Grunt/CommonJS/etc application. In this case, the script won't run automatically. Instead, it'll let you determine when you'd like it to run.
import retina from 'retina';
window.addEventListener('load', retina);
Notice that the retina
function can be called as often as you need in order to re-initialize the image swapping.
If you don't pass any arguments to the retina
function, it will only attempt to process images that have not previously been processed by the script. Optionally, you can pass a collection of HTML elements to the script, in which case it will only attempt to process elements in that collection, specifically the ones that have not been processed before. Your collection may take the form of an Array, NodeList, or jQuery selection.
retina();
// Finds all images not previously processed and processes them.
retina( [img, img, img] );
// Only attempts to process the images in the collection.
retina( $('img') );
// Same.
retina( document.querySelectorAll('img') );
// Same.
CSS Preprocessors
The process for including the CSS mixins is relatively straightforward. Here is a breakdown for each:
SCSS
Add the @mixin retina( ... )
mixin from _retina.scss to your SCSS stylesheet (or reference it in an @import
). In your stylesheet, call the mixin using @include retina( ... )
anywhere instead of using background
or background-image
.
Sass
Add the =retina( ... )
mixin from _retina.sass to your Sass stylesheet (or reference it in an @import
). In your stylesheet, call the mixin using +retina( ... )
anywhere instead of using background
or background-image
.
Less
Add the .retina( ... )
mixin from retina.less to your Less stylesheet (or reference it in an @import
). In your stylesheet, call the mixin using .retina( ... )
anywhere instead of using background
or background-image
.
Stylus
Add the retina( ... )
mixin from retina.styl to your Stylus stylesheet (or reference it in an @import
). In your stylesheet, call the mixin using retina( ... )
anywhere instead of using background
or background-image
.
Considerations for Ruby on Rails 3+
...or any framework that embeds some digest/hash to the asset URLs based on the contents, e.g. /images/image-{hash1}.jpg
.
The problem with this is that the high-resolution version would have a different hash, and would not conform to the usual pattern, i.e. /images/image@2x-{hash2}.jpg
. So automatic detection would fail because retina.js would check the existence of /images/image-{hash1}@2x.jpg
.
There's no way for retina.js to know beforehand what the high-resolution image's hash would be without some sort of help from the server side. So in this case, there are a couple of options for handling it:
Bypass Digesting
One potential method is to bypass digesting altogether by implementing a process like team-umlaut's asset compile rake file which will generate non-digested asset files as necessary.
Use Manual Paths
Although it's not quite as fancy as dynamically serving up files based on the resolution of the user's environment, this may be a good time to pass a URL string to the data-rjs
attribute so that you can manually tell retina.js exactly where to look for a high-resolution variant of your image.
Top Related Projects
JavaScript, SCSS, Sass, Less, and Stylus helpers for rendering high-resolution image variants
jQuery plugin for 'responsive cropping'. Dynamically crop images to fill available space without cutting out the image's subject. Great for full-screen images.
A responsive image polyfill for <picture>, srcset, sizes, and more
High performance and SEO friendly lazy loader for images (responsive and normal), iframes and more, that detects any visibility changes triggered through user interaction, CSS or JavaScript without configuration.
LazyLoad is a lightweight, flexible script that speeds up your website by deferring the loading of your below-the-fold images, backgrounds, videos, iframes and scripts to when they will enter the viewport. Written in plain "vanilla" JavaScript, it leverages IntersectionObserver, supports responsive images and enables native lazy loading.
A library for panning and zooming elements using CSS transforms :mag:
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot