Tutorial December 3, 2025

Eye-Catching Animated Heading - Make Keywords Instantly Grab Attention!

Smooth animated curved underlines that instantly capture visitor attention! Highlight keywords with elegant animation effects, making important information stand out and effectively boost engagement and conversions. Perfect for product pages, hero sections, and sale announcements.

✨ Key Benefits

  • Increase Engagement: Animated curved underlines capture attention and reduce bounce rates
  • Boost Conversions: Highlight product benefits, sale announcements, and key messages effectively
  • Mobile Responsive: Fully optimized for all devices with performance-optimized code
  • Easy Customization: Control colors, sizes, animation speed, and alignment via Shopify theme editor
  • SEO Friendly: Supports H1, H2, H3 tags for better content hierarchy

🎬 Preview

📋 Installation

Step 1: Create curved-underline-heading.liquid in your theme's Sections directory.

Step 2: Copy the code below:

{%- style -%}
  .curved-underline-section-{{ section.id }} {
    padding-top: {{ section.settings.padding_top }}px;
    padding-bottom: {{ section.settings.padding_bottom }}px;
    overflow: visible;
  }
  
  .curved-underline-section-{{ section.id }} .curved-underline-wrapper {
    max-width: 100%;
    margin: 0 auto;
  }
  
  .curved-underline-section-{{ section.id }} .curved-underline-heading {
    text-align: {{ section.settings.text_alignment }};
    color: {{ section.settings.heading_color }};
    font-weight: 700;
    line-height: 1.3;
    margin: 0;
    word-wrap: break-word;
  }
  
  .curved-underline-section-{{ section.id }} .curved-underline-heading.h1 {
    font-size: {{ section.settings.heading_size }}px;
  }
  
  .curved-underline-section-{{ section.id }} .curved-underline-heading.h2 {
    font-size: calc({{ section.settings.heading_size }}px * 0.85);
  }
  
  .curved-underline-section-{{ section.id }} .curved-underline-heading.h3 {
    font-size: calc({{ section.settings.heading_size }}px * 0.7);
  }
  
  .curved-underline-section-{{ section.id }} .underlined-word {
    position: relative;
    display: inline-block;
    padding-bottom: 12px;
    z-index: 1;
  }
  
  .curved-underline-section-{{ section.id }} .curved-line {
    position: absolute;
    bottom: 0;
    left: -5%;
    width: 110%;
    height: 18px;
    overflow: visible;
    pointer-events: none;
    z-index: -1;
  }
  
  
  .curved-underline-section-{{ section.id }} .curved-line svg {
    width: 100%;
    height: 100%;
    display: block;
  }
  
  .curved-underline-section-{{ section.id }} .curved-line path {
    stroke: {{ section.settings.line_color }};
    stroke-width: {{ section.settings.line_thickness }};
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: 0.6;
    stroke-dasharray: 1000;
    stroke-dashoffset: 1000;
  }
  
  .curved-underline-section-{{ section.id }} .curved-line.animate path {
    animation: draw-line-{{ section.id }} {{ section.settings.animation_duration }}s ease-out forwards;
    animation-delay: {{ section.settings.animation_delay }}s;
  }
  
  
  @keyframes draw-line-{{ section.id }} {
    to {
      stroke-dashoffset: 0;
    }
  }
  
  @media screen and (max-width: 749px) {
    .curved-underline-section-{{ section.id }} .curved-underline-heading.h1 {
      font-size: 32px !important;
    }
    
    .curved-underline-section-{{ section.id }} .curved-underline-heading.h2 {
      font-size: 28px !important;
    }
    
    .curved-underline-section-{{ section.id }} .curved-underline-heading.h3 {
      font-size: 24px !important;
    }
    
    .curved-underline-section-{{ section.id }} .curved-line {
      height: 15px;
    }
  }
  
  @media screen and (min-width: 750px) and (max-width: 989px) {
    .curved-underline-section-{{ section.id }} .curved-underline-heading.h1 {
      font-size: 40px !important;
    }
    
    .curved-underline-section-{{ section.id }} .curved-underline-heading.h2 {
      font-size: 36px !important;
    }
    
    .curved-underline-section-{{ section.id }} .curved-underline-heading.h3 {
      font-size: 32px !important;
    }
  }
{%- endstyle -%}

