Components
41
Accordion Block Benifits Grid Block 404 Card Stack Careers Grid Case Study Carousel Case Study Hero Content Columns Content Image Content Image Accordion Content Video Cta Block Example Featured Blog Hero Featured Resource Hero Form Cta Form Hero Full Width Image Homepage Hero Hover List Image Hero Image Mask Image Testimonial Carousel Industry Insights Latest News List Columns Logo Scroller Map Block Post Feed Resource Grid Split Hero Split Text Statement Statistics Row Team Filter Team Grid Testimonial Carousel Testimonial Carousel Text Highlight Tools Grid Two Column List

Homepage Hero

View example

Transforming potential. Fuelling growth.

Growth partners
for ambitious businesses.

Talk to us

homepage-hero-bg

Case studies

Scroll to reveal more

Native Communities

Talk to us

4,466

viewings booked through PPC

175%

increase in organic conversions

6,121

website enquiries

Native case study- Kampus building at night
Field
Field Type
Field Name
Instructions
Content (initial view)
wysiwyg
content
Background image (initial view)
image
background_image
Note: Image must include the overlay to improve accessibility/legibility
Case study
relationship
case_study
Note: Choose which case study info appears on scroll. Case study info powered from the post type
Partners logos left
repeater
partners_logos_left
-- Logo
image
logo
-- Link
link
link
Partners logos right
repeater
partners_logos_right
-- Logo
image
logo
-- Link
link
link

				
@import "../../resources/scss/util/variables";
@import "../../resources/scss/util/mixins";
@import "../../resources/scss/vendor/bootstrap/vendor/rfs";

