Banner Components

Hero banners, announcement bars, and promo banners built with TailwindCSS. Perfect for landing pages, notifications, and marketing. Copy, paste, and customize for React, Vue, or HTML.

1. Simple Announcement Banner

A clean announcement bar for promotions, updates, or alerts with dismiss functionality.

🚀 New: Get 50% off all premium templates!
<div x-data="{ show: true }" x-show="show" class="bg-violet text-white px-6 py-3 rounded-lg flex items-center justify-between shadow">
  <div class="flex items-center">
    <svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
    </svg>
    <span class="font-bold">🚀 New: Get 50% off all premium templates!</span>
  </div>
  <div class="flex items-center">
    <a href="#" class="underline font-semibold hover:text-yellow-300 ml-4 mr-4">Shop Now</a>
    <button @click="show = false" class="text-white/80 hover:text-white">
      <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
      </svg>
    </button>
  </div>
</div>
<template>
  <div v-show="visible" class="bg-violet text-white px-6 py-3 rounded-lg flex items-center justify-between shadow">
    <div class="flex items-center">
      <svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
      </svg>
      <span class="font-bold">{{ message }}</span>
    </div>
    <div class="flex items-center">
      <a :href="actionUrl" class="underline font-semibold hover:text-yellow-300 ml-4 mr-4">{{ actionText }}</a>
      <button @click="dismiss" class="text-white/80 hover:text-white">
        <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
        </svg>
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const props = defineProps({
  message: {
    type: String,
    default: '🚀 New: Get 50% off all premium templates!'
  },
  actionText: {
    type: String,
    default: 'Shop Now'
  },
  actionUrl: {
    type: String,
    default: '#'
  }
})

const emit = defineEmits(['dismiss'])
const visible = ref(true)

const dismiss = () => {
  visible.value = false
  emit('dismiss')
}
</script>
import React, { useState } from 'react'

const AnnouncementBanner = ({ 
  message = '🚀 New: Get 50% off all premium templates!',
  actionText = 'Shop Now',
  actionUrl = '#',
  onDismiss 
}) => {
  const [visible, setVisible] = useState(true)

  const handleDismiss = () => {
    setVisible(false)
    if (onDismiss) onDismiss()
  }

  if (!visible) return null

  return (
    <div className="bg-violet text-white px-6 py-3 rounded-lg flex items-center justify-between shadow">
      <div className="flex items-center">
        <svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
        </svg>
        <span className="font-bold">{message}</span>
      </div>
      <div className="flex items-center">
        <a href={actionUrl} className="underline font-semibold hover:text-yellow-300 ml-4 mr-4">
          {actionText}
        </a>
        <button onClick={handleDismiss} className="text-white/80 hover:text-white">
          <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12"></path>
          </svg>
        </button>
      </div>
    </div>
  )
}

export default AnnouncementBanner

2. Gradient Hero Banner

A stunning hero banner with gradient background, animated elements, and call-to-action buttons.

New Features Available

Build Amazing Websites

Create stunning, responsive web experiences with our collection of beautiful TailwindCSS components. No design skills required.

