Menu Search
Jump to the content X X
Smashing Conf Barcelona 2016

We use ad-blockers as well, you know. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. upcoming SmashingConf Barcelona, dedicated to smart front-end techniques and design patterns.

Open Source Plugin Magnific Popup, A Truly Responsive Lightbox (For jQuery And Zepto.js)

A lightbox is one of those tools that work great on the desktop but often fail on small mobile devices. These days, finding a plugin that is responsive and that displays content right away is hard. For this reason, I created Magnific Popup1, an open-source lightbox plugin focused on performance.

In this article, I’ll share the techniques I employed in creating this plugin, techniques that can make your lightbox much faster and easier to use, whatever the device being used.

1. Speed Link

We might not be able to speed up the loading time of an image with this lightbox plugin, but we can create the perception of a faster loading time.

Progressive Loading of Images Link

The majority of lightbox plugins will fully preload an image before displaying it. This is done to figure out the original size of the image and to center it with JavaScript. Because Magnific Popup centers the content with CSS, we can avoid preloading and instead display the image right away to take advantage of progressive image loading. It will render and show the image while the data is being received.

You can speed this up even more by progressively rendering the JPEG2. It is rendered not from top to bottom, but from low quality to full quality, so the user can discern the image even faster. The type of rendering to use is strictly a matter of preference.

Progressive image loading3

CSS-Based Resizing Link

The CSS-only approach makes this lightbox extremely flexible. You can specify sizes in relative units such as ems, resize popups in media queries, and update popup content dynamically without having to worry about how it will be resized and centered. Try to avoid, or at least reduce, the number of resizing properties in a window’s resize event, because it will look much slower than resizing with just pure CSS.

Vertically centering an element with unknown dimensions is probably the most horrifying topic in CSS layout. The main goal for me was to prevent the size of the content area from dynamically updating the contents of the lightbox, and to make it work in IE 8 and above.

Following the principle of progressive enhancement, I decided to drop the vertical centering feature in IE 7 completely, because the only way to implement it was to use slow CSS expressions, which kill performance in old browsers. In contrast to modern browsers, the resolution of monitors on which IE 7 is being run is unusually easy to predict. We’d know that the user would be on an old PC, which typically has a resolution of somewhere between 800 × 600 and 1280 × 1024 pixels; so, we can just set a fixed margin from the top: .lightbox-image { margin-top: 10%; }. Alternatively, instead of opening the lightbox, you can just link directly to the content. In Magnific Popup, you can do this like so:

