tailwindCSS - 如何在旋转木马幻灯片上添加按钮?
tailwindCSS - How to add a Button on a carousel slide?
我一直在玩这个 Carousel created by Tom Smedley。他使用 AlpineJS 和 TailwindCSS。这真是一个华丽的设计。
我有re-edited上面链接的代码笔来解决我的问题。
Here is my version of the sandbox which replicates the problem
我为每个轮播幻灯片添加了一个 LEARN MORE
按钮,但是该按钮隐藏在 <h1>
内容 header 后面。为了测试,我在按钮上添加了悬停效果来改变颜色,但是按钮不能悬停。
- 如何将按钮固定在
<h1>
文本的前面并使其自身位于 <h1>
header 的左下方?我可以通过设置按钮边距来解决这个问题,但由于每张幻灯片上文本长度的性质,这不是一个好的解决方案。
这是我的目标截图:
我不关心按钮是否在幻灯片之外(由于 h1 文本长度),我只希望它位于 header 文本的左下方。
我尝试了很多使用 flex、grids 等的尝试...但我一直在挣扎。谢谢你的帮助。
将所有 <button>
标签放在 <h1>
标签内,并插入以下 CSS:
h1 > button {
position: absolute !important;
left: 0;
top: 100%;
font-size: 1rem !important;
}
我还包含了一个片段。 运行 全屏模式:
function carousel() {
return {
active: 0,
init() {
var flkty = new Flickity(this.$refs.carousel, {
wrapAround: true,
});
flkty.on("change", (i) => (this.active = i));
},
};
}
function carouselFilter() {
return {
active: 0,
changeActive(i) {
this.active = i;
this.$nextTick(() => {
let flkty = Flickity.data(
this.$el.querySelectorAll(".carousel")[i]
);
flkty.resize();
console.log(flkty);
});
},
};
}
.flickity-viewport {
height: 500px !important;
}
h1 > button {
position: absolute !important;
left: 0;
top: 100%;
font-size: 1rem !important;
pointer-events: auto; /* This is part of EDIT 2 */
}
<html>
<head></head>
<script src="https://unpkg.com/flickity@2/dist/flickity.pkgd.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/flickity@2/dist/flickity.min.css">
<link rel="stylesheet" href="https://unpkg.com/tailwindcss@1.2.0/dist/tailwind.min.css">
<body>
<main
class="min-h-screen bg-black text-white flex items-center justify-center"
x-data="carouselFilter()"
>
<div class="container grid grid-cols-1">
<div class="flex py-12 justify-center">
<a
class="
px-2
text-lg
uppercase
font-bold
tracking-widest
hover:text-white
"
:class="{ 'text-gray-800': active != 0 }"
href="#"
@click.prevent="changeActive(0)"
>Lorem Ipsum</a
>
</div>
<div
class="row-start-2 col-start-1"
x-show="active == 0"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform scale-90"
x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-300"
x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 transform scale-90"
>
<div
class="grid grid-cols-1 grid-rows-1"
x-data="carousel()"
x-init="init()"
>
<div
class="
col-start-1
row-start-1
relative
z-20
flex
items-center
justify-center
pointer-events-none
"
>
<h1
class="absolute text-5xl uppercase font-black tracking-widest"
x-show="active == 0"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12"
>
Lorem Ipsum is simply dummy text of the printing and typesetting
industry. Lorem Ipsum has been the industry's standard dummy
text ever since the 1500s
<button
class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
"
x-show="active == 0"
>
LEARN MORE
</button>
</h1>
<h1
class="absolute text-5xl uppercase font-black tracking-widest"
x-show="active == 1"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12"
>
It is a long established fact that a reader will be distracted
by the readable content of a page when looking at its layout.
<button
class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
"
x-show="active == 1"
>
LEARN MORE
</button>
</h1>
<h1
class="absolute text-5xl uppercase font-black tracking-widest"
x-show="active == 2"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12"
>
There are many variations of passages of Lorem Ipsum available
<button
class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
"
x-show="active == 2"
>
LEARN MORE
</button>
</h1>
<h1
class="absolute text-5xl uppercase font-black tracking-widest"
x-show="active == 3"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12"
>
but the majority have suffered alteration in some form
<button
class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
"
x-show="active == 3"
>
LEARN MORE
</button>
</h1>
</div>
<div class="carousel col-start-1 row-start-1" x-ref="carousel">
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1581375221876-8f287f7cd2cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=770&q=80"
loading="lazy"
/>
</div>
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1581375279144-bb3b381c7046?ixlib=rb-1.2.1&auto=format&fit=crop&w=770&q=80"
loading="lazy"
/>
</div>
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1581375303816-4a17124934f7?ixlib=rb-1.2.1&auto=format&fit=crop&w=770&q=80"
loading="lazy"
/>
</div>
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1494253109108-2e30c049369b?ixlib=rb-1.2.1&auto=format&fit=crop&w=770&q=80"
loading="lazy"
/>
</div>
</div>
</div>
</div>
<div
class="row-start-2 col-start-1"
x-show="active == 1"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform scale-90"
x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-300"
x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 transform scale-90"
></div>
</div>
</main>
</body>
</html>
您无法对按钮应用悬停效果的原因是 pointer-events
属性 已设置为 none
,在 div 包含 <h1>
和 <button>
标签。这是因为如果不这样设置,则应用于背景的拖动功能将不起作用。因此,它是能够单击按钮并突出显示标题文本,还是能够拖动和滚动背景之间的选择。
如果删除 pointer-events-none class,您会注意到悬停效果在按钮上起作用。
编辑:
好的,所以我们进入第 2 部分。基本上我们需要做的是将按钮提升到 headers 所在的级别。当此页面在 [=100= 中呈现时],您可以使用 DevTools 检查元素。我从 DOM 复制了按钮元素,并将它们放在与所有 <h1>
标签相同的容器中。所以现在你有 2 组按钮。这是一组的样子:
<button class="flickity-button flickity-prev-next-button previous custom-flickity-button" type="button" aria-label="Previous" onclick="slide('previous')">
<svg class="flickity-button-icon" viewBox="0 0 100 100">
<path d="M 10,50 L 60,100 L 70,90 L 30,50 L 70,10 L 60,0 Z" class="arrow"></path>
</svg>
</button>
<button class="flickity-button flickity-prev-next-button custom-flickity-button next" type="button" aria-label="Next" onclick="slide('next')">
<svg class="flickity-button-icon" viewBox="0 0 100 100">
<path d="M 10,50 L 60,100 L 70,90 L 30,50 L 70,10 L 60,0 Z" class="arrow" transform="translate(100, 100) rotate(180) "></path>
</svg>
</button>
稍微浏览一下 Flickity 文档,您会发现按钮是 optional,用于渲染。同样,因为我们不会直接与 Flickity 实例交互,所以我在初始化时禁用了拖动功能。这看起来像这样:
function carousel() {
return {
active: 0,
init() {
var flkty = new Flickity(this.$refs.carousel, {
wrapAround: true,
draggable: false, // This is new
prevNextButtons: false // This is new
});
flkty.on("change", (i) => (this.active = i));
}
};
}
由于我们添加的新按钮基本上都是 Flickity 使用的按钮,因此我们真的不需要太担心样式问题。只需要稍作修改。为了减少意外修改实际 CSS 的机会,我添加了 class custom-flickity-button
.
附加样式:
.custom-flickity-button {
/* 21 is the threshold. Below this, it will be under the h1 text */
z-index: 25;
}
.custom-flickity-button:focus {
outline: none;
box-shadow: none;
}
/*
If you make h1 relative, then this padding will apply.
But that was causing some issues while transitioning.
I'm leaving this for you to explore.
*/
#text-container {
padding: 0 70px;
}
最后,我们需要为新按钮提供一些点击功能:
// This is to make the new buttons slide. You can modify the logic to work with multiple carousels, as you've done above
function slide(value) {
let flkty = Flickity.data(document.querySelector('.carousel'))
if (value == 'next') {
flkty.next()
} else if (value == 'previous') {
flkty.previous()
}
}
我不太熟悉使用 Alpine 和 Tailwind,因此您可以修改此代码以适应它。但无论如何,这就是你所要求的。带有交互式滑块按钮的交互式 了解更多 按钮。
function carousel() {
return {
active: 0,
init() {
var flkty = new Flickity(this.$refs.carousel, {
wrapAround: true,
});
flkty.on("change", (i) => (this.active = i));
},
};
}
function carouselFilter() {
return {
active: 0,
changeActive(i) {
this.active = i;
this.$nextTick(() => {
let flkty = Flickity.data(
this.$el.querySelectorAll(".carousel")[i]
);
flkty.resize();
console.log(flkty);
});
},
};
}
// This is to make the new buttons slide. You can modify the logic to work with multiple carousels, as you've done above
function slide(value) {
let flkty = Flickity.data(document.querySelector('.carousel'))
if (value == 'next') {
flkty.next()
} else if (value == 'previous') {
flkty.previous()
}
}
.flickity-viewport {
height: 500px !important;
}
h1 > button {
position: absolute !important;
left: 0;
top: 100%;
font-size: 1rem !important;
}
.custom-flickity-button {
/* 21 is the threshold. Below this, it will be under the h1 text */
z-index: 1
}
.custom-flickity-button:focus {
outline: none;
box-shadow: none;
border: none;
}
/*
If you make h1 relative, then this padding will apply.
But that was causing some issues while transitioning.
I'm leaving this for you to explore.
*/
#text-container {
padding: 0 70px;
}
<html>
<head></head>
<script src="https://unpkg.com/flickity@2/dist/flickity.pkgd.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/flickity@2/dist/flickity.min.css">
<link rel="stylesheet" href="https://unpkg.com/tailwindcss@1.2.0/dist/tailwind.min.css">
<body>
<main class="min-h-screen bg-black text-white flex items-center justify-center" x-data="carouselFilter()">
<div class="container grid grid-cols-1">
<div class="flex py-12 justify-center">
<a class="
px-2
text-lg
uppercase
font-bold
tracking-widest
hover:text-white
" :class="{ 'text-gray-800': active != 0 }" href="#" @click.prevent="changeActive(0)">Lorem Ipsum</a>
</div>
<div class="row-start-2 col-start-1" x-show="active == 0" x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform scale-90" x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-300" x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 transform scale-90">
<div class="grid grid-cols-1 grid-rows-1" x-data="carousel()" x-init="init()">
<div class="
col-start-1
row-start-1
relative
z-20
flex
items-center
justify-center
" id="text-container">
<button class="flickity-button flickity-prev-next-button previous custom-flickity-button" type="button"
aria-label="Previous" onclick="slide('previous')"><svg class="flickity-button-icon" viewBox="0 0 100 100">
<path d="M 10,50 L 60,100 L 70,90 L 30,50 L 70,10 L 60,0 Z" class="arrow"></path>
</svg></button>
<button class="flickity-button flickity-prev-next-button custom-flickity-button next" type="button"
aria-label="Next" onclick="slide('next')"><svg class="flickity-button-icon" viewBox="0 0 100 100">
<path d="M 10,50 L 60,100 L 70,90 L 30,50 L 70,10 L 60,0 Z" class="arrow"
transform="translate(100, 100) rotate(180) "></path>
</svg></button>
<h1 class="absolute text-5xl uppercase font-black tracking-widest" x-show="active == 0"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12">
Lorem Ipsum is simply dummy text of the printing and typesetting
industry. Lorem Ipsum has been the industry's standard dummy
text ever since the 1500s
<button class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
" x-show="active == 0">
LEARN MORE
</button>
</h1>
<h1 class="absolute text-5xl uppercase font-black tracking-widest" x-show="active == 1"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12">
It is a long established fact that a reader will be distracted
by the readable content of a page when looking at its layout.
<button class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
" x-show="active == 1">
LEARN MORE
</button>
</h1>
<h1 class="absolute text-5xl uppercase font-black tracking-widest" x-show="active == 2"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12">
There are many variations of passages of Lorem Ipsum available
<button class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
" x-show="active == 2">
LEARN MORE
</button>
</h1>
<h1 class="absolute text-5xl uppercase font-black tracking-widest" x-show="active == 3"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12">
but the majority have suffered alteration in some form
<button class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
" x-show="active == 3">
LEARN MORE
</button>
</h1>
</div>
<div class="carousel col-start-1 row-start-1" x-ref="carousel">
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1581375221876-8f287f7cd2cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=770&q=80"
loading="lazy" />
</div>
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1581375279144-bb3b381c7046?ixlib=rb-1.2.1&auto=format&fit=crop&w=770&q=80"
loading="lazy" />
</div>
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1581375303816-4a17124934f7?ixlib=rb-1.2.1&auto=format&fit=crop&w=770&q=80"
loading="lazy" />
</div>
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1494253109108-2e30c049369b?ixlib=rb-1.2.1&auto=format&fit=crop&w=770&q=80"
loading="lazy" />
</div>
</div>
</div>
</div>
</div>
<div
class="row-start-2 col-start-1"
x-show="active == 1"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform scale-90"
x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-300"
x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 transform scale-90"
></div>
</main>
</body>
</html>
PS:出于某种原因,.custom-flickity-button:focus
仍在代码段中显示蓝色 box-shadow。它没有正常显示,所以你可能想看看那个。
编辑 2:
嘿!刚刚对 pointer-events 属性 进行了一些阅读,结果发现如果将 pointer-events: none
设置为一个元素,但将 pointer-events: auto
的值赋予其任何 children, parent 元素不会阻止指针事件在 children.
上触发
基本上这意味着我在编辑 1 中所做的一切都是不必要的。您需要做的就是在我原来的答案中的按钮上添加一行 CSS -> pointer-events: auto
,您将同时拥有可用的按钮和可拖动的旋转木马!
这个不错!它解决了您的问题,您和我今天都学到了新东西! :P
我已经在我的原始代码段中进行了此更改,因此您可以在那里查看。至于编辑 1,我暂时保留它。其他时间可能会帮助别人,谁知道呢。
我一直在玩这个 Carousel created by Tom Smedley。他使用 AlpineJS 和 TailwindCSS。这真是一个华丽的设计。
我有re-edited上面链接的代码笔来解决我的问题。
Here is my version of the sandbox which replicates the problem
我为每个轮播幻灯片添加了一个 LEARN MORE
按钮,但是该按钮隐藏在 <h1>
内容 header 后面。为了测试,我在按钮上添加了悬停效果来改变颜色,但是按钮不能悬停。
- 如何将按钮固定在
<h1>
文本的前面并使其自身位于<h1>
header 的左下方?我可以通过设置按钮边距来解决这个问题,但由于每张幻灯片上文本长度的性质,这不是一个好的解决方案。
这是我的目标截图:
我不关心按钮是否在幻灯片之外(由于 h1 文本长度),我只希望它位于 header 文本的左下方。
我尝试了很多使用 flex、grids 等的尝试...但我一直在挣扎。谢谢你的帮助。
将所有 <button>
标签放在 <h1>
标签内,并插入以下 CSS:
h1 > button {
position: absolute !important;
left: 0;
top: 100%;
font-size: 1rem !important;
}
我还包含了一个片段。 运行 全屏模式:
function carousel() {
return {
active: 0,
init() {
var flkty = new Flickity(this.$refs.carousel, {
wrapAround: true,
});
flkty.on("change", (i) => (this.active = i));
},
};
}
function carouselFilter() {
return {
active: 0,
changeActive(i) {
this.active = i;
this.$nextTick(() => {
let flkty = Flickity.data(
this.$el.querySelectorAll(".carousel")[i]
);
flkty.resize();
console.log(flkty);
});
},
};
}
.flickity-viewport {
height: 500px !important;
}
h1 > button {
position: absolute !important;
left: 0;
top: 100%;
font-size: 1rem !important;
pointer-events: auto; /* This is part of EDIT 2 */
}
<html>
<head></head>
<script src="https://unpkg.com/flickity@2/dist/flickity.pkgd.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/flickity@2/dist/flickity.min.css">
<link rel="stylesheet" href="https://unpkg.com/tailwindcss@1.2.0/dist/tailwind.min.css">
<body>
<main
class="min-h-screen bg-black text-white flex items-center justify-center"
x-data="carouselFilter()"
>
<div class="container grid grid-cols-1">
<div class="flex py-12 justify-center">
<a
class="
px-2
text-lg
uppercase
font-bold
tracking-widest
hover:text-white
"
:class="{ 'text-gray-800': active != 0 }"
href="#"
@click.prevent="changeActive(0)"
>Lorem Ipsum</a
>
</div>
<div
class="row-start-2 col-start-1"
x-show="active == 0"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform scale-90"
x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-300"
x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 transform scale-90"
>
<div
class="grid grid-cols-1 grid-rows-1"
x-data="carousel()"
x-init="init()"
>
<div
class="
col-start-1
row-start-1
relative
z-20
flex
items-center
justify-center
pointer-events-none
"
>
<h1
class="absolute text-5xl uppercase font-black tracking-widest"
x-show="active == 0"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12"
>
Lorem Ipsum is simply dummy text of the printing and typesetting
industry. Lorem Ipsum has been the industry's standard dummy
text ever since the 1500s
<button
class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
"
x-show="active == 0"
>
LEARN MORE
</button>
</h1>
<h1
class="absolute text-5xl uppercase font-black tracking-widest"
x-show="active == 1"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12"
>
It is a long established fact that a reader will be distracted
by the readable content of a page when looking at its layout.
<button
class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
"
x-show="active == 1"
>
LEARN MORE
</button>
</h1>
<h1
class="absolute text-5xl uppercase font-black tracking-widest"
x-show="active == 2"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12"
>
There are many variations of passages of Lorem Ipsum available
<button
class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
"
x-show="active == 2"
>
LEARN MORE
</button>
</h1>
<h1
class="absolute text-5xl uppercase font-black tracking-widest"
x-show="active == 3"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12"
>
but the majority have suffered alteration in some form
<button
class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
"
x-show="active == 3"
>
LEARN MORE
</button>
</h1>
</div>
<div class="carousel col-start-1 row-start-1" x-ref="carousel">
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1581375221876-8f287f7cd2cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=770&q=80"
loading="lazy"
/>
</div>
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1581375279144-bb3b381c7046?ixlib=rb-1.2.1&auto=format&fit=crop&w=770&q=80"
loading="lazy"
/>
</div>
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1581375303816-4a17124934f7?ixlib=rb-1.2.1&auto=format&fit=crop&w=770&q=80"
loading="lazy"
/>
</div>
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1494253109108-2e30c049369b?ixlib=rb-1.2.1&auto=format&fit=crop&w=770&q=80"
loading="lazy"
/>
</div>
</div>
</div>
</div>
<div
class="row-start-2 col-start-1"
x-show="active == 1"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform scale-90"
x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-300"
x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 transform scale-90"
></div>
</div>
</main>
</body>
</html>
您无法对按钮应用悬停效果的原因是 pointer-events
属性 已设置为 none
,在 div 包含 <h1>
和 <button>
标签。这是因为如果不这样设置,则应用于背景的拖动功能将不起作用。因此,它是能够单击按钮并突出显示标题文本,还是能够拖动和滚动背景之间的选择。
如果删除 pointer-events-none class,您会注意到悬停效果在按钮上起作用。
编辑:
好的,所以我们进入第 2 部分。基本上我们需要做的是将按钮提升到 headers 所在的级别。当此页面在 [=100= 中呈现时],您可以使用 DevTools 检查元素。我从 DOM 复制了按钮元素,并将它们放在与所有 <h1>
标签相同的容器中。所以现在你有 2 组按钮。这是一组的样子:
<button class="flickity-button flickity-prev-next-button previous custom-flickity-button" type="button" aria-label="Previous" onclick="slide('previous')">
<svg class="flickity-button-icon" viewBox="0 0 100 100">
<path d="M 10,50 L 60,100 L 70,90 L 30,50 L 70,10 L 60,0 Z" class="arrow"></path>
</svg>
</button>
<button class="flickity-button flickity-prev-next-button custom-flickity-button next" type="button" aria-label="Next" onclick="slide('next')">
<svg class="flickity-button-icon" viewBox="0 0 100 100">
<path d="M 10,50 L 60,100 L 70,90 L 30,50 L 70,10 L 60,0 Z" class="arrow" transform="translate(100, 100) rotate(180) "></path>
</svg>
</button>
稍微浏览一下 Flickity 文档,您会发现按钮是 optional,用于渲染。同样,因为我们不会直接与 Flickity 实例交互,所以我在初始化时禁用了拖动功能。这看起来像这样:
function carousel() {
return {
active: 0,
init() {
var flkty = new Flickity(this.$refs.carousel, {
wrapAround: true,
draggable: false, // This is new
prevNextButtons: false // This is new
});
flkty.on("change", (i) => (this.active = i));
}
};
}
由于我们添加的新按钮基本上都是 Flickity 使用的按钮,因此我们真的不需要太担心样式问题。只需要稍作修改。为了减少意外修改实际 CSS 的机会,我添加了 class custom-flickity-button
.
附加样式:
.custom-flickity-button {
/* 21 is the threshold. Below this, it will be under the h1 text */
z-index: 25;
}
.custom-flickity-button:focus {
outline: none;
box-shadow: none;
}
/*
If you make h1 relative, then this padding will apply.
But that was causing some issues while transitioning.
I'm leaving this for you to explore.
*/
#text-container {
padding: 0 70px;
}
最后,我们需要为新按钮提供一些点击功能:
// This is to make the new buttons slide. You can modify the logic to work with multiple carousels, as you've done above
function slide(value) {
let flkty = Flickity.data(document.querySelector('.carousel'))
if (value == 'next') {
flkty.next()
} else if (value == 'previous') {
flkty.previous()
}
}
我不太熟悉使用 Alpine 和 Tailwind,因此您可以修改此代码以适应它。但无论如何,这就是你所要求的。带有交互式滑块按钮的交互式 了解更多 按钮。
function carousel() {
return {
active: 0,
init() {
var flkty = new Flickity(this.$refs.carousel, {
wrapAround: true,
});
flkty.on("change", (i) => (this.active = i));
},
};
}
function carouselFilter() {
return {
active: 0,
changeActive(i) {
this.active = i;
this.$nextTick(() => {
let flkty = Flickity.data(
this.$el.querySelectorAll(".carousel")[i]
);
flkty.resize();
console.log(flkty);
});
},
};
}
// This is to make the new buttons slide. You can modify the logic to work with multiple carousels, as you've done above
function slide(value) {
let flkty = Flickity.data(document.querySelector('.carousel'))
if (value == 'next') {
flkty.next()
} else if (value == 'previous') {
flkty.previous()
}
}
.flickity-viewport {
height: 500px !important;
}
h1 > button {
position: absolute !important;
left: 0;
top: 100%;
font-size: 1rem !important;
}
.custom-flickity-button {
/* 21 is the threshold. Below this, it will be under the h1 text */
z-index: 1
}
.custom-flickity-button:focus {
outline: none;
box-shadow: none;
border: none;
}
/*
If you make h1 relative, then this padding will apply.
But that was causing some issues while transitioning.
I'm leaving this for you to explore.
*/
#text-container {
padding: 0 70px;
}
<html>
<head></head>
<script src="https://unpkg.com/flickity@2/dist/flickity.pkgd.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/flickity@2/dist/flickity.min.css">
<link rel="stylesheet" href="https://unpkg.com/tailwindcss@1.2.0/dist/tailwind.min.css">
<body>
<main class="min-h-screen bg-black text-white flex items-center justify-center" x-data="carouselFilter()">
<div class="container grid grid-cols-1">
<div class="flex py-12 justify-center">
<a class="
px-2
text-lg
uppercase
font-bold
tracking-widest
hover:text-white
" :class="{ 'text-gray-800': active != 0 }" href="#" @click.prevent="changeActive(0)">Lorem Ipsum</a>
</div>
<div class="row-start-2 col-start-1" x-show="active == 0" x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform scale-90" x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-300" x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 transform scale-90">
<div class="grid grid-cols-1 grid-rows-1" x-data="carousel()" x-init="init()">
<div class="
col-start-1
row-start-1
relative
z-20
flex
items-center
justify-center
" id="text-container">
<button class="flickity-button flickity-prev-next-button previous custom-flickity-button" type="button"
aria-label="Previous" onclick="slide('previous')"><svg class="flickity-button-icon" viewBox="0 0 100 100">
<path d="M 10,50 L 60,100 L 70,90 L 30,50 L 70,10 L 60,0 Z" class="arrow"></path>
</svg></button>
<button class="flickity-button flickity-prev-next-button custom-flickity-button next" type="button"
aria-label="Next" onclick="slide('next')"><svg class="flickity-button-icon" viewBox="0 0 100 100">
<path d="M 10,50 L 60,100 L 70,90 L 30,50 L 70,10 L 60,0 Z" class="arrow"
transform="translate(100, 100) rotate(180) "></path>
</svg></button>
<h1 class="absolute text-5xl uppercase font-black tracking-widest" x-show="active == 0"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12">
Lorem Ipsum is simply dummy text of the printing and typesetting
industry. Lorem Ipsum has been the industry's standard dummy
text ever since the 1500s
<button class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
" x-show="active == 0">
LEARN MORE
</button>
</h1>
<h1 class="absolute text-5xl uppercase font-black tracking-widest" x-show="active == 1"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12">
It is a long established fact that a reader will be distracted
by the readable content of a page when looking at its layout.
<button class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
" x-show="active == 1">
LEARN MORE
</button>
</h1>
<h1 class="absolute text-5xl uppercase font-black tracking-widest" x-show="active == 2"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12">
There are many variations of passages of Lorem Ipsum available
<button class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
" x-show="active == 2">
LEARN MORE
</button>
</h1>
<h1 class="absolute text-5xl uppercase font-black tracking-widest" x-show="active == 3"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-12"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-out duration-300"
x-transition:leave-start="opacity-100 transform translate-y-0"
x-transition:leave-end="opacity-0 transform -translate-y-12">
but the majority have suffered alteration in some form
<button class="
border border-white
text-white
rounded-md
px-4
py-2
m-2
transition
duration-500
ease
select-none
hover:text-white hover:bg-indigo-600
focus:outline-none focus:shadow-outline
" x-show="active == 3">
LEARN MORE
</button>
</h1>
</div>
<div class="carousel col-start-1 row-start-1" x-ref="carousel">
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1581375221876-8f287f7cd2cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=770&q=80"
loading="lazy" />
</div>
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1581375279144-bb3b381c7046?ixlib=rb-1.2.1&auto=format&fit=crop&w=770&q=80"
loading="lazy" />
</div>
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1581375303816-4a17124934f7?ixlib=rb-1.2.1&auto=format&fit=crop&w=770&q=80"
loading="lazy" />
</div>
<div class="w-3/5 px-2">
<img
src="https://images.unsplash.com/photo-1494253109108-2e30c049369b?ixlib=rb-1.2.1&auto=format&fit=crop&w=770&q=80"
loading="lazy" />
</div>
</div>
</div>
</div>
</div>
<div
class="row-start-2 col-start-1"
x-show="active == 1"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform scale-90"
x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-300"
x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 transform scale-90"
></div>
</main>
</body>
</html>
PS:出于某种原因,.custom-flickity-button:focus
仍在代码段中显示蓝色 box-shadow。它没有正常显示,所以你可能想看看那个。
编辑 2:
嘿!刚刚对 pointer-events 属性 进行了一些阅读,结果发现如果将 pointer-events: none
设置为一个元素,但将 pointer-events: auto
的值赋予其任何 children, parent 元素不会阻止指针事件在 children.
基本上这意味着我在编辑 1 中所做的一切都是不必要的。您需要做的就是在我原来的答案中的按钮上添加一行 CSS -> pointer-events: auto
,您将同时拥有可用的按钮和可拖动的旋转木马!
这个不错!它解决了您的问题,您和我今天都学到了新东西! :P
我已经在我的原始代码段中进行了此更改,因此您可以在那里查看。至于编辑 1,我暂时保留它。其他时间可能会帮助别人,谁知道呢。