Material Design CSS framework with interactive JavaScript components for building responsive web applications
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Components for handling images, videos, and media content including lightbox functionality, carousels, sliders, and responsive media display with Material Design styling.
Image lightbox component with zoom functionality and smooth animations.
/**
* Materialbox lightbox component
* @param el - Image element to be lightboxed
* @param options - Configuration options
*/
class Materialbox {
constructor(el: Element, options?: MaterialboxOptions);
static init(els: Element | NodeList, options?: MaterialboxOptions): Materialbox | Materialbox[];
static getInstance(el: Element): Materialbox;
static get defaults(): MaterialboxOptions;
/** Open lightbox */
open(): void;
/** Close lightbox */
close(): void;
destroy(): void;
}
interface MaterialboxOptions {
/** Enter animation duration */
inDuration?: number; // default: 275
/** Exit animation duration */
outDuration?: number; // default: 200
/** Callback before lightbox opens */
onOpenStart?: () => void;
/** Callback after lightbox opens */
onOpenEnd?: () => void;
/** Callback before lightbox closes */
onCloseStart?: () => void;
/** Callback after lightbox closes */
onCloseEnd?: () => void;
}Usage Examples:
<!-- Basic materialbox -->
<img class="materialboxed" width="650" src="images/sample-1.jpg">
<!-- Materialbox with caption -->
<img class="materialboxed" data-caption="A picture of some deer and tons of trees" width="250" src="images/sample-1.jpg">
<!-- Responsive materialbox -->
<img class="materialboxed responsive-img" src="images/sample-1.jpg">// Initialize materialbox
const elems = document.querySelectorAll('.materialboxed');
const instances = M.Materialbox.init(elems, {
inDuration: 400,
onOpenStart: () => console.log('Lightbox opening'),
onCloseEnd: () => console.log('Lightbox closed')
});
// Programmatic control
const instance = M.Materialbox.getInstance(document.querySelector('.materialboxed'));
instance.open();Responsive carousel component for images and content with touch support.
/**
* Carousel component
* @param el - Carousel container element
* @param options - Configuration options
*/
class Carousel {
constructor(el: Element, options?: CarouselOptions);
static init(els: Element | NodeList, options?: CarouselOptions): Carousel | Carousel[];
static getInstance(el: Element): Carousel;
static get defaults(): CarouselOptions;
/** Move to next item(s) */
next(n?: number): void;
/** Move to previous item(s) */
prev(n?: number): void;
/** Move to specific item */
set(n: number, callback?: () => void): void;
destroy(): void;
}
interface CarouselOptions {
/** Animation duration in milliseconds */
duration?: number; // default: 200
/** Zoom scale for non-active items */
dist?: number; // default: -100
/** Spacing for center image */
shift?: number; // default: 0
/** Padding between non-center items */
padding?: number; // default: 0
/** Number of visible items */
numVisible?: number; // default: 5
/** Full width slider */
fullWidth?: boolean; // default: false
/** Show indicator dots */
indicators?: boolean; // default: false
/** Don't wrap around items */
noWrap?: boolean; // default: false
/** Callback when cycle to new item */
onCycleTo?: (item: Element, dragged: boolean) => void;
}Usage Examples:
<!-- Basic carousel -->
<div class="carousel">
<a class="carousel-item" href="#one!"><img src="images/sample-1.jpg"></a>
<a class="carousel-item" href="#two!"><img src="images/sample-2.jpg"></a>
<a class="carousel-item" href="#three!"><img src="images/sample-3.jpg"></a>
<a class="carousel-item" href="#four!"><img src="images/sample-4.jpg"></a>
<a class="carousel-item" href="#five!"><img src="images/sample-5.jpg"></a>
</div>
<!-- Full width carousel -->
<div class="carousel carousel-slider center">
<div class="carousel-fixed-item center">
<a class="btn waves-effect white grey-text darken-text-2">button</a>
</div>
<div class="carousel-item red white-text" href="#one!">
<h2>First Panel</h2>
<p class="white-text">This is your first panel</p>
</div>
<div class="carousel-item amber white-text" href="#two!">
<h2>Second Panel</h2>
<p class="white-text">This is your second panel</p>
</div>
</div>// Initialize carousel
const elems = document.querySelectorAll('.carousel');
const instances = M.Carousel.init(elems, {
fullWidth: false,
indicators: true,
duration: 300,
onCycleTo: (item) => console.log('Cycled to:', item)
});
// Carousel navigation
const instance = M.Carousel.getInstance(document.querySelector('.carousel'));
instance.next(); // Go to next item
instance.prev(); // Go to previous item
instance.set(2); // Go to third item (0-indexed)Full-width image slider with indicators and automatic transitions.
/**
* Slider component
* @param el - Slider container element
* @param options - Configuration options
*/
class Slider {
constructor(el: Element, options?: SliderOptions);
static init(els: Element | NodeList, options?: SliderOptions): Slider | Slider[];
static getInstance(el: Element): Slider;
static get defaults(): SliderOptions;
/** Go to next slide */
next(): void;
/** Go to previous slide */
prev(): void;
/** Pause automatic transitions */
pause(): void;
/** Start automatic transitions */
start(): void;
destroy(): void;
}
interface SliderOptions {
/** Show indicator dots */
indicators?: boolean; // default: true
/** Slider height in pixels */
height?: number; // default: 400
/** Transition duration */
duration?: number; // default: 500
/** Interval between automatic transitions */
interval?: number; // default: 6000
}Usage Examples:
<!-- Basic slider -->
<div class="slider">
<ul class="slides">
<li>
<img src="images/slider1.jpg">
<div class="caption center-align">
<h3>This is our big Tagline!</h3>
<h5 class="light grey-text text-lighten-3">Here's our small slogan.</h5>
</div>
</li>
<li>
<img src="images/slider2.jpg">
<div class="caption left-align">
<h3>Left Aligned Caption</h3>
<h5 class="light grey-text text-lighten-3">Here's our small slogan.</h5>
</div>
</li>
</ul>
</div>// Initialize slider
const elems = document.querySelectorAll('.slider');
const instances = M.Slider.init(elems, {
indicators: true,
height: 500,
duration: 600,
interval: 4000
});
// Slider control
const instance = M.Slider.getInstance(document.querySelector('.slider'));
instance.pause(); // Pause auto-slide
instance.start(); // Resume auto-slideParallax scrolling effect for background images.
/**
* Parallax component
* @param el - Parallax container element
* @param options - Configuration options
*/
class Parallax {
constructor(el: Element, options?: ParallaxOptions);
static init(els: Element | NodeList, options?: ParallaxOptions): Parallax | Parallax[];
static getInstance(el: Element): Parallax;
static get defaults(): ParallaxOptions;
destroy(): void;
}
interface ParallaxOptions {
/** Responsive threshold in pixels */
responsiveThreshold?: number; // default: 0
}Usage Examples:
<!-- Parallax container -->
<div class="parallax-container">
<div class="parallax"><img src="images/parallax1.jpg"></div>
</div>
<!-- Content section -->
<div class="section white">
<div class="row container">
<h2 class="header">Parallax</h2>
<p class="grey-text text-darken-3 lighten-3">
Parallax is an effect where the background content is moved at a different speed than the foreground content.
</p>
</div>
</div>
<!-- Another parallax -->
<div class="parallax-container">
<div class="parallax"><img src="images/parallax2.jpg"></div>
</div>// Initialize parallax
const elems = document.querySelectorAll('.parallax');
const instances = M.Parallax.init(elems);CSS Classes:
/* Parallax classes */
.parallax-container {
/* Parallax container */
position: relative;
overflow: hidden;
height: 500px;
}
.parallax {
/* Parallax image container */
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.parallax img {
/* Parallax image */
display: block;
position: absolute;
left: 50%;
bottom: 0;
min-width: 100%;
min-height: 100%;
transform: translate3d(-50%, 0, 0);
transform-style: preserve-3d;
backface-visibility: hidden;
}CSS utilities for responsive image handling.
/* Responsive image classes */
.responsive-img {
/* Responsive image */
max-width: 100%;
height: auto;
}
.responsive-video {
/* Responsive video container */
position: relative;
padding-bottom: 56.25%; /* 16:9 aspect ratio */
padding-top: 30px;
height: 0;
overflow: hidden;
}
.responsive-video iframe,
.responsive-video object,
.responsive-video embed {
/* Responsive video content */
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.video-container {
/* Video wrapper */
position: relative;
padding-bottom: 56.25%;
height: 0;
overflow: hidden;
}
.video-container iframe,
.video-container object,
.video-container embed {
/* Video content */
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}Usage Examples:
<!-- Responsive image -->
<img class="responsive-img" src="images/sample-1.jpg">
<!-- Responsive video -->
<div class="video-container">
<iframe width="853" height="480" src="//www.youtube.com/embed/Q8TXgCzxEnw?rel=0" frameborder="0" allowfullscreen></iframe>
</div>
<!-- Responsive embedded content -->
<div class="responsive-video">
<iframe src="https://player.vimeo.com/video/22439234" frameborder="0"></iframe>
</div>/* Media query mixins for responsive design */
@media only screen and (max-width: 600px) {
/* Small screens */
.hide-on-small-only { display: none !important; }
}
@media only screen and (max-width: 992px) {
/* Medium and small screens */
.hide-on-med-and-down { display: none !important; }
}
@media only screen and (min-width: 601px) {
/* Medium and large screens */
.hide-on-med-and-up { display: none !important; }
}
@media only screen and (min-width: 600px) and (max-width: 992px) {
/* Medium screens only */
.hide-on-med-only { display: none !important; }
}
@media only screen and (min-width: 993px) {
/* Large screens only */
.hide-on-large-only { display: none !important; }
}<!-- Gallery grid -->
<div class="row">
<div class="col s12 m6 l4">
<img class="materialboxed responsive-img"
data-caption="Gallery Image 1"
src="images/gallery1.jpg">
</div>
<div class="col s12 m6 l4">
<img class="materialboxed responsive-img"
data-caption="Gallery Image 2"
src="images/gallery2.jpg">
</div>
<div class="col s12 m6 l4">
<img class="materialboxed responsive-img"
data-caption="Gallery Image 3"
src="images/gallery3.jpg">
</div>
</div><!-- Hero parallax section -->
<div id="index-banner" class="parallax-container">
<div class="section no-pad-bot">
<div class="container">
<br><br>
<h1 class="header center teal-text text-lighten-2">Materialize</h1>
<div class="row center">
<h5 class="header col s12 light">A modern responsive front-end framework</h5>
</div>
<div class="row center">
<a href="#" class="btn-large waves-effect waves-light teal lighten-1">Get Started</a>
</div>
<br><br>
</div>
</div>
<div class="parallax"><img src="images/background1.jpg" alt="Unsplashed background img 1"></div>
</div><!-- Carousel with external controls -->
<div class="carousel-wrapper">
<div class="carousel" id="custom-carousel">
<a class="carousel-item" href="#!"><img src="images/sample-1.jpg"></a>
<a class="carousel-item" href="#!"><img src="images/sample-2.jpg"></a>
<a class="carousel-item" href="#!"><img src="images/sample-3.jpg"></a>
</div>
<!-- Custom navigation -->
<div class="carousel-nav center">
<a class="btn-floating btn-small waves-effect waves-light" onclick="prevCarousel()">
<i class="material-icons">keyboard_arrow_left</i>
</a>
<a class="btn-floating btn-small waves-effect waves-light" onclick="nextCarousel()">
<i class="material-icons">keyboard_arrow_right</i>
</a>
</div>
</div>// Custom carousel navigation
function nextCarousel() {
const instance = M.Carousel.getInstance(document.getElementById('custom-carousel'));
instance.next();
}
function prevCarousel() {
const instance = M.Carousel.getInstance(document.getElementById('custom-carousel'));
instance.prev();
}// Lazy loading implementation
function lazyLoadImages() {
const images = document.querySelectorAll('img[data-src]');
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazy');
imageObserver.unobserve(img);
}
});
});
images.forEach(img => imageObserver.observe(img));
}
// Initialize lazy loading
document.addEventListener('DOMContentLoaded', lazyLoadImages);<!-- Lazy loaded images -->
<img class="responsive-img lazy" data-src="images/sample-1.jpg" alt="Sample Image">
<img class="responsive-img lazy" data-src="images/sample-2.jpg" alt="Sample Image">// Initialize all media components
document.addEventListener('DOMContentLoaded', function() {
// Initialize materialbox
M.Materialbox.init(document.querySelectorAll('.materialboxed'));
// Initialize carousels
M.Carousel.init(document.querySelectorAll('.carousel'), {
fullWidth: true,
indicators: true
});
// Initialize sliders
M.Slider.init(document.querySelectorAll('.slider'));
// Initialize parallax
M.Parallax.init(document.querySelectorAll('.parallax'));
});// Handle responsive changes
window.addEventListener('resize', function() {
// Reinitialize components that need recalculation
const carousels = document.querySelectorAll('.carousel');
carousels.forEach(carousel => {
const instance = M.Carousel.getInstance(carousel);
if (instance) {
instance.destroy();
M.Carousel.init(carousel);
}
});
});// Add new media content dynamically
function addCarouselItem(imageSrc, caption) {
const carousel = document.querySelector('.carousel');
const newItem = document.createElement('a');
newItem.className = 'carousel-item';
newItem.href = '#!';
const img = document.createElement('img');
img.src = imageSrc;
img.alt = caption;
newItem.appendChild(img);
carousel.appendChild(newItem);
// Reinitialize carousel
const instance = M.Carousel.getInstance(carousel);
instance.destroy();
M.Carousel.init(carousel);
}