500+
Components
50k+
Happy Users
100%
Open Source
<div class="relative overflow-hidden bg-gradient-to-br from-indigo-600 via-purple-600 to-pink-500 rounded-2xl">
  <!-- Animated Background Elements -->
  <div class="absolute inset-0">
    <div class="absolute top-20 left-20 w-32 h-32 bg-white/10 rounded-full blur-xl animate-pulse"></div>
    <div class="absolute bottom-20 right-20 w-40 h-40 bg-white/5 rounded-full blur-2xl animate-pulse delay-700"></div>
    <div class="absolute top-1/2 left-1/3 w-24 h-24 bg-white/10 rounded-full blur-lg animate-pulse delay-1000"></div>
  </div>

  <!-- Content -->
  <div class="relative px-8 py-16 lg:px-16 lg:py-24">
    <div class="max-w-4xl mx-auto text-center">
      <!-- Badge -->
      <div class="inline-flex items-center gap-2 px-4 py-2 bg-white/20 backdrop-blur-sm rounded-full text-white text-sm font-medium mb-8">
        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
        </svg>
        New Features Available
      </div>

      <!-- Main Heading -->
      <h1 class="text-4xl md:text-6xl lg:text-7xl font-bold text-white mb-6 leading-tight">
        Build Amazing
        <span class="bg-gradient-to-r from-yellow-300 to-orange-400 bg-clip-text text-transparent">
          Websites
        </span>
      </h1>

      <!-- Subtitle -->
      <p class="text-xl md:text-2xl text-white/90 mb-8 max-w-3xl mx-auto leading-relaxed">
        Create stunning, responsive web experiences with our collection of beautiful TailwindCSS components.
      </p>

      <!-- CTA Buttons -->
      <div class="flex flex-col sm:flex-row gap-4 justify-center items-center mb-16">
        <button class="group relative px-8 py-4 bg-white text-indigo-600 rounded-full font-semibold text-lg shadow-xl hover:shadow-2xl transform hover:-translate-y-1 transition-all duration-300">
          <span class="relative z-10">Get Started Free</span>
          <div class="absolute inset-0 bg-gradient-to-r from-yellow-400 to-orange-400 rounded-full opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
        </button>
        <button class="group px-8 py-4 border-2 border-white/30 text-white rounded-full font-semibold text-lg backdrop-blur-sm hover:bg-white/10 transition-all duration-300 flex items-center gap-2">
          <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.828 14.828a4 4 0 01-5.656 0M9 10h1m4 0h1M4 7h16l-1.5 9H5.5L4 7z"></path>
          </svg>
          View Demo
        </button>
      </div>

      <!-- Stats -->
      <div class="grid grid-cols-3 gap-8 max-w-2xl mx-auto">
        <div class="text-center">
          <div class="text-3xl md:text-4xl font-bold text-white mb-2">500+</div>
          <div class="text-white/80 text-sm md:text-base">Components</div>
        </div>
        <div class="text-center">
          <div class="text-3xl md:text-4xl font-bold text-white mb-2">50k+</div>
          <div class="text-white/80 text-sm md:text-base">Happy Users</div>
        </div>
        <div class="text-center">
          <div class="text-3xl md:text-4xl font-bold text-white mb-2">100%</div>
          <div class="text-white/80 text-sm md:text-base">Open Source</div>
        </div>
      </div>
    </div>
  </div>

</div>
<template>
  <div class="relative overflow-hidden bg-gradient-to-br from-indigo-600 via-purple-600 to-pink-500 rounded-2xl">
    <!-- Animated Background Elements -->
    <div class="absolute inset-0">
      <div class="absolute top-20 left-20 w-32 h-32 bg-white/10 rounded-full blur-xl animate-pulse"></div>
      <div class="absolute bottom-20 right-20 w-40 h-40 bg-white/5 rounded-full blur-2xl animate-pulse delay-700"></div>
      <div class="absolute top-1/2 left-1/3 w-24 h-24 bg-white/10 rounded-full blur-lg animate-pulse delay-1000"></div>
    </div>

    <div class="relative px-8 py-16 lg:px-16 lg:py-24">
      <div class="max-w-4xl mx-auto text-center">
        <!-- Badge -->
        <div class="inline-flex items-center gap-2 px-4 py-2 bg-white/20 backdrop-blur-sm rounded-full text-white text-sm font-medium mb-8">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
          </svg>
          {{ badge }}
        </div>

        <h1 class="text-4xl md:text-6xl lg:text-7xl font-bold text-white mb-6 leading-tight">
          {{ title }}
          <span class="bg-gradient-to-r from-yellow-300 to-orange-400 bg-clip-text text-transparent">
            {{ highlightText }}
          </span>
        </h1>

        <p class="text-xl md:text-2xl text-white/90 mb-8 max-w-3xl mx-auto leading-relaxed">
          {{ subtitle }}
        </p>

        <div class="flex flex-col sm:flex-row gap-4 justify-center items-center mb-16">
          <button @click="$emit('primaryAction')" class="group relative px-8 py-4 bg-white text-indigo-600 rounded-full font-semibold text-lg shadow-xl hover:shadow-2xl transform hover:-translate-y-1 transition-all duration-300">
            <span class="relative z-10">{{ primaryButtonText }}</span>
            <div class="absolute inset-0 bg-gradient-to-r from-yellow-400 to-orange-400 rounded-full opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
          </button>
          <button @click="$emit('secondaryAction')" class="group px-8 py-4 border-2 border-white/30 text-white rounded-full font-semibold text-lg backdrop-blur-sm hover:bg-white/10 transition-all duration-300 flex items-center gap-2">
            <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.828 14.828a4 4 0 01-5.656 0M9 10h1m4 0h1M4 7h16l-1.5 9H5.5L4 7z"></path>
            </svg>
            {{ secondaryButtonText }}
          </button>
        </div>

        <div class="grid grid-cols-3 gap-8 max-w-2xl mx-auto">
          <div v-for="stat in stats" :key="stat.label" class="text-center">
            <div class="text-3xl md:text-4xl font-bold text-white mb-2">{{ stat.value }}</div>
            <div class="text-white/80 text-sm md:text-base">{{ stat.label }}</div>
          </div>
        </div>
      </div>
    </div>

    <div class="absolute -bottom-1 left-0 right-0">
      <svg viewBox="0 0 1200 120" fill="none" class="w-full h-20">
        <path d="M0 120V40C200 10 400 0 600 20C800 40 1000 60 1200 40V120H0Z" fill="white"/>
      </svg>
    </div>
  </div>