.block-homepage-hero {
	--text-color: var(--white);
	--hero-mask-size: 75%;
	--mask-y-offset: 90%;
	--mask-overlay-opacity: 0;

	@include bp($md) {
		--hero-mask-size: 50%;
		--mask-y-offset: 75%;
	}

	@include bp(1100px) {
		--hero-mask-size: 40%;
		// --mask-y-offset: 75%;
	}

	@include bp(1270px) {
		--hero-mask-size: 30%;
		// --mask-y-offset: 75%;
	}

	@include bp(1560px) {
		--hero-mask-size: 25%;
		// --mask-y-offset: 75%;
	}

	@include bp(1900px) {
		--hero-mask-size: 20%;
		// --mask-y-offset: 75%;
	}

	@include padding-top(rem-calc(120));
	@include padding-bottom(rem-calc(120));
	margin-bottom: 0.5rem;

	background-color: var(--primary);

	height: calc(100vh - #{rem-calc(20)});
	min-height: rem-calc(400);

	@include bp($lg) {
		min-height: rem-calc(930);
	}

	position: relative;

	.hero-social-links {
		position: absolute;
		z-index: 10;
		display: flex;
		flex-direction: row;
		gap: rem-calc(20);

		top: unset;
		bottom: rem-calc(20);
		left: 50%;
		transform: translateX(-50%);

		@include bp($lg) {
			gap: rem-calc(16);
			bottom: unset;
			top: rem-calc(20);
			left: rem-calc(20);
			transform: unset;
		}

		.social-icon {
			width: rem-calc(24);
			height: rem-calc(24);
			display: block;
			background-repeat: no-repeat;
			background-position: center;
			background-size: contain;
			transition: opacity 0.3s ease;
			
			@include bp($md) {
				width: rem-calc(32);
				height: rem-calc(32);
			}

			&:hover {
				opacity: 0.7;
			}

			.sr-only {
				position: absolute;
				width: 1px;
				height: 1px;
				padding: 0;
				margin: -1px;
				overflow: hidden;
				clip: rect(0, 0, 0, 0);
				white-space: nowrap;
				border-width: 0;
			}

			&-tiktok {
				background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill-rule='evenodd' stroke-linejoin='round' stroke-miterlimit='2' clip-rule='evenodd' viewBox='0 0 64 64' id='tiktok'%3E%3Cpath d='M33 7a1 1 0 0 0-1 1v34c0 2.76-2.24 5-5 5s-5-2.24-5-5 2.24-5 5-5a1 1 0 0 0 1-1v-8a1 1 0 0 0-1-1c-8.28 0-15 6.721-15 15 0 8.28 6.72 15 15 15 8.279 0 15-6.72 15-15V25.494A16.927 16.927 0 0 0 49 27h2a1 1 0 0 0 1-1v-8a1 1 0 0 0-1-1h-2c-3.863 0-7-3.137-7-7V8a1 1 0 0 0-1-1zm1 2h6v1c0 4.967 4.033 9 9 9h1v6h-1c-2.731 0-5.292-.73-7.499-2.009a1 1 0 0 0-1.501.866V42c0 7.175-5.825 13-13 13s-13-5.825-13-13c0-6.838 5.292-12.45 12-12.962v6.033c-3.39.486-6 3.405-6 6.93 0 3.862 3.137 7 7 7s7-3.138 7-7z' fill='white' stroke='white' stroke-width='3'/%3E%3C/svg%3E%0A");
			}

			&-linkedin {
				background-image: url("data:image/svg+xml,%3Csvg width='25' height='25' viewBox='0 0 25 25' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M16.2109 8.54297C17.8022 8.54297 19.3284 9.17511 20.4536 10.3003C21.5788 11.4255 22.2109 12.9517 22.2109 14.543V21.543H18.2109V14.543C18.2109 14.0125 18.0002 13.5038 17.6252 13.1288C17.2501 12.7537 16.7414 12.543 16.2109 12.543C15.6805 12.543 15.1718 12.7537 14.7967 13.1288C14.4217 13.5038 14.2109 14.0125 14.2109 14.543V21.543H10.2109V14.543C10.2109 12.9517 10.8431 11.4255 11.9683 10.3003C13.0935 9.17511 14.6196 8.54297 16.2109 8.54297Z' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M6.21094 9.54297H2.21094V21.543H6.21094V9.54297Z' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M4.21094 6.54297C5.31551 6.54297 6.21094 5.64754 6.21094 4.54297C6.21094 3.4384 5.31551 2.54297 4.21094 2.54297C3.10637 2.54297 2.21094 3.4384 2.21094 4.54297C2.21094 5.64754 3.10637 6.54297 4.21094 6.54297Z' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E%0A");
			}

			&-instagram {
				background-image: url("data:image/svg+xml,%3Csvg width='25' height='25' viewBox='0 0 25 25' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M17.2109 2.54297H7.21094C4.44951 2.54297 2.21094 4.78154 2.21094 7.54297V17.543C2.21094 20.3044 4.44951 22.543 7.21094 22.543H17.2109C19.9724 22.543 22.2109 20.3044 22.2109 17.543V7.54297C22.2109 4.78154 19.9724 2.54297 17.2109 2.54297Z' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M16.2106 11.9133C16.3341 12.7455 16.1919 13.5955 15.8044 14.3423C15.4169 15.0891 14.8038 15.6947 14.0523 16.0729C13.3008 16.4512 12.4491 16.5829 11.6184 16.4492C10.7878 16.3155 10.0204 15.9234 9.42548 15.3284C8.83056 14.7335 8.43838 13.9661 8.30471 13.1355C8.17105 12.3048 8.30271 11.4532 8.68097 10.7016C9.05923 9.95012 9.66483 9.33701 10.4116 8.94951C11.1584 8.56201 12.0084 8.41986 12.8406 8.54327C13.6896 8.66915 14.4755 9.06473 15.0823 9.67158C15.6892 10.2784 16.0848 11.0643 16.2106 11.9133Z' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M17.7109 7.04297H17.7209' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E%0A");
			}
		}
	}

	.initial-content {
		padding-top: 4rem;

		.col-12 {
			text-align: center;

			.btn {
				@include fluid-type(16, 26);
				padding: rem-calc(17 30);
			}
		}
	}

	.container {
		position: relative;
		z-index: 5;

		&.mask-container {
			&.inactive {
				pointer-events: none;
			}
		}
	}

	> picture {
		border-radius: rem-calc(24);
		overflow: hidden;
	}

	.pill {
		width: rem-calc(416);
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;

		position: absolute;
		top: var(--mask-y-offset);
		left: 50%;
		z-index: 10;
		transform: translate3d(-50%, calc(-1.25 * var(--mask-y-offset)), 0);

		&-title {
			//
		}

		&-subtitle {
			margin-bottom: 0;
		}
	}

	.alt-container {
		position: absolute;
		inset: 0;
		width: 100%;
		height: 100%;

		border-radius: rem-calc(24);

		mask: url("data:image/svg+xml,%3Csvg width='416' height='196' viewBox='0 0 416 196' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 98C0 43.8761 43.8761 0 98 0H318C372.124 0 416 43.8761 416 98C416 152.124 372.124 196 318 196H98C43.8761 196 0 152.124 0 98Z' fill='white'/%3E%3C/svg%3E%0A");
		mask-repeat: no-repeat;
		mask-position: center var(--mask-y-offset);
		mask-size: 10%;
		mask-size: var(--hero-mask-size);

		.alt-hero {
			height: 100%;
			position: relative;

			.container,
			.row {
				height: 100%;
			}
		}

		.container {
			position: relative;
			z-index: 2;
		}

		.alt-content {
			display: flex;
			flex-direction: column;
			align-items: center;
			justify-content: center;

			.content-col {
				height: 100%;

				display: flex;
				flex-direction: column;
				align-items: center;
				justify-content: center;
				gap: rem-calc(24);
				padding-bottom: rem-calc(40);
			}

			.content-inner {
				margin-top: auto;

				display: flex;
				flex-direction: column;
				align-items: center;
				justify-content: center;
				gap: rem-calc(24);
			}
		}

		.stats {
			display: flex;
			flex-direction: row;
			flex-wrap: wrap;
			align-items: center;
			justify-content: center;
			gap: rem-calc(24);
			margin-top: auto;
			margin-bottom: 2rem;

			@include bp($lg) {
				margin-bottom: 0;
			}

			.stat {
				max-width: rem-calc(140);
				display: flex;
				flex-direction: column;
				align-items: center;
				justify-content: center;
				text-align: center;
				padding: 0;

				p {
					margin-bottom: 0;

					&.stat-number {
						line-height: 1;
					}

					&.stat-description {
						font-weight: 400;
					}
				}
			}
		}

		picture {
			z-index: 1;

			&:before {
				width: 100%;
				height: 100%;
				content: '';
				background-color: black;
				position: absolute;
				inset: 0;
				z-index: 1;
				opacity: var(--mask-overlay-opacity);
			}
		}
	}

	.alt-content {
		opacity: 0;
	}

    .initial-content {
        height: 100%;
    }
    
	.partner-logos {
		position: absolute;
		width: 100%;
		padding: 0 1.5rem;
	}
	
	@media (min-height: 820px) {
        .partner-logos {
            top: 50%;
        }
    }
	
    @media (min-width: 1200px) {
        .partner-logos {
            top: 72%;
        }
    }
    
    @media (min-width: 768px) {
        .block-homepage-hero {
            --mask-y-offset: 85%
        }
    }
    
    @media (min-width: 1024px) {
        .block-homepage-hero {
            --mask-y-offset: 77%
        }
    }
    
    @media (min-width: 1200px) {
        .block-homepage-hero {
            --mask-y-offset: 75%
        }
    }
	
	.partner-logos .logo {
	    padding: 0.5rem 0;
	}

	.partner-logos .logo img {
		max-height: 35px;
		width: auto;
		margin-top: 1rem;

		@media (min-width: 1024px) {
			margin-top: 0;
			max-height: 50px;
		}
	}
	
	.alt-container .alt-content .content-inner {
	    margin-top: 5%;
	}
	
	.alt-container .stats {
	    margin-top: 3rem;
	}
	
	.alt-container .stats {
        align-items: flex-start;
	}
}
class HomepageHero {
	/**
	 * Create and initialise objects of this class
	 * @param {object} block
	 */
	constructor(block) {
		this.block = block;
		this.scrollTriggers = [];
		this.animation = null;
		this.baseMaskPx = 416; // base mask size in pixels used to derive start percentage

		const debounce = (func, wait) => {
			let timeout;
			return function(...args) {
				const context = this;
				clearTimeout(timeout);
				timeout = setTimeout(() => func.apply(context, args), wait);
			};
		};

		const debouncedInit = debounce(() => {
			this.init();
		}, 250);

		window.addEventListener('resize', debouncedInit);

		this.init();
	}

	/**
	 * Clean up all ScrollTrigger instances and animations
	 */
	cleanup() {
		// Kill all ScrollTrigger instances
		this.scrollTriggers.forEach(trigger => {
			trigger.kill();
		});
		this.scrollTriggers = [];

		// Kill the animation timeline if it exists
		if (this.animation) {
			this.animation.kill();
			this.animation = null;
		}

		// Remove inline CSS variable so it can be recalculated cleanly
		if (this.block && this.block.style) {
			this.block.style.removeProperty('--hero-mask-size');
		}

		// Refresh ScrollTrigger to recalculate positions
		ScrollTrigger.refresh();
	}

	init() {
		// Clean up any existing ScrollTriggers and animations before reinitializing
		this.cleanup();

		const pill = this.block.querySelector('.pill');
		const initialContent = this.block.querySelector('.initial-content');
		const altContent = this.block.querySelector('.alt-content');
		const maskContainer = this.block.querySelector('.mask-container');

		// Reset styles that might have been modified
		if (altContent) {
			altContent.style.opacity = '';
		}
		if (maskContainer) {
			maskContainer.classList.remove('inactive');
		}

		// Compute and set initial mask size based on viewport width
		const startMaskPercent = Math.max(0, Math.min(75, (this.baseMaskPx / window.innerWidth) * 100));
		this.block.style.setProperty('--hero-mask-size', `${startMaskPercent}%`);

		const firstScrollTrigger = ScrollTrigger.create({
			trigger: initialContent,
			start: 'top top',
			end: 'bottom top',
			onEnter: () => {
				if (altContent) {
					altContent.style.opacity = 1;
				}
			}
		});
		this.scrollTriggers.push(firstScrollTrigger);

		// scrolltrigger, pin the block, on scroll, animate the --mask-size to 160%
		this.animation = gsap.timeline({
			paused: true,
		});

		this.animation.to(initialContent, {
			autoAlpha: 0,
			duration: 0.5,
			ease: 'power1.inOut',
		}, 0);

		this.animation.to(pill, {
			autoAlpha: 0,
			duration: 0.5,
			ease: 'power1.inOut',
		}, 0);

		this.animation.add(() => {
			if (maskContainer) {
				maskContainer.classList.toggle('inactive');
			}
		});

		let maxMaskSize = 400;
		if(window.innerWidth >= 768) {
			maxMaskSize = 300;
		}
		if(window.innerWidth >= 992) {
			maxMaskSize = 220;
		}

		// Animate from current --hero-mask-size value to the computed end size
		this.animation.to(this.block, {
			'--hero-mask-size': `${maxMaskSize}%`,
			duration: 0.5,
			ease: 'power1.inOut',
		}, '-=50%');

		this.animation.to(this.block, {
			'--mask-overlay-opacity': 0.7,
			duration: 0.5,
			ease: 'power1.inOut',
		}, '<50%');

		this.animation.fromTo(altContent, {
			autoAlpha: 0,
		}, {
			autoAlpha: 1,
			duration: 0.5,
			ease: 'power1.inOut',
		}, '<50%');

		const secondScrollTrigger = ScrollTrigger.create({
			trigger: this.block,
			start: 'top 10px',
			end: 'bottom top',
			pin: true,
			pinSpacing: true,
			animation: this.animation,
			scrub: 0.5,
			refreshPriority: 1,
		});
		this.scrollTriggers.push(secondScrollTrigger);

		requestAnimationFrame(() => {
			ScrollTrigger.refresh();
		});
	}
}

document.addEventListener('DOMContentLoaded', () => {
	document.querySelectorAll('.block-homepage-hero').forEach( block => new HomepageHero(block) );
});
{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 2,
    "name": "strategiq/homepage-hero",
    "title": "Homepage hero",
    "description": "Block to be used as a template",
    "category": "strategiq",
    "icon": "strategiq",
    "acf": {
        "mode": "preview",
        "renderTemplate": "block-homepage-hero.php"
    },
    "supports": {
        "anchor": true,
        "align": false,
        "color": {
            "background": false,
            "text": false,
            "gradients": false
        },
        "spacing": {
            "padding": [],
            "margin": []
        }
    },
    "example": {
        "attributes": {
            "mode": "preview",
            "data": {
                "heading_type": "h2",
                "heading_text": "Example - Example",
                "content": "This is some example content to represent what the content will look like"
            }
        }
    },
    "style": "file:../../assets/css/homepage-hero/block-homepage-hero.css"
}
Page Title
Page Type
Page URL
Front Page 2025
page
There are is no readme file with this component.