目前,我只想将 Tailwind CSS 和 React 应用于“第一印象”部分。这是我最近添加的 div 块(通过 ChatGPT 的帮助),当我加载页面时,我注意到 Bootstrap CSS 样式被 Tailwind 覆盖。删除 Tailwind CDN 链接允许页面的其余部分按预期设计样式,尽管代价是新添加的 div 块渲染不正确。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MapPalette - Login</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.23.5/babel.min.js"></script>
<!-- Tailwind CSS -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
<style>
.navbar {
position: sticky;
top: 0;
z-index: 3;
}
.navbar-brand {
/*controls brand name size in navbar*/
font-size: 1.5rem;
}
.nav-link {
/*controls font size and margin of nav links*/
font-size: 1.2rem;
margin-left: 20px;
}
.navbar-brand img {
/*brand logo sizing*/
width: 50px;
height: 50px;
margin-right: 8px;
}
.app-name {
font-size: 2.5rem;
color: #007bff;
}
/* Full-width hero section */
.hero {
background: url('../resources/index/run-background.jpeg') no-repeat center center/cover;
height: 80vh;
position: relative;
}
.hero-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
color: white;
}
.hero h1 {
font-size: 4rem;
margin-bottom: 1rem;
}
.btn-primary {
margin-right: 10px;
}
/* Key Features section */
.key-features {
display: flex;
justify-content: space-between;
margin: 2rem 0;
text-align: center;
}
.features-image {
width: 50px;
height: 50px;
margin-bottom: 1rem;
}
/* Video container */
.video-container {
text-align: center;
}
/* About us */
.about-us {
padding: 3rem 0;
}
.about-us-description {
font-style: italic;
font-weight: lighter;
}
/* First Impressions section */
.first-impressions .card {
border: none;
background-color: #f8f9fa;
}
/* Fade-in scroll effect */
.fade-in {
opacity: 0;
transform: translateY(50px);
transition: opacity 0.8s ease-out, transform 1s ease-out;
}
.fade-in.show {
opacity: 1;
transform: translateY(0);
}
/* Sequential rendering for Key Features */
.col-sm-4 {
opacity: 0;
transform: translateY(50px);
transition: opacity 0.8s ease-out, transform 2s ease-out;
}
/* Additional hover feature */
.col-sm-4:hover {
background-color: #f1f1f1;
transform: scale(1.05);
}
/* Carousel modifications */
.carousel-container {
position: relative;
max-width: 35%;
margin: auto;
overflow: hidden;
}
.carousel-slide {
display: flex;
transition: transform 0.5s ease-in-out;
}
.carousel-item {
min-width: 100%;
text-align: center;
opacity: 1;
visibility: visible;
}
.person-image {
width: 100%;
height: auto;
object-fit: contain;
}
.person-name {
font-size: 1.5em;
margin: 10px 0;
}
.person-description {
font-size: 1em;
color: #666;
font-style: italic;
}
.carousel-control-prev, .carousel-control-next {
top: 40%;
transform: translateY(-50%);
z-index: 2;
}
.prev, .next {
cursor: pointer;
position: absolute;
font-size: 2em;
color: #333;
background-color: transparent;
border: none;
padding: 0 10px;
}
.prev {
left: 10px;
}
.next {
right: 10px;
}
.scrollbar-hide::-webkit-scrollbar {
display: none;
}
/* Hide scrollbar for IE, Edge and Firefox */
.scrollbar-hide {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light px-3">
<div class="container-fluid">
<a class="navbar-brand" href="#"><img src="../resources/index/mappalettelogo.png"><span style="color: #007bff;">MapPalette</span></a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a href="login.html" class="nav-link btn btn-outline-primary">Login</a>
</li>
<li class="nav-item">
<a href="signup.html" class="nav-link btn btn-primary">Sign Up</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Hero Section -->
<section class="hero">
<div class="hero-content">
<h1>Explore the World with MapPalette</h1>
<p>Creative routes for every adventure</p>
<a href="signup.html" class="btn btn-primary">Get Started</a>
<a href="login.html" class="btn btn-outline-light">Login</a>
</div>
</section>
<!-- First Impressions Section -->
<section class="first-impressions fade-in">
<div id="root">
<!-- Your React component -->
<script type="text/babel">
// Copy the entire GalleryComponent code here
const GalleryComponent = () => {
const [activeIndex, setActiveIndex] = React.useState(null);
const [scrollPosition, setScrollPosition] = React.useState(0);
const scrollContainerRef = React.useRef(null);
const images = [
"../resources/index/about_us/placeholder.jpg",
"../resources/index/about_us/placeholder.jpg",
"../resources/index/about_us/placeholder.jpg",
"../resources/index/about_us/placeholder.jpg",
"../resources/index/about_us/placeholder.jpg",
"../resources/index/about_us/placeholder.jpg",
"../resources/index/about_us/placeholder.jpg",
"../resources/index/about_us/placeholder.jpg",
];
const handleScroll = (e) => {
if (scrollContainerRef.current) {
const container = scrollContainerRef.current;
const scrollPos = container.scrollLeft;
setScrollPosition(scrollPos);
const itemWidth = container.offsetWidth / 3;
const newActiveIndex = Math.round(scrollPos / itemWidth);
setActiveIndex(newActiveIndex);
}
};
const getItemScale = (index) => {
if (activeIndex === null) return 0.6;
const distance = Math.abs(index - activeIndex);
switch (distance) {
case 0:
return 1;
case 1:
return 0.85;
case 2:
return 0.75;
case 3:
return 0.65;
default:
return 0.6;
}
};
const getVerticalOffset = (index) => {
const scale = getItemScale(index);
return (1 - scale) * 20;
};
return (
<div className="w-full h-screen bg-white relative overflow-hidden">
<div
ref={scrollContainerRef}
className="flex overflow-x-auto h-full items-center snap-x snap-mandatory scrollbar-hide px-12"
onScroll={handleScroll}
style={{
scrollBehavior: 'smooth',
WebkitOverflowScrolling: 'touch'
}}
>
<div className="flex-shrink-0 w-[20vw]" />
{images.map((src, index) => (
<div
key={index}
className="snap-start flex-shrink-0 h-full flex items-center justify-center transition-all duration-500 ease-in-out px-2"
style={{
width: 'auto',
opacity: getItemScale(index) * 0.8 + 0.2,
}}
>
<div
className="relative overflow-hidden group transition-all duration-500"
onMouseEnter={() => setActiveIndex(index)}
style={{
height: `${getItemScale(index) * 70}vh`,
transform: `translateY(${getVerticalOffset(index)}%)`,
transformOrigin: 'center center'
}}
>
<img
src={src}
alt={`Gallery image ${index + 1}`}
className="h-full w-auto object-cover transition-transform duration-500 group-hover:scale-105"
style={{
maxWidth: 'none'
}}
/>
</div>
</div>
))}
<div className="flex-shrink-0 w-[20vw]" />
</div>
<div className="absolute bottom-8 left-1/2 transform -translate-x-1/2">
<div className="flex space-x-0.5">
{images.map((_, index) => (
<div
key={index}
className={`h-px transition-all duration-300 ${
activeIndex === index ? 'bg-black w-8' : 'bg-gray-300 w-4'
}`}
/>
))}
</div>
</div>
</div>
);
};
// Render the component
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<GalleryComponent />);
</script>
</div>
</section>
<!-- Key Features Section -->
<section class="container py-5 text-center">
<div class="mb-5 fade-in">
<h2>Why Choose MapPalette?</h2>
</div>
<div class="row mt-4 fade-in">
<div class="col-sm-4">
<img class="features-image" src="../resources/index/features/maps.png" alt="">
<h4>Creative Route Drawing</h4>
<p>Design and follow fun, custom running routes on the map.</p>
</div>
<div class="col-sm-4">
<img class="features-image" src="../resources/index/features/share.png" alt="">
<h4>Share Your Routes</h4>
<p>Easily share your routes with friends or on social media.</p>
</div>
<div class="col-sm-4">
<img class="features-image" src="../resources/index/features/integration.png" alt="">
<h4>Seamless Integration</h4>
<p>Connect with fitness apps like Strava to track your runs.</p>
</div>
</div>
</section>
</body>
</html>
不要使用CDN版本。相反,像平常一样导入 Tailwind / Bootstrap 库,但将它们限制在您自己的类中以防止它们“泄漏”。
在你的主 .css 文件中;
.tw-only {
@tailwind base;
@tailwind components;
@tailwind utilities;
}
在你的html中:
<div class="tw-only">Tailwind styles are only applied within this element</div>