This Joomla override allows you to display some articles in a horizontal carousel. You can use different Joomla core modules for this override: mod_articles_category, mod_newsflash, mod_articles_latest, etc. The CSS and the JS codes are added directly in the override, rather than in the 'user.css' and 'user.js' files. At the bottom of this article, you can download the files of the override.
Mobile frontend rendering
PhP markup
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_category
* @author web-eau.net
* @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Helper\ModuleHelper;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;
if (!$list)
{
return;
}
?>
<!-- in case your template doesnt load the Bootstrap carousel component -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
<div class="text-center my-3">
<div class="row mx-auto my-auto justify-content-center una-col-flex">
<div id="recipeCarousel" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner" role="listbox">
<?php foreach ($list as $item) : ?>
<div class="carousel-item active">
<div class="col-md-3">
<div class="card">
<div class="card-img">
<!-- article intro image -->
<?php
$article_images = json_decode($item->images);
$article_image = '';
$article_image_alt = '';
if(isset($article_images->image_intro) && !empty($article_images->image_intro)) {
$article_image = $article_images->image_intro;
$article_image_alt = $article_images->image_intro_alt;
}?>
<a href="<?php echo $item->link; ?>">
<img class="carousel-img img-fluid rounded" src="<?php echo $article_image; ?>" alt="<?php echo $article_image_alt; ?>" >
</a>
</div>
<!-- article title -->
<div class="card-img-overlay d-flex align-items-end px-4">
<a class="fs-5 align-items-end text-white fw-bold text-decoration-none" alt="<?php echo $item->title; ?>" href="<?php echo $item->link; ?>"><?php echo $item->title; ?></a>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<a class="carousel-control-prev bg-transparent w-aut" href="#recipeCarousel" role="button" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
</a>
<a class="carousel-control-next bg-transparent w-aut" href="#recipeCarousel" role="button" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
</a>
</div>
</div>
</div>
<style>
@media (max-width: 767px) {
.carousel-inner .carousel-item > div {display: none;}
.carousel-inner .carousel-item > div:first-child {display: block;}
}
.carousel-inner .carousel-item.active,
.carousel-inner .carousel-item-next,
.carousel-inner .carousel-item-prev {display: flex;}
/* medium and up screens */
@media (min-width: 768px) {
.carousel-inner .carousel-item-end.active,
.carousel-inner .carousel-item-next {transform: translateX(25%);}
.carousel-inner .carousel-item-start.active,
.carousel-inner .carousel-item-prev {transform: translateX(-25%);}
}
.carousel-inner .carousel-item-end,
.carousel-inner .carousel-item-start {transform: translateX(0);}
.carousel-img img {width: 632px !important;background: rgba(53, 53, 53, 0.35);filter: brightness(0.65);overflow: hidden;z-index:-2 !important;}
.una-col-flex img {max-height: 100%;min-width: 100%;object-fit: cover;vertical-align: bottom;filter: brightness(65%);}
</style>
<script>
let items = document.querySelectorAll('.carousel .carousel-item')
items.forEach((el) => {
const minPerSlide = 4
let next = el.nextElementSibling
for (var i=1; i<minPerSlide; i++) {
if (!next) {
// wrap carousel by using first child
next = items[0]
}
let cloneChild = next.cloneNode(true)
el.appendChild(cloneChild.children[0])
next = next.nextElementSibling
}
})
</script>