react-image-gallery
Version:
React carousel image gallery component with thumbnail and mobile support
703 lines (605 loc) • 17 kB
CSS
/**
* React Image Gallery - Styles
*
* Design System: Base-4 spacing scale
* Spacing: 2, 4, 8, 12, 16, 20, 24, 32, 48, 64, 80, 96, 120px
*
* CSS Custom Properties for theming:
* --ig-primary-color: Primary/accent color (default: #337ab7)
* --ig-white: Icon and text color (default: #fff)
* --ig-black: Background color in fullscreen (default: #000)
* --ig-background-overlay: Overlay background (default: rgba(0, 0, 0, 0.4))
* --ig-thumbnail-size: Thumbnail dimensions (default: 96px)
* --ig-thumbnail-size-small: Thumbnail size on small screens (default: 80px)
* --ig-thumbnail-border-width: Thumbnail border width (default: 4px)
* --ig-thumbnail-border-width-small: Thumbnail border on small screens (default: 3px)
* --ig-bullet-size: Bullet size (default: 4px)
* --ig-bullet-size-small: Bullet size on small screens (default: 3px)
*/
:root {
--ig-primary-color: #337ab7;
--ig-white: #fff;
--ig-black: #000;
--ig-background-overlay: rgba(0, 0, 0, 0.4);
--ig-thumbnail-size: 96px;
--ig-thumbnail-size-small: 80px;
--ig-thumbnail-border-width: 4px;
--ig-thumbnail-border-width-small: 3px;
--ig-bullet-size: 4px;
--ig-bullet-size-small: 3px;
}
/* ==========================================================================
SVG Icon Styles
========================================================================== */
.image-gallery-icon {
color: var(--ig-white, #fff);
transition: all 0.3s ease-out;
appearance: none;
background-color: transparent;
border: 0;
cursor: pointer;
outline: none;
position: absolute;
z-index: 4;
filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.5));
}
@media (hover: hover) and (pointer: fine) {
.image-gallery-icon:hover {
color: var(--ig-primary-color, #337ab7);
}
.image-gallery-icon:hover .image-gallery-svg {
transform: scale(1.1);
}
}
.image-gallery-icon:focus {
outline: 2px solid var(--ig-primary-color, #337ab7);
}
.image-gallery-using-mouse .image-gallery-icon:focus {
outline: none;
}
/* Fullscreen & Play buttons */
.image-gallery-fullscreen-button,
.image-gallery-play-button {
bottom: 0;
padding: 20px;
}
.image-gallery-fullscreen-button .image-gallery-svg,
.image-gallery-play-button .image-gallery-svg {
height: 32px;
width: 32px;
}
@media (max-width: 768px) {
.image-gallery-fullscreen-button,
.image-gallery-play-button {
padding: 16px;
}
.image-gallery-fullscreen-button .image-gallery-svg,
.image-gallery-play-button .image-gallery-svg {
height: 24px;
width: 24px;
}
}
@media (max-width: 480px) {
.image-gallery-fullscreen-button,
.image-gallery-play-button {
padding: 12px;
}
.image-gallery-fullscreen-button .image-gallery-svg,
.image-gallery-play-button .image-gallery-svg {
height: 16px;
width: 16px;
}
}
.image-gallery-fullscreen-button {
right: 0;
}
.image-gallery-play-button {
left: 0;
}
/* Top & Bottom navigation */
.image-gallery-top-nav,
.image-gallery-bottom-nav {
padding: 12px;
left: 50%;
transform: translateX(-50%);
}
.image-gallery-top-nav .image-gallery-svg,
.image-gallery-bottom-nav .image-gallery-svg {
height: 120px;
width: 96px;
}
@media (max-width: 768px) {
.image-gallery-top-nav .image-gallery-svg,
.image-gallery-bottom-nav .image-gallery-svg {
height: 72px;
width: 48px;
}
}
@media (max-width: 480px) {
.image-gallery-top-nav .image-gallery-svg,
.image-gallery-bottom-nav .image-gallery-svg {
height: 48px;
width: 32px;
}
}
.image-gallery-top-nav[disabled],
.image-gallery-bottom-nav[disabled] {
cursor: not-allowed;
opacity: 0.6;
pointer-events: none;
}
.image-gallery-top-nav {
top: 0;
}
.image-gallery-bottom-nav {
bottom: 0;
}
/* Left & Right navigation */
.image-gallery-left-nav,
.image-gallery-right-nav {
padding: 48px 12px;
top: 50%;
transform: translateY(-50%);
}
.image-gallery-left-nav .image-gallery-svg,
.image-gallery-right-nav .image-gallery-svg {
height: 120px;
width: 64px;
}
@media (max-width: 768px) {
.image-gallery-left-nav .image-gallery-svg,
.image-gallery-right-nav .image-gallery-svg {
height: 72px;
width: 32px;
}
}
@media (max-width: 480px) {
.image-gallery-left-nav .image-gallery-svg,
.image-gallery-right-nav .image-gallery-svg {
height: 48px;
width: 24px;
}
}
.image-gallery-left-nav[disabled],
.image-gallery-right-nav[disabled] {
cursor: not-allowed;
opacity: 0.6;
pointer-events: none;
}
.image-gallery-left-nav {
left: 0;
}
.image-gallery-right-nav {
right: 0;
}
/* ==========================================================================
Gallery Container
========================================================================== */
.image-gallery {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: transparent;
position: relative;
/* Prevent mobile overscroll/pull-to-refresh */
overscroll-behavior: none;
-webkit-overflow-scrolling: touch;
}
.image-gallery.fullscreen-modal {
background: var(--ig-black, #000);
bottom: 0;
height: 100%;
left: 0;
position: fixed;
right: 0;
top: 0;
width: 100%;
z-index: 5;
}
.image-gallery.fullscreen-modal .image-gallery-content {
top: 50%;
transform: translateY(-50%);
}
/* ==========================================================================
Gallery Content
========================================================================== */
.image-gallery-content {
position: relative;
line-height: 0;
top: 0;
}
.image-gallery-content.fullscreen {
background: var(--ig-black, #000);
}
.image-gallery-content .image-gallery-slide .image-gallery-image {
max-height: calc(100vh - 80px);
}
.image-gallery-content.image-gallery-thumbnails-left
.image-gallery-slide
.image-gallery-image,
.image-gallery-content.image-gallery-thumbnails-right
.image-gallery-slide
.image-gallery-image {
max-height: 100vh;
}
/* ==========================================================================
Slide Wrapper
========================================================================== */
.image-gallery-slide-wrapper {
position: relative;
}
.image-gallery-slide-wrapper.image-gallery-thumbnails-left,
.image-gallery-slide-wrapper.image-gallery-thumbnails-right {
display: inline-block;
width: calc(100% - 112px);
}
@media (max-width: 768px) {
.image-gallery-slide-wrapper.image-gallery-thumbnails-left,
.image-gallery-slide-wrapper.image-gallery-thumbnails-right {
width: calc(100% - 88px);
}
}
.image-gallery-slide-wrapper.image-gallery-rtl {
direction: rtl;
}
.image-gallery-swipe {
overflow: hidden;
/* GPU acceleration */
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-transform: translateZ(0);
transform: translateZ(0);
touch-action: pan-y pinch-zoom;
}
/* ==========================================================================
Slides
========================================================================== */
.image-gallery-slides {
overflow: hidden;
position: relative;
/* Allow vertical scroll and pinch-zoom; block horizontal pan so JS handles swipe.
The browser's built-in direction detection prevents vertical scroll during
horizontal swipes. On desktop, wheel/trackpad scroll passes through normally. */
touch-action: pan-y pinch-zoom;
/* GPU acceleration for smooth swiping */
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
contain: layout style paint;
isolation: isolate;
}
/* Flex container that holds all slides and gets transformed */
.image-gallery-slides-container {
display: flex;
/* GPU acceleration for smooth swiping */
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
will-change: transform;
}
.image-gallery-slides-container.vertical {
flex-direction: column;
height: 100%;
}
.image-gallery-slides-container.vertical .image-gallery-slide {
flex: 0 0 100%;
height: 100%;
min-height: 0;
}
.image-gallery-slides-container.vertical
.image-gallery-slide
.image-gallery-image {
height: 100%;
width: auto;
max-width: 100%;
}
.image-gallery-slide {
flex: 0 0 100%;
min-width: 0;
position: relative;
/* GPU acceleration for smooth swiping */
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.image-gallery-slide .image-gallery-image {
width: 100%;
object-fit: contain;
}
.image-gallery-slide .image-gallery-description {
background: var(--ig-background-overlay, rgba(0, 0, 0, 0.4));
bottom: 72px;
color: var(--ig-white, #fff);
left: 0;
line-height: 1;
padding: 12px 20px;
position: absolute;
white-space: normal;
}
@media (max-width: 768px) {
.image-gallery-slide .image-gallery-description {
bottom: 48px;
font-size: 0.8em;
padding: 8px 16px;
}
}
/* ==========================================================================
Bullets
========================================================================== */
.image-gallery-bullets {
bottom: 20px;
left: 0;
margin: 0 auto;
position: absolute;
right: 0;
width: 80%;
z-index: 4;
text-align: center;
}
.image-gallery-bullets .image-gallery-bullets-container {
margin: 0 auto;
padding: 0;
display: inline-block;
}
.image-gallery-bullets .image-gallery-bullets-inner {
display: flex;
align-items: center;
justify-content: flex-start;
white-space: nowrap;
padding: 2px 0;
}
.image-gallery-bullets .image-gallery-bullet {
appearance: none;
background-color: transparent;
border: 1px solid var(--ig-white, #fff);
border-radius: 50%;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
cursor: pointer;
margin: 0 4px;
outline: none;
width: calc(var(--ig-bullet-size, 4px) * 2 + 2px);
height: calc(var(--ig-bullet-size, 4px) * 2 + 2px);
padding: 0;
flex-shrink: 0;
transition: all 0.2s ease-out;
}
@media (max-width: 768px) {
.image-gallery-bullets .image-gallery-bullet {
margin: 0 3px;
width: calc(var(--ig-bullet-size-small, 3px) * 2 + 2px);
height: calc(var(--ig-bullet-size-small, 3px) * 2 + 2px);
}
}
@media (max-width: 480px) {
.image-gallery-bullets .image-gallery-bullet {
width: 8px;
height: 8px;
}
}
.image-gallery-bullets .image-gallery-bullet:focus {
transform: scale(1.2);
background: var(--ig-primary-color, #337ab7);
border: 1px solid var(--ig-primary-color, #337ab7);
}
.image-gallery-bullets .image-gallery-bullet.active {
transform: scale(1.2);
border: 1px solid var(--ig-white, #fff);
background: var(--ig-white, #fff);
}
@media (hover: hover) and (pointer: fine) {
.image-gallery-bullets .image-gallery-bullet:hover {
background: var(--ig-primary-color, #337ab7);
border: 1px solid var(--ig-primary-color, #337ab7);
}
.image-gallery-bullets .image-gallery-bullet.active:hover {
background: var(--ig-primary-color, #337ab7);
}
}
/* Vertical bullets */
.image-gallery-bullets.image-gallery-bullets-vertical {
left: 20px;
right: auto;
bottom: auto;
width: auto;
top: 50%;
transform: translateY(-50%);
}
.image-gallery-bullets.image-gallery-bullets-vertical
.image-gallery-bullets-inner {
flex-direction: column;
padding: 0 2px;
}
.image-gallery-bullets.image-gallery-bullets-vertical .image-gallery-bullet {
display: block;
margin: 4px 0;
}
@media (max-width: 768px) {
.image-gallery-bullets.image-gallery-bullets-vertical .image-gallery-bullet {
margin: 3px 0;
}
}
@media (max-width: 480px) {
.image-gallery-bullets.image-gallery-bullets-vertical .image-gallery-bullet {
margin: 3px 0;
}
}
/* ==========================================================================
Thumbnails Wrapper
========================================================================== */
.image-gallery-thumbnails-wrapper {
position: relative;
}
.image-gallery-thumbnails-wrapper.thumbnails-swipe-horizontal {
touch-action: pan-y;
}
.image-gallery-thumbnails-wrapper.thumbnails-swipe-vertical {
touch-action: pan-x;
}
.image-gallery-thumbnails-wrapper.thumbnails-wrapper-rtl {
direction: rtl;
}
.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-left,
.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-right {
display: inline-block;
vertical-align: top;
width: var(--ig-thumbnail-size, 96px);
}
@media (max-width: 768px) {
.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-left,
.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-right {
width: var(--ig-thumbnail-size-small, 80px);
}
}
.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-left
.image-gallery-thumbnails,
.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-right
.image-gallery-thumbnails {
height: 100%;
width: 100%;
left: 0;
padding: 0;
position: absolute;
top: 0;
}
.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-left
.image-gallery-thumbnails
.image-gallery-thumbnail,
.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-right
.image-gallery-thumbnails
.image-gallery-thumbnail {
display: block;
margin-right: 0;
padding: 0;
}
.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-left
.image-gallery-thumbnails
.image-gallery-thumbnail
+ .image-gallery-thumbnail,
.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-right
.image-gallery-thumbnails
.image-gallery-thumbnail
+ .image-gallery-thumbnail {
margin-left: 0;
margin-top: 2px;
}
.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-left,
.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-right {
margin: 0 4px;
}
@media (max-width: 768px) {
.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-left,
.image-gallery-thumbnails-wrapper.image-gallery-thumbnails-right {
margin: 0 4px;
}
}
/* ==========================================================================
Thumbnails
========================================================================== */
.image-gallery-thumbnails {
overflow: hidden;
padding: 4px 0;
}
@media (max-width: 768px) {
.image-gallery-thumbnails {
padding: 4px 0;
}
}
.image-gallery-thumbnails .image-gallery-thumbnails-container {
cursor: pointer;
text-align: center;
white-space: nowrap;
}
.image-gallery-thumbnail {
display: inline-block;
border: var(--ig-thumbnail-border-width, 4px) solid transparent;
transition: border 0.3s ease-out;
width: var(--ig-thumbnail-size, 96px);
background: transparent;
padding: 0;
}
@media (max-width: 768px) {
.image-gallery-thumbnail {
border: var(--ig-thumbnail-border-width-small, 3px) solid transparent;
width: var(--ig-thumbnail-size-small, 80px);
}
}
.image-gallery-thumbnail + .image-gallery-thumbnail {
margin-left: 2px;
}
.image-gallery-thumbnail .image-gallery-thumbnail-inner {
display: block;
position: relative;
}
.image-gallery-thumbnail .image-gallery-thumbnail-image {
vertical-align: middle;
width: 100%;
line-height: 0;
}
.image-gallery-thumbnail.active,
.image-gallery-thumbnail:focus {
outline: none;
border: var(--ig-thumbnail-border-width, 4px) solid
var(--ig-primary-color, #337ab7);
}
@media (max-width: 768px) {
.image-gallery-thumbnail.active,
.image-gallery-thumbnail:focus {
border: var(--ig-thumbnail-border-width-small, 3px) solid
var(--ig-primary-color, #337ab7);
}
}
@media (hover: hover) and (pointer: fine) {
.image-gallery-thumbnail:hover {
outline: none;
border: var(--ig-thumbnail-border-width, 4px) solid
var(--ig-primary-color, #337ab7);
}
}
@media (hover: hover) and (pointer: fine) and (max-width: 768px) {
.image-gallery-thumbnail:hover {
border: var(--ig-thumbnail-border-width-small, 3px) solid
var(--ig-primary-color, #337ab7);
}
}
/* ==========================================================================
Thumbnail Label
========================================================================== */
.image-gallery-thumbnail-label {
box-sizing: border-box;
color: var(--ig-white, #fff);
font-size: 1em;
left: 0;
line-height: 1em;
padding: 5%;
position: absolute;
top: 50%;
text-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
transform: translateY(-50%);
white-space: normal;
width: 100%;
}
@media (max-width: 768px) {
.image-gallery-thumbnail-label {
font-size: 0.8em;
line-height: 0.8em;
}
}
/* ==========================================================================
Index Display
========================================================================== */
.image-gallery-index {
background: var(--ig-background-overlay, rgba(0, 0, 0, 0.4));
color: var(--ig-white, #fff);
line-height: 1;
padding: 10px 20px;
position: absolute;
right: 0;
top: 0;
z-index: 4;
}
@media (max-width: 768px) {
.image-gallery-index {
font-size: 0.8em;
padding: 5px 10px;
}
}