<div class="curved-underline-section-{{ section.id }} page-width">
  <div class="curved-underline-wrapper">
    {% if section.settings.heading != blank %}
      <h2 class="curved-underline-heading {{ section.settings.heading_tag }}">
        {% assign heading_text = section.settings.heading %}
        {% assign highlight_word = section.settings.highlight_word %}
        
        {% if highlight_word != blank and heading_text contains highlight_word %}
          {% comment %} Use placeholder method to replace the first occurrence of highlight word {% endcomment %}
          {% assign placeholder = "|||UNDERLINE_PLACEHOLDER|||" %}
          {% assign modified_text = heading_text | replace_first: highlight_word, placeholder %}
          {% assign parts = modified_text | split: placeholder %}
          {{ parts[0] }}<span class="underlined-word">{{ highlight_word }}<span class="curved-line"><svg viewBox="0 0 200 18" preserveAspectRatio="none">
              <path d="M5,16 Q100,3 195,8" />
          </svg></span></span>{{ parts[1] }}
        {% else %}
          {{ heading_text }}
        {% endif %}
      </h2>
    {% endif %}
    
  </div>
</div>

<script>
  (function() {
    const section = document.querySelector('.curved-underline-section-{{ section.id }}');
    const curvedLines = section.querySelectorAll('.curved-line');
    
    const observerOptions = {
      root: null,
      rootMargin: '-100px 0px -100px 0px',
      threshold: 0.5
    };
    
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          curvedLines.forEach(line => {
            line.classList.add('animate');
          });
          observer.unobserve(entry.target);
        }
      });
    }, observerOptions);
    
    if (section) {
      observer.observe(section);
    }
  })();
</script>

{% schema %}
{
  "name": "Curved Underline Heading",
  "tag": "section",
  "class": "section-curved-underline",
  "settings": [
    {
      "type": "text",
      "id": "heading",
      "label": "Heading text",
      "default": "Curved Underline Heading"
    },
    {
      "type": "text",
      "id": "highlight_word",
      "label": "Highlighted word",
      "default": "Underline",
      "info": "Enter the word or phrase to add curved underline, can be single or multiple words"
    },
    {
      "type": "select",
      "id": "heading_tag",
      "label": "Heading tag",
      "options": [
        {
          "value": "h1",
          "label": "H1"
        },
        {
          "value": "h2",
          "label": "H2"
        },
        {
          "value": "h3",
          "label": "H3"
        }
      ],
      "default": "h2"
    },
    {
      "type": "range",
      "id": "heading_size",
      "min": 20,
      "max": 100,
      "step": 2,
      "unit": "px",
      "label": "Heading font size",
      "default": 48
    },
    {
      "type": "color",
      "id": "heading_color",
      "label": "Heading color",
      "default": "#000000"
    },
    {
      "type": "select",
      "id": "text_alignment",
      "label": "Text alignment",
      "options": [
        {
          "value": "left",
          "label": "Left"
        },
        {
          "value": "center",
          "label": "Center"
        },
        {
          "value": "right",
          "label": "Right"
        }
      ],
      "default": "center"
    },
    {
      "type": "header",
      "content": "Curved underline settings"
    },
    {
      "type": "color",
      "id": "line_color",
      "label": "Underline color",
      "default": "#FF6B6B"
    },
    {
      "type": "range",
      "id": "line_thickness",
      "min": 1,
      "max": 15,
      "step": 1,
      "unit": "px",
      "label": "Underline thickness",
      "default": 8
    },
    {
      "type": "range",
      "id": "animation_duration",
      "min": 0.5,
      "max": 3,
      "step": 0.1,
      "unit": "s",
      "label": "Animation duration",
      "default": 1.5
    },
    {
      "type": "range",
      "id": "animation_delay",
      "min": 0,
      "max": 3,
      "step": 0.1,
      "unit": "s",
      "label": "Animation delay",
      "default": 0.3
    },
    {
      "type": "header",
      "content": "Spacing settings"
    },
    {
      "type": "range",
      "id": "padding_top",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "label": "Top padding",
      "default": 40
    },
    {
      "type": "range",
      "id": "padding_bottom",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "label": "Bottom padding",
      "default": 40
    }
  ],
  "presets": [
    {
      "name": "Curved Underline Heading"
    }
  ]
}
{% endschema %}

Step 3: Add section via Online Store > Themes > Customize > Add section > Curved Underline Heading

💡 Usage

  1. Heading Text: Enter your heading in "Heading text" field
  2. Highlighted Word: Enter word/phrase to underline in "Highlighted word" field
  3. Customize: Adjust font size (20-100px), colors, alignment, underline thickness (1-15px), and animation timing

Best Practices:

  • Highlight 1-3 key words (product benefits, CTAs, sale keywords)
  • Ensure good color contrast for readability
  • Match underline color to your brand
Curved Underline Heading Settings