</template>

<script setup>
const props = defineProps({
  badge: {
    type: String,
    default: 'New Features Available'
  },
  title: {
    type: String,
    default: 'Build Amazing'
  },
  highlightText: {
    type: String,
    default: 'Websites'
  },
  subtitle: {
    type: String,
    default: 'Create stunning, responsive web experiences with our collection of beautiful TailwindCSS components.'
  },
  primaryButtonText: {
    type: String,
    default: 'Get Started Free'
  },
  secondaryButtonText: {
    type: String,
    default: 'View Demo'
  },
  stats: {
    type: Array,
    default: () => [
      { value: '500+', label: 'Components' },
      { value: '50k+', label: 'Happy Users' },
      { value: '100%', label: 'Open Source' }
    ]
  }
})

defineEmits(['primaryAction', 'secondaryAction'])
</script>
import React from 'react'

const GradientHeroBanner = ({
  badge = 'New Features Available',
  title = 'Build Amazing',
  highlightText = 'Websites',
  subtitle = 'Create stunning, responsive web experiences with our collection of beautiful TailwindCSS components.',
  primaryButtonText = 'Get Started Free',
  secondaryButtonText = 'View Demo',
  stats = [
    { value: '500+', label: 'Components' },
    { value: '50k+', label: 'Happy Users' },
    { value: '100%', label: 'Open Source' }
  ],
  onPrimaryAction,
  onSecondaryAction
}) => {
  return (
    <div className="relative overflow-hidden bg-gradient-to-br from-indigo-600 via-purple-600 to-pink-500 rounded-2xl">
      {/* Animated Background Elements */}
      <div className="absolute inset-0">
        <div className="absolute top-20 left-20 w-32 h-32 bg-white/10 rounded-full blur-xl animate-pulse"></div>
        <div className="absolute bottom-20 right-20 w-40 h-40 bg-white/5 rounded-full blur-2xl animate-pulse delay-700"></div>
        <div className="absolute top-1/2 left-1/3 w-24 h-24 bg-white/10 rounded-full blur-lg animate-pulse delay-1000"></div>
      </div>

      {/* Content */}
      <div className="relative px-8 py-16 lg:px-16 lg:py-24">
        <div className="max-w-4xl mx-auto text-center">
          {/* Badge */}
          <div className="inline-flex items-center gap-2 px-4 py-2 bg-white/20 backdrop-blur-sm rounded-full text-white text-sm font-medium mb-8">
            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
            </svg>
            {badge}
          </div>

          {/* Main Heading */}
          <h1 className="text-4xl md:text-6xl lg:text-7xl font-bold text-white mb-6 leading-tight">
            {title}
            <span className="bg-gradient-to-r from-yellow-300 to-orange-400 bg-clip-text text-transparent">
              {' '}{highlightText}
            </span>
          </h1>

          {/* Subtitle */}
          <p className="text-xl md:text-2xl text-white/90 mb-8 max-w-3xl mx-auto leading-relaxed">
            {subtitle}
          </p>

          {/* CTA Buttons */}
          <div className="flex flex-col sm:flex-row gap-4 justify-center items-center mb-16">
            <button 
              onClick={onPrimaryAction}
              className="group relative px-8 py-4 bg-white text-indigo-600 rounded-full font-semibold text-lg shadow-xl hover:shadow-2xl transform hover:-translate-y-1 transition-all duration-300"
            >
              <span className="relative z-10">{primaryButtonText}</span>
              <div className="absolute inset-0 bg-gradient-to-r from-yellow-400 to-orange-400 rounded-full opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
            </button>
            <button 
              onClick={onSecondaryAction}
              className="group px-8 py-4 border-2 border-white/30 text-white rounded-full font-semibold text-lg backdrop-blur-sm hover:bg-white/10 transition-all duration-300 flex items-center gap-2"
            >
              <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M14.828 14.828a4 4 0 01-5.656 0M9 10h1m4 0h1M4 7h16l-1.5 9H5.5L4 7z" />
              </svg>
              {secondaryButtonText}
            </button>
          </div>

          {/* Stats */}
          <div className="grid grid-cols-3 gap-8 max-w-2xl mx-auto">
            {stats.map((stat, index) => (
              <div key={index} className="text-center">
                <div className="text-3xl md:text-4xl font-bold text-white mb-2">{stat.value}</div>
                <div className="text-white/80 text-sm md:text-base">{stat.label}</div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  )
}

export default GradientHeroBanner

3. Minimal Notification Banner

Clean and simple notification banner with icon and action button - perfect for important updates.

New version 2.0 is now available with improved performance!
<div class="bg-blue-50 border-l-4 border-blue-400 p-4 rounded-r-lg">
  <div class="flex items-center justify-between">
    <div class="flex items-center">
      <svg class="w-5 h-5 text-blue-400 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
      </svg>
      <span class="text-blue-800 font-medium">New version 2.0 is now available with improved performance!</span>
    </div>
    <button class="text-blue-600 hover:text-blue-800 font-semibold text-sm ml-4 whitespace-nowrap">Update Now</button>
  </div>
</div>
<template>
  <div :class="bannerClasses">
    <div class="flex items-center justify-between">
      <div class="flex items-center">
        <svg class="w-5 h-5 mr-3" :class="iconColor" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
        </svg>
        <span :class="textColor">{{ message }}</span>
      </div>
      <button @click="$emit('action')" :class="buttonColor">{{ actionText }}</button>
    </div>
  </div>
</template>

<script setup>
import { computed } from 'vue'

const props = defineProps({
  message: {
    type: String,
    default: 'New version 2.0 is now available with improved performance!'
  },
  actionText: {
    type: String,
    default: 'Update Now'
  },
  variant: {
    type: String,
    default: 'info',
    validator: (value) => ['info', 'success', 'warning', 'error'].includes(value)
  }
})

const bannerClasses = computed(() => {
  const variants = {
    info: 'bg-blue-50 border-l-4 border-blue-400',
    success: 'bg-green-50 border-l-4 border-green-400',
    warning: 'bg-yellow-50 border-l-4 border-yellow-400',
    error: 'bg-red-50 border-l-4 border-red-400'
  }
  return `${variants[props.variant]} p-4 rounded-r-lg`
})

const iconColor = computed(() => {
  const colors = {
    info: 'text-blue-400',
    success: 'text-green-400',
    warning: 'text-yellow-400',
    error: 'text-red-400'
  }
  return colors[props.variant]
})

const textColor = computed(() => {
  const colors = {
    info: 'text-blue-800 font-medium',
    success: 'text-green-800 font-medium',
    warning: 'text-yellow-800 font-medium',
    error: 'text-red-800 font-medium'
  }
  return colors[props.variant]
})

const buttonColor = computed(() => {
  const colors = {
    info: 'text-blue-600 hover:text-blue-800',
    success: 'text-green-600 hover:text-green-800',
    warning: 'text-yellow-600 hover:text-yellow-800',
    error: 'text-red-600 hover:text-red-800'
  }
  return `${colors[props.variant]} font-semibold text-sm ml-4 whitespace-nowrap`
})

defineEmits(['action'])
</script>
import React from 'react'

const MinimalNotificationBanner = ({
  message = 'New version 2.0 is now available with improved performance!',
  actionText = 'Update Now',
  variant = 'info',
  onAction
}) => {
  const getVariantClasses = () => {
    const variants = {
      info: {
        container: 'bg-blue-50 border-l-4 border-blue-400',
        icon: 'text-blue-400',
        text: 'text-blue-800 font-medium',
        button: 'text-blue-600 hover:text-blue-800'
      },
      success: {
        container: 'bg-green-50 border-l-4 border-green-400',
        icon: 'text-green-400',
        text: 'text-green-800 font-medium',
        button: 'text-green-600 hover:text-green-800'
      },
      warning: {
        container: 'bg-yellow-50 border-l-4 border-yellow-400',
        icon: 'text-yellow-400',
        text: 'text-yellow-800 font-medium',
        button: 'text-yellow-600 hover:text-yellow-800'
      },
      error: {
        container: 'bg-red-50 border-l-4 border-red-400',
        icon: 'text-red-400',
        text: 'text-red-800 font-medium',
        button: 'text-red-600 hover:text-red-800'
      }
    }
    return variants[variant] || variants.info
  }

  const classes = getVariantClasses()

  return (
    <div className={`${classes.container} p-4 rounded-r-lg`}>
      <div className="flex items-center justify-between">
        <div className="flex items-center">
          <svg className={`w-5 h-5 mr-3 ${classes.icon}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
          </svg>
          <span className={classes.text}>{message}</span>
        </div>
        <button
          onClick={onAction}
          className={`${classes.button} font-semibold text-sm ml-4 whitespace-nowrap`}
        >
          {actionText}
        </button>
      </div>
    </div>
  )
}

export default MinimalNotificationBanner

4. Neobrutalist Promo Banner

Bold neobrutalist design with thick borders, vibrant colors, and strong shadows - perfect for promotions.

%

LIMITED TIME OFFER

Save 70% on all premium templates

<div class="relative bg-[#ffde59] border-4 border-black p-6 shadow-[8px_8px_0px_0px_rgba(0,0,0,1)] transform hover:shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] transition-all">
  <div class="absolute -top-3 -right-3 w-8 h-8 bg-[#ff5c5c] border-2 border-black"></div>
  <div class="flex items-center justify-between">
    <div class="flex items-center">
      <div class="w-12 h-12 bg-violet border-2 border-black flex items-center justify-center mr-4">
        <span class="text-white font-black text-xl">%</span>
      </div>
      <div>
        <h3 class="text-xl font-black text-black uppercase tracking-tight">LIMITED TIME OFFER</h3>
        <p class="text-black font-bold text-sm">Save 70% on all premium templates</p>
      </div>
    </div>
    <button class="bg-black text-[#ffde59] font-black px-6 py-3 border-2 border-black shadow-[4px_4px_0px_0px_rgba(0,0,0,0.3)] hover:shadow-[2px_2px_0px_0px_rgba(0,0,0,0.3)] transition-all uppercase tracking-wide">
      CLAIM NOW
    </button>
  </div>
</div>
<template>
  <div class="relative bg-[#ffde59] border-4 border-black p-6 shadow-[8px_8px_0px_0px_rgba(0,0,0,1)] transform hover:shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] transition-all">
    <div class="absolute -top-3 -right-3 w-8 h-8 bg-[#ff5c5c] border-2 border-black"></div>
    <div class="flex items-center justify-between">
      <div class="flex items-center">
        <div class="w-12 h-12 bg-violet border-2 border-black flex items-center justify-center mr-4">
          <span class="text-white font-black text-xl">{{ icon }}</span>
        </div>
        <div>
          <h3 class="text-xl font-black text-black uppercase tracking-tight">{{ title }}</h3>
          <p class="text-black font-bold text-sm">{{ subtitle }}</p>
        </div>
      </div>
      <button 
        @click="$emit('action')"
        class="bg-black text-[#ffde59] font-black px-6 py-3 border-2 border-black shadow-[4px_4px_0px_0px_rgba(0,0,0,0.3)] hover:shadow-[2px_2px_0px_0px_rgba(0,0,0,0.3)] transition-all uppercase tracking-wide"
      >
        {{ buttonText }}
      </button>
    </div>
  </div>
</template>

<script setup>
const props = defineProps({
  icon: {
    type: String,
    default: '%'
  },
  title: {
    type: String,
    default: 'LIMITED TIME OFFER'
  },
  subtitle: {
    type: String,
    default: 'Save 70% on all premium templates'
  },
  buttonText: {
    type: String,
    default: 'CLAIM NOW'
  }
})

defineEmits(['action'])
</script>
import React from 'react'

const NeobrutalistPromoBanner = ({
  icon = '%',
  title = 'LIMITED TIME OFFER',
  subtitle = 'Save 70% on all premium templates',
  buttonText = 'CLAIM NOW',
  onAction
}) => {
  return (
    <div className="relative bg-[#ffde59] border-4 border-black p-6 shadow-[8px_8px_0px_0px_rgba(0,0,0,1)] transform hover:shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] transition-all">
      <div className="absolute -top-3 -right-3 w-8 h-8 bg-[#ff5c5c] border-2 border-black"></div>
      <div className="flex items-center justify-between">
        <div className="flex items-center">
          <div className="w-12 h-12 bg-violet border-2 border-black flex items-center justify-center mr-4">
            <span className="text-white font-black text-xl">{icon}</span>
          </div>
          <div>
            <h3 className="text-xl font-black text-black uppercase tracking-tight">{title}</h3>
            <p className="text-black font-bold text-sm">{subtitle}</p>
          </div>
        </div>
        <button 
          onClick={onAction}
          className="bg-black text-[#ffde59] font-black px-6 py-3 border-2 border-black shadow-[4px_4px_0px_0px_rgba(0,0,0,0.3)] hover:shadow-[2px_2px_0px_0px_rgba(0,0,0,0.3)] transition-all uppercase tracking-wide"
        >
          {buttonText}
        </button>
      </div>
    </div>
  )
}

export default NeobrutalistPromoBanner

5. Floating Action Banner

Modern floating banner with gradient background, perfect for CTAs and important announcements.

Limited Time: 48 Hours Left!

Get our premium templates bundle for just $29 (was $99)

<div x-data="{ show: true }" x-show="show" class="fixed bottom-6 right-6 max-w-md bg-gradient-to-r from-violet to-purple-600 text-white rounded-2xl p-4 shadow-2xl backdrop-blur-sm z-50">
  <div class="flex items-start justify-between">
    <div class="flex items-start">
      <div class="w-10 h-10 bg-white/20 rounded-full flex items-center justify-center mr-3 flex-shrink-0">
        <svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
        </svg>
      </div>
      <div class="flex-1">
        <h4 class="font-bold text-sm mb-1">Limited Time: 48 Hours Left!</h4>
        <p class="text-white/90 text-xs mb-3">Get our premium templates bundle for just $29 (was $99)</p>
        <button class="bg-white text-violet font-bold px-4 py-2 rounded-full text-xs hover:bg-white/90 transition-colors">
          Get Deal
        </button>
      </div>
    </div>
    <button @click="show = false" class="text-white/80 hover:text-white ml-2">
      <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
      </svg>
    </button>
  </div>
</div>
<template>
  <Teleport to="body">
    <Transition
      enter-active-class="transition-all duration-300"
      enter-from-class="translate-y-full opacity-0"
      enter-to-class="translate-y-0 opacity-100"
      leave-active-class="transition-all duration-300"
      leave-from-class="translate-y-0 opacity-100"
      leave-to-class="translate-y-full opacity-0"
    >
      <div v-show="visible" class="fixed bottom-6 right-6 max-w-md bg-gradient-to-r from-violet to-purple-600 text-white rounded-2xl p-4 shadow-2xl backdrop-blur-sm z-50">
        <div class="flex items-start justify-between">
          <div class="flex items-start">
            <div class="w-10 h-10 bg-white/20 rounded-full flex items-center justify-center mr-3 flex-shrink-0">
              <svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
              </svg>
            </div>
            <div class="flex-1">
              <h4 class="font-bold text-sm mb-1">{{ title }}</h4>
              <p class="text-white/90 text-xs mb-3">{{ message }}</p>
              <button 
                @click="$emit('action')"
                class="bg-white text-violet font-bold px-4 py-2 rounded-full text-xs hover:bg-white/90 transition-colors"
              >
                {{ buttonText }}
              </button>
            </div>
          </div>
          <button @click="dismiss" class="text-white/80 hover:text-white ml-2">
            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
            </svg>
          </button>
        </div>
      </div>
    </Transition>
  </Teleport>
</template>

<script setup>
import { ref } from 'vue'

const props = defineProps({
  title: {
    type: String,
    default: 'Limited Time: 48 Hours Left!'
  },
  message: {
    type: String,
    default: 'Get our premium templates bundle for just $29 (was $99)'
  },
  buttonText: {
    type: String,
    default: 'Get Deal'
  },
  autoShow: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['action', 'dismiss'])
const visible = ref(props.autoShow)

const dismiss = () => {
  visible.value = false
  emit('dismiss')
}
</script>
import React, { useState, useEffect } from 'react'
import { createPortal } from 'react-dom'

const FloatingActionBanner = ({
  title = 'Limited Time: 48 Hours Left!',
  message = 'Get our premium templates bundle for just $29 (was $99)',
  buttonText = 'Get Deal',
  autoShow = true,
  onAction,
  onDismiss
}) => {
  const [visible, setVisible] = useState(autoShow)
  const [mounted, setMounted] = useState(false)

  useEffect(() => {
    setMounted(true)
  }, [])

  const handleDismiss = () => {
    setVisible(false)
    if (onDismiss) onDismiss()
  }

  const handleAction = () => {
    if (onAction) onAction()
  }

  if (!mounted || !visible) return null

  const banner = (
    <div className={`fixed bottom-6 right-6 max-w-md bg-gradient-to-r from-violet to-purple-600 text-white rounded-2xl p-4 shadow-2xl backdrop-blur-sm z-50 transition-all duration-300 ${visible ? 'translate-y-0 opacity-100' : 'translate-y-full opacity-0'}`}>
      <div className="flex items-start justify-between">
        <div className="flex items-start">
          <div className="w-10 h-10 bg-white/20 rounded-full flex items-center justify-center mr-3 flex-shrink-0">
            <svg className="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
          </div>
          <div className="flex-1">
            <h4 className="font-bold text-sm mb-1">{title}</h4>
            <p className="text-white/90 text-xs mb-3">{message}</p>
            <button 
              onClick={handleAction}
              className="bg-white text-violet font-bold px-4 py-2 rounded-full text-xs hover:bg-white/90 transition-colors"
            >
              {buttonText}
            </button>
          </div>
        </div>
        <button onClick={handleDismiss} className="text-white/80 hover:text-white ml-2">
          <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12" />
          </svg>
        </button>
      </div>
    </div>
  )

  return createPortal(banner, document.body)
}

export default FloatingActionBanner

🚀 How to Use These Banner Components

Requirements

  • TailwindCSS v4.0+ installed
  • AlpineJS for interactive functionality (HTML version)
  • Responsive breakpoint support

Features

  • Dismissible announcements
  • Animated gradient backgrounds
  • Call-to-action buttons with hover effects

Pro Tip: Use announcement banners at the top of your site for promotions and hero banners for landing pages. Both components are fully responsive and work great on mobile devices.

We use cookies to improve your experience and analytics. You can accept all cookies or reject non-essential ones.

Learn More