This is a solution to the Coding bootcamp testimonials slider challenge on Frontend Mentor. Frontend Mentor challenges help you improve your coding skills by building realistic projects.
Users should be able to:
- View the optimal layout for the component depending on their device's screen size
- Navigate the slider using either their mouse/trackpad or keyboard
- Solution URL: click here
- Live Site URL: click here
- Semantic HTML5 markup
- CSS custom properties
- Flexbox
- CSS Grid
- Mobile-first workflow
- CSS transformations and transitions
- Vanilla JavaScript
- Use of
::before
and::after
pseudoelements to add background images:& .previous::before { content: url('../images/icon-prev.svg'); } & .next::before { content: url('../images/icon-next.svg'); }
- Use of the
flex
shorthand to adjust an element to the full width of its parent container (See Useful resources):.slide { display: flex; flex-direction: column; /* flex-grow: 1; flex-shrink: 0; flex-basis: 100%*/ flex: 1 0 100%; height: 665px; }
- Use of the
toggle()
JavaScript method with theforce
parameter to switch a CSS class between two values based on the truthiness of a condition (See Useful resources):function disableButton() { const isAtFirstSlide = currentSlide === 0; const isAtLastSlide = currentSlide === numberOfSlides - 1; previousButton.classList.toggle('disabled', isAtFirstSlide); nextButton.classList.toggle('disabled', isAtLastSlide); }
- Create a DOM
document
using the DOMParser to mock the HTML structure. Select the nodes and pass them as arguments to a Class:beforeEach(() => { // Define an html structure using template literals const html = ` <div class="slider-container"></div> <div class="slider-controls"> <button class="previous" aria-label="Previous"></button> <button class="next" aria-label="Next"></button> </div> `; // Create a new DOMParser instance const parser = new DOMParser(); // Parse the string into a DOM document dom = parser.parseFromString(html, 'text/html'); // Select all the nodes required to instantiate a Class sliderContainer = dom.querySelector('.slider-container'); previousButton = dom.querySelector('.previous'); nextButton = dom.querySelector('.next'); // Create a new instance of 'Slider' and passing the nodes as arguments slider = new Slider({ sliderContainer, previousButton, nextButton, slides}) })
- Use of spies to keep track of usage for
document
native methods likequerySelector
:jest.spyOn(document, 'querySelector').mockImplementation((selector) => { if (selector === '.slider-container') { return sliderContainer; } })
- Use of spies to keep track of usage for custom and lifecycle methods in web components:
// Spy on 'render' method of the 'slideItem' instance const renderSpy = jest.spyOn(slideItem, 'render'); // Spy on the 'connectedCallback' lifecycle method of the 'slideItem' instance const connectedCallbackSpy = jest.spyOn(slideItem, 'connectedCallback');
- Use of new CSS features like container queries
- Use of CSS Grid in complex layouts
- Use of animations with CSS
- Implementation of UI testing
- Use of OOP pattern
- Use of accessibility principles
- Cross-browser support
- Use of web components for reusability
- toggle() JavaScript method - This helped me for toggling an HTMLElement class. I liked to use the `force`` argument because it gives me a more simple logic without using too much conditionals.
- MDN multiple backgrounds - This is an amazing resource showing how can multiple backgrounds been applied with ease.
- Flexbox: flex-grow, flex-shrink y flex-basis - This is an amazing article describing in detail the use of these three flexbox properties.
- DOMparser() interface - Official MDN docs describing in detail the use of this interface to parse HTML from a string into a DOM document.
- Website - Daniel González
- Frontend Mentor - @odagora
- Twitter - @odagora
- MDN documentation
- ChatGPT for code refactoring