$('.popup-link').magnificPopup(function() {
  disableOn: function() {
    // Detect IE 7 or lower with your preferred method
    // and return false if you want to trigger the default action
    return isIE7 ? false: true;

Centering an HTML block

Here are the criteria:

  1. The size of the block is unknown and could be changed at any time.
  2. Block should be centered both horizontally and vertically.
  3. If the height of the popup is bigger than the viewport, then the scrollbar should appear, and the popup should automatically align to the top.

The one reliable technique to vertically center an element of unknown height that I’ve found uses a helper inline-block element with a setting of vertical-align: middle and height: 100%. Chris Coyier has written a superb article4 covering this technique. It works perfectly5 and meets all three requirements.

Centering an image with a caption

In addition to the requirements of an HTML block, the image should also meet these requirements:

  • It should fit the area both horizontally and vertically.
  • Its maximum height should equal the height of the original image.
  • The caption should be positioned directly below the image, and the text may flow up to two lines.

Here is the structure of the image’s lightbox:

<div class="container">
  <img src="image.jpg"/>
  <div class="description">Caption</div>

Implementing this just for an image and with support for IE 8 and above is not hard6. The problem comes when you try to position elements near to the image (such as a caption or related icon).

I was not able to find the solution for such a layout without using JavaScript, so I used a technique that applies a max-height to the image. Check the example on CodePen7 to see how it works.

Centering an iframe

Iframes in Magnific Popup are resized using the popular and effective technique introduced by Thierry Koblentz in his article “Creating Intrinsic Ratios for Video8” on A List Apart. All you need to do to force any element’s height to scale according to its width is to put it in a container and apply top padding as a percentage:

.iframe-container {
  width: 100%;
  height: 0;
  overflow: hidden;

  /* element ratio is 4:3 (3/4 * 100) */
  padding-top: 75%;

.iframe-container iframe {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;

Window height on iPhone

Mobile Safari on iPhone and iPod has a nasty bug: the height of the window is always reduced by the height of the navigation bar, whether the bar is present or not, so the popup won’t center correctly. When researching this issue, I found two ways to fix it:

  1. Just add 60 pixels to the height of the window. This solution doesn’t work with iOS 6’s full-screen mode, and it’s not future-friendly.
  2. Use window.innerHeight instead of document.documentElement.clientHeight, which returns the correct value, but only when the window is not zoomed in.

But I’ve figured out a third way to implement this (for more details on this technique, check my answer on Stack Overflow):

var getIphoneWindowHeight = function() {
  // Get zoom level of mobile Safari
  // Such zoom detection might not work correctly on other platforms
  var zoomLevel = document.documentElement.clientWidth / window.innerWidth;

  // window.innerHeight returns height of the visible area.
  // We multiply it by zoom and get our real height.
  return window.innerHeight * zoomLevel;

If you know of a better way to position elements than what’s suggested here, we’d be hugely grateful to hear!

Preloading images in a gallery is essential and vastly increases browsing speed. The average modern browser accepts about six connections per host name9, whereas IE 7 accepts only two.

After the lightbox gallery is opened, it should start loading not one, but a group of images (the number of items in a group should depend on the size of the images and on how likely your visitor will navigate to the next one — test it!). Don’t even think about waiting to load the next image until after the current one has completely loaded; otherwise, it will reduce browsing speed significantly.

In Magnific Popup, you can set the number of images to preload before and after the current one, and these two values will automatically switch according to the direction in which the user is navigating.

Parallel loading
Inaccurate comparison between parallel and one-by-one loading.

High-DPI Display Support Link

Magnific Popup’s default controls are made with pure CSS, without any external resources. Thus, the controls are not only light, but also ready for high-DPI (i.e. Retina) displays. But in this section of the article I’d like to talk about serving images for displays with high pixel density.

It’s not hard to change the path, as the image in lightbox is loaded dynamically. The main problem is that the image should be scaled by half (for 2x device pixel ratio). It rises the question: how to get the image size via JavaScript without waiting until it is completely loaded to keep progressive loading?

While researching, I’ve found that the image naturalWidth is defined exactly after browser gets its size. So we just fire an interval that checks if the image object has defined naturalWidth, after it has it we scale the image by applying max-width that equals image.naturalWidth / window.devicePixelRatio. Here is simplified version of how the image loading is implemented:

var interval,
	onHasSize = function() {
		if(hasSize) return;

		// we ignore browsers that don't support naturalWidth
		var naturalWidth = img[0].naturalWidth;

		if(window.devicePixelRatio > 1 && naturalWidth > 0) {
			img.css('max-width', naturalWidth / window.devicePixelRatio);

		hasSize = true;
	onLoaded = function() {
	onError = function() {
	checkSize = function() {
		if(img[0].naturalWidth > 0) {
	img = $('<img />')
		.on('load', onLoaded)
		.on('error', onError)
		// hd-image.jpg is optimized for the current pixel density
		.attr('src', 'hd-image.jpg')

interval = setInterval(checkSize, 100);

There is a very common assumption that the image optimized for Retina display weighs two times or more than the normal one, but it’s not always true. As the image will be scaled down, JPEG quality can be reduced without any notable visual difference. From my experience, saving an image for 2x pixel ratio with 25% JPEG quality produces a good-looking result and the file size is only about 1.4x times larger than the regular one. Daan Jobsis has a great article10 that covers this technique.

What image to serve on what screen size is a topic for another article. I just want to emphasize that for many users mobile is the only way to access the internet. If you serve smaller images for mobile and there is a chance that user will need full-sized ones — provide an alternative way to get it.

Avoid Extra HTTP Requests for Controls Link

Preload all controls (i.e. the arrows, the closing icon, the preloader) before the popup has opened in order to load the actual content faster. This can be implemented in three ways:

  • Create all controls with CSS only (as Magnific Popup does by default).
  • Include the control graphics in the main CSS sprite of your website, or preload them with CSS before the popup has opened.
  • Use the Data URI scheme11 to embed base64-encoded images directly in the CSS (supported by IE 8 and above).

2. Accessibility Link

Content that has opened in the lightbox should be easily zoomable and scrollable, no matter what the device. The contents and controls of the popup should be accessible with the tab key for keyboard users.

Conditional Lightbox Link

This relatively new technique, introduced by Brad Frost12, disables the lightbox entirely on devices with a small screen, substituting an alternative more appropriate to mobile use. Here are some examples:

  • Open maps and videos as a separate page. Many mobile browsers will recognize such links and open a dedicated app that is much easier to use.
  • Simply open images in a new page for easier zooming and panning.
  • Open long text-based popups in a new page. In Magnific Popup, you can do this by adding the source of the popup inside a data attribute and linking to a mobile-friendly page in the href attribute. For example:
    <a href="separate-mobile-friendly-page.html" data-mfp-src="popup-content.html">Open popup</a>

    Here is the popup initialization (with an option that disables the popup and just opens the link when the window is narrower than 500 pixels):

    $('.popup-link').magnificPopup(function() {
      disableOn: function() {
        // Detect here whether you want to show the popup
        // return true if you want
        if($(window).width() < 500) {
          return false;
        return true;

Progressive Enhancement Link

Build the markup as if there were no JavaScript at all, and make the button that opens the content-oriented lightbox link to the content. Not only is this an enhancement for users without JavaScript, but it allows you to open the content in a new window, and it makes it completely SEO-friendly. Images will be perfectly indexed by search engines, and the anchor text will work as an alt attribute in the img tag.

<!-- Correct: -->
<a href="image.jpg">Description of the image</a>

<!-- Incorrect: -->
<a href="#" data-src="image.jpg">Description of the image</a>

<!-- Correct: -->
<a href="large-image.jpg">
  <img src="thumbail.jpg" alt="Description of the image" />

<!-- Incorrect: -->
<img src="thumbail.jpg" data-src="large-image.jpg" alt="Description of the image" />

Selectable Image Link

Users should be able to select and copy an image that is opened in a popup. This is one of the few ways to bookmark, save or share it.

Presently, fully overlaying a lightbox image with left and right navigation arrows is very common. The screenshots below show context menus above the image (the one on the right is overlaid with a transparent div, making any kind of interaction with the image virtually impossible).

accessible image13

position: fixed and overflow: scroll Link

Zooming a fixed-positioned element looks unnatural and confusing in the majority of mobile browsers. I suggest avoiding this property entirely on devices on which content is likely to be zoomed.

Exactly the same problem happens when you apply overflow: scroll to a popup’s wrapper. In this case, the problem is an unnatural scroll:

  • Once the user has reached the end of the scroll, the main window starts scrolling behind the popup.
  • Scrolling momentum is missing. On iOS 5+, this issue can be fixed with -webkit-overflow-scrolling: touch, but what about other devices?

Magnific Popup automatically disables these properties on mobile devices. Instead of using a fixed positon, it adds a huge dark overlay to the whole page that equals the height of the document and that positions the content area using position: absolute and with a top that equals the scrollTop of the window.

Keyboard Focus Link

Upon loading, the focus should be set on the popup itself or on the first input (if it is a form). When tabbing, focus should be confined to the lightbox and its controls. After the popup has closed, focus should return to its original location. This can be implemented very simply:

// Save current focused element
var lastFocusedElement = document.activeElement;

// Set focus on some element in lightbox

// After lightbox is closed, put it back

Roger Johansson’s great article “Lightboxes and Keyboard Accessibility14” discusses this topic and the overall keyboard accessibility of lightboxes.

Touch Swipe Support Link

The main problem with the swipe gesture on touch devices is that it requires blocking the default behavior of the touchmove event (e.preventDefault()), which blocks the zooming and panning gesture.

There are just two ways to enable swiping and zooming at once:

  1. Emulate zooming behavior with help of JavaScript touch events by changing the transform property of the content’s container. But this requires recalculating the content’s size, which breaks our CSS-based resizing technique and is not reliable when there are interactive elements such as iframes. Without a doubt, the library that implements such zooming and panning the best is iScroll15 by Matteo Spinelli.
  2. Don’t inhibit the default behavior of browser zooming when two touch pointers are detected. But finding the difference between panning and swiping is very hard because detection of the browser’s zoom level is unreliable.

By design, the main purpose of a lightbox is to show enlarged versions of images. So, we would conclude that natural zooming is much more important than swiping. That is why Magnific Popup does not have swiping support. Navigation between gallery items is implemented simply by tapping on arrows with a large hit area.

But if you really need swiping, there are some ways to implement it:

  • If you don’t need a dragging effect, use something like the TouchSwipe16 plugin.
  • If you need touch navigation with a dragging effect, open in the popup some slideshow plugin with touch support, such as FlexSlider17 or (mine) RoyalSlider18.
  • Use a conditional lightbox technique and create a separate mobile-friendly page that has just a list of stacked images.

If we disable the swiping gesture, we should at least make tap navigation faster. Mobile browsers wait about 300 milliseconds before firing a click event in case they detect a double-tap event. This can be fixed with the popular “fast click” technique, which fires a click on touchend. Ryan Fioravanti of Google has a complete guide19 on it.

3. User Interface Link

Some devices allow multiple types of input at once (such as touching and mousing). We conclude that we cannot require mouseovers (:hover) for important UI elements, and we cannot neglect mouse events if touch support is present.

Apple’s “Human Interface Guidelines” for iOS state20 that a comfortable size for a tappable UI element is at least 44 × 44 pixels. Assuming that any device with any screen size may have touch support, we’ll apply as large a hit area as possible by default.

Hit area for buttons21
Red rectangles show the hit area for the controls. (Image: JJ Harrison22)

Now let’s talk about actual implementation. First of all, buttons are rendered as <button> elements. Here is why:

  • A button can have a title attribute, which we can use to describe what the button does and its keyboard shortcut.
  • Buttons, unlike <a> elements, do not require hacks such as href="#" and href="javascript:void()". When the cursor hovers over a link, many browsers will show the contents of the href attribute in the bottom-left corner of the browser window; displaying javascript:void() would look quite illogical.
  • Buttons are the most semantically correct approach for such controls.

I recommend reading Nicholas Zakas’ article “You Can’t Create a Button23,” which offers a few more arguments in favor of using <button> elements.

The Close Button Link

The closing icon is just a math multiplication sign (×) rendered in Arial. I strongly recommend avoiding specifying multiple fonts (like font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif) because the position and size of the multiplication sign is very inconsistent across fonts.

The multiplication sign in different fonts: Arial, Georgia, Lucida Grande, Helvetica, Helvetica Neue, Roboto.

Next and Previous Buttons Link

The main requirement for default arrow icons is that they should be visible on any background. At first glance, the best option is to use Unicode triangles with shadow25, but it turns out that there are no equally sized left and right triangles.

The only remaining option is to use two nested triangles with different colors. Here is how that’s done:

.double-triangle {
  width: 90px;
  height: 110px;

.double-triangle:after {
  display: block;
  width: 0;
  height: 0;
  position: absolute;
  left: 0;
  top: 0;
  margin-top: 35px;
  margin-left: 35px;
.double-triangle:after {
  content: '';
  border-top: 12px solid transparent;
  border-bottom: 12px solid transparent;
  border-right: 12px solid black;
  top: 8px;
  left: 5px;
.double-triangle:before {
  content: '';
  border-top: 20px solid transparent;
  border-bottom: 20px solid transparent;
  border-right: 20px solid white;

Because of pseudo-elements, such an implementation will not work in IE 7. Navigation buttons are an important part of the UI, so I decided to write a small polyfill to make it work in IE 7, too. We just add two elements inside the button and apply the same styles as the :before and :after elements.

var button = $('<button class="double-triangle"></button>');
if(ie7) {
  button.append('<span class="ie-before"></span><span class="ie-after"></span>');

Here’s the CSS:

.dobule-triangle .ie-before {
  /* styles ... */

Cursors Link

I am a big fan of custom cursors; they are a lovely addition to an interface. The zoom-in and zoom-out cursors make very clear that content may be enlarged or reduced, while the progress cursor is an excellent loading indicator of AJAX-based popups. Sadly, zoom cursors are still not supported by IE 10.

.zoom-in-cur {
   cursor: -webkit-zoom-in;
   cursor: -moz-zoom-in;
   cursor: zoom-in;
.zoom-out-cur {
   cursor: -webkit-zoom-out;
   cursor: -moz-zoom-out;
   cursor: zoom-out;
.progress-cur {
  cursor: progress;

Animation Link

The main rule of in and out animation for a lightbox is make sure you need it. If you do, at least keep it short (shorter than 300 milliseconds). Avoid animation if you anticipate a large image or a huge block of HTML in a lightbox.

Magnific Popup does not use JavaScript animation at all. Instead, it uses light and fast CSS transitions. Browsers that don’t support transitions are most likely slow, and thus JavaScript animation would look choppy in them.

One more important point: As I said before, Magnific Popup automatically disables position: fixed on mobile devices and creates a tall dark overlay on the page. Animating such a block might cause mobile devices to lag, so I suggest forcing position: fixed for the background and keeping position: absolute for the content itself.

And here’s a pro tip: To make your sliding animation a little smoother, Paul Irish suggests26 animating the translateY property, instead of top or margin-top.

In Summary Link

A responsive lightbox is not one that scales down proportionally when the screen’s size changes. It’s the one that provides fully accessible content, whatever the device.

No matter what script you use, it should support these standards:

  • Escape key to close the popup.
  • Left and right arrow keys to navigate the gallery.
  • Tab key to navigate the contents of the popup.
  • If there is a single image, the lightbox should close when any part of the image is clicked.
  • If it is a gallery, clicking on the current image should advance to the next image. Check out the discussion on UX Stack Exchange27 for more information.
  • A gallery should be clearly indicated: “1 of 10” counters, arrows, bullets, thumbnails, or any combination of these.

I hope this article and script will be useful to some. For more techniques, dig into the code of Magnific Popup in the GitHub repository34.

(al) (ea)

Footnotes Link

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
SmashingConf Barcelona 2016

Hold on, Tiger! Thank you for reading the article. Did you know that we also publish printed books and run friendly conferences – crafted for pros like you? Like SmashingConf Barcelona, on October 25–26, with smart design patterns and front-end techniques.

↑ Back to top Tweet itShare on Facebook


Dmitry Semenov is a professional frontend web developer and user experience designer based in Kiev, Ukraine. Follow Dmitry on Twitter or check his website.

  1. 1

    I’m using Fresco, it has a much better way to handle swipe events on touch devices, with images actually moving as you’d expect. It also scales the actual UI based on screen size and toggles UI elements, so I’d call it more ‘truly responsive’ than this.

    • 2

      John Craft

      May 2, 2013 7:26 am

      You clearly haven’t read the article. The plugin that you listed:

      1. Blocks zoom gesture
      2. Has a huge paddings around the image on small device.
      3. Not open source
      4. Commercial, license costs 50 EURO (are you nuts?)
      5. Preloads images completely before displaying.
      6. Weights 5 times more!

  2. 4

    Thank you, awesome script! Don’t know even what’s more awesome – the plugin or the article :)

  3. 5

    Gabriel Sharp

    May 2, 2013 4:37 am

    Well this is clearly the most thoughtful Lightbox ever made, it gets out of your way and perfectly considers users needs.

    Can’t wait to use this.

    Congrats on the release.

  4. 6

    Ronny Karam

    May 2, 2013 4:47 am

    Great tool.

    One thing to point though on the plugin’s page.

    Popup with video or map > Open YouTube video > video is not centered in the middle of the viewport; you need to scroll to view it.
    Chrome Version 28.0.1485.0 dev

    After updating to Chrome to Version 28.0.1490.2 dev, the video is centered.

    • 7

      So it’s basically a Chrome-only javascript or css bug, which also only occurs with the development (and not the stable) version ;)

      cu, w0lf.

  5. 8

    Nice article, Dmitry! Thank you both for this article and new plugin! :)

  6. 9

    Wonderful job Dima. I spent so so much time working on my site trying to accomplish responsive gallery slide that would be fast and would work on all screen sizes. I think I have accomplished this, but you sir have done ten times better. Putting it out there and letting people use the results of your hard work, is another task of its own. Congrats!

  7. 10

    That is incredible – just what I was looking for, absolutely unbelievable!!! I’m going to take the afternoon off and read this!!

  8. 11

    Dmitry, i wrote you two letters regarding your RoyalSlider, could you answer me?
    Thank you, спасибо или как еще нужно написать, чтобы дождаться от вас ответа. Спасибо

  9. 12

    Kevin Middleton

    May 2, 2013 8:38 am

    Dmitry, congratulations on another solid and stable plugin release! I’m a big fan of RoyalSlider and am impressed with (but not surprised at) the amount of thought that went into this lightbox’s construction.

  10. 13

    Awesome! Just what I was looking for. Having just recently needed to build a script like this, I was surprised to find that there are not a lot of options out there for “responsive” light boxes/modals. In fact, I think this is the only one that actually does an excellent job at handling all of the usability issues! Thank you!

  11. 14

    Brilliant plugin and very nice and interesting article.
    Great work!

  12. 15

    Thanks for this fantastic tutorial, this guide makes so much easy to create Lightbox within those steps and one more important thing is that, its very much responsive and not blunder.


  13. 16

    Jordan Park Singleton

    May 2, 2013 4:48 am

    Glad to see it’s ready to go! I came across Magnific a few days ago (when looking for a light box solution for a site I’m working on) and it sounded like it wasn’t yet ready for production use, so I ended up going with the old version of Flexbox instead. I’ll definitely keep it in mind for future projects. Quality open-source light boxes are hard to come by.


  14. 17

    J. P. Singleton

    May 2, 2013 4:56 am

    Glad to see it’s ready to go! I came across Magnific a few days ago (in looking for a solution for a project I’m currently working on) but it sounded like it wasn’t yet ready for production use so I ended up falling back on the old version of Flexbox. Quality open-source lightboxes are hard to come by. I’ll definitely keep this one in mind for my next project.


  15. 18

    I don’t remember the last time I found a light box useful, but I remember plenty when it completely broke the use of the screen.

    This one seems to be one of the better, it does appear to have minor issues in Stock Android browser with portrait/landscape switching and the buttons disappearing, as well as the page shadowing not working as expected.

    I am unsure why it is not generally better to avoid light boxes and just use plain html and images as these are guaranteed to work on all devices without the pain of testing etc.

    • 19

      Dmitry Semenov

      May 2, 2013 7:58 am

      I like to compare plugins, like lightboxes, tooltips and carousels, with a gun – they can kill the experience if they fall into the wrong hands. But if you use them wisely, they will speed-up and simplify life on the end user dramatically. There are really good links listed in “Useful related resources” section that explain when and why you should use lightbox, e.g.:


      I’d be very grateful if you open and issue on GitHub regarding the Android issue and provide some more details. For some reason I can’t repeat it on my test Android 2.3 device.

      Thank you!

      • 20

        That’s a pretty funny analogy as I’ve never known a gun to dramatically speed up and simplify life on the end user.

        Nice plugin however.

        • 21

          Dmitry Semenov

          May 3, 2013 10:37 pm

          Hahaha, this just made my day! I really should have read my comment before publishing it.

  16. 22

    Erlend Sogge Heggen

    May 2, 2013 5:05 am

    Magnificent indeed! Did anyone say WordPress plugin? no?.., dangit.

  17. 26

    Jane Samplow

    May 2, 2013 5:07 am

    Great article. I completely agree with you, it’s so annoying when zoom is disabled.

  18. 27

    Stefan Shendal

    May 2, 2013 5:21 am

    Thank you, great article! By the way, Magnific Popup logo is very cool, if someone haven’t noticed before – it changes every time you refresh the page.

  19. 28

    Sweet! And I see you will be making this a WP plugin. I’m signing up to be notified at

  20. 29

    WordPress users can use which is also fully responsive. I don’t actually see the progressive enhancement as a benefit. I think animated loading gifs are better than seeing pixelated versions of the image. It feels like the user wouldn’t know exactly when the whole image is really loaded, their eyes have to keep adjusting to it.

    Regardless, you’re totally right than responsive lightboxes have been HUGELY overlooked for too long. It’s good to see new offerings coming out more and more. Thanks for an extremely detailed article and excellent script.


↑ Back to top