Summary
- Introduction
- Example 1: Testimonial Slider
- Example 2: Testimonial Slider with Stars
- Example 3: Stacked Testimonials
- Example 4: Grid
- Final Notes
- Resources
Introduction
Testimonials are a powerful way to build trust and showcase customer satisfaction directly on your website. In this guide, we share a few testimonial widget customization examples that you can just copy and paste!
Each example includes a screenshot, the HTML structure, and the CSS styling so you can easily adapt them to your design.
If you need to modify the layout, styling, or behavior of any example, you can use AI tools to customize the code to match your brand, website framework, or design preferences.
Example 1: Testimonial Slider
Preview
Basic customization:
- Brand color: To adjust the color of the inner scroller according to your brand, you can simply change the color code in the CSS code:
If you don’t know the color code, the following tool can be helpful to grab this information from the website: ColorZilla - Chrome Web Store
HTML
▶ Click to expand HTML code
<div class="crw-theme-color crw-tst-modern-slider" id="crw-slider-widget">
<% if (!surveys.length) { %>
<div class="crw-empty-message">
No testimonials at this moment.
</div>
<% } else { %>
<div class="crw-slider-wrapper">
<button class="crw-nav-btn crw-prev" onclick="moveSlider(-1)">
<svg viewBox="0 0 24 24"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></svg>
</button>
<div class="crw-track-container">
<div class="crw-track" id="crw-track">
<% _.each(surveys, function(survey, index) { %>
<div class="crw-card-item">
<div class="crw-card-inner">
<div class="crw-card-header">
<div class="crw-name"><%= survey.customer_data.contact_anon_name %></div>
<% if (survey.customer_data.customer_name) { %>
<div class="crw-company"><%= survey.customer_data.customer_name %></div>
<% } %>
<div class="crw-date"><%= moment(survey.closed).format('MM/DD/YYYY') %></div>
</div>
<div class="crw-card-body">
<div class="crw-comment-text" id="comment-<%= index %>">
<%= survey.comment %>
</div>
<div class="crw-read-more-btn" onclick="toggleExpand('comment-<%= index %>', this)">
⌄
</div>
</div>
</div>
</div>
<% }); %>
</div>
</div>
<button class="crw-nav-btn crw-next" onclick="moveSlider(1)">
<svg viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>
</button>
</div>
<div class="crw-powered-by">
<a href="https://www.crewhu.com" target="_blank">Powered by <img src="https://cdn2.hubspot.net/hubfs/445399/crewhu_images/image.png" alt="Crewhu"></a>
</div>
<% } %>
</div>
<style>
<%= cssTemplate %>
</style>
<style>
/* CONTAINER RESET */
.crw-tst-modern-slider {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 20px 0;
box-sizing: border-box;
position: relative;
background-color: transparent;
}
.crw-tst-modern-slider * {
box-sizing: border-box;
}
/* FLEX WRAPPER */
.crw-slider-wrapper {
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
/* NAVIGATION ARROWS */
.crw-nav-btn {
background: none;
border: 2px solid var(--brand-color);
color: var(--brand-color);
width: 40px;
height: 40px;
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
z-index: 10;
flex-shrink: 0;
padding: 0;
}
.crw-nav-btn svg {
width: 24px;
height: 24px;
fill: currentColor;
display: block;
}
.crw-nav-btn:hover {
background-color: var(--brand-color);
color: #fff;
}
@media (max-width: 500px) {
.crw-nav-btn {
width: 30px;
height: 30px;
}
.crw-nav-btn svg {
width: 18px;
height: 18px;
}
}
/* TRACK CONTAINER - UPDATED: SYMMETRIC PADDING */
.crw-track-container {
overflow: hidden;
width: 100%;
margin: 0 15px;
padding: 20px 0;
}
/* TRACK ANIMATION */
.crw-track {
display: flex;
transition: transform 0.5s cubic-bezier(0.25, 1, 0.5, 1);
width: 100%;
margin: 0;
padding: 0;
list-style: none;
}
/* SLIDE ITEM */
.crw-card-item {
flex: 0 0 33.333%;
padding: 0 10px;
display: flex;
}
@media (max-width: 992px) {
.crw-card-item { flex: 0 0 50%; }
}
@media (max-width: 600px) {
.crw-card-item { flex: 0 0 100%; }
}
/* CARD DESIGN */
.crw-card-inner {
background: var(--card-bg);
border-radius: 12px;
box-shadow: 0 4px 15px var(--shadow-color);
padding: 30px 25px;
width: 100%;
text-align: center;
transition: transform 0.3s ease, box-shadow 0.3s ease;
display: flex;
flex-direction: column;
border: 1px solid rgba(0,0,0,0.02);
min-height: 280px;
justify-content: flex-start;
}
.crw-card-inner:hover {
transform: translateY(-5px);
box-shadow: 0 8px 25px rgba(0,0,0,0.15);
}
/* HEADER: UPDATED FOR ALIGNMENT */
.crw-card-header {
height: 110px;
display: flex;
flex-direction: column;
justify-content: center;
margin-bottom: 10px;
flex-shrink: 0;
border-bottom: 1px solid transparent;
}
/* TYPOGRAPHY */
.crw-name {
font-size: 1.2em;
font-weight: 700;
color: var(--text-main);
margin-bottom: 4px;
text-transform: capitalize;
line-height: 1.2;
}
.crw-company {
font-size: 0.95em;
font-weight: 600;
color: var(--text-muted);
margin-bottom: 4px;
text-transform: none;
line-height: 1.2;
}
.crw-date {
font-size: 0.8em;
color: #999;
margin-top: 4px;
}
/* COMMENT BOX */
.crw-card-body {
position: relative;
}
.crw-comment-text {
font-size: 1em;
line-height: 1.6;
color: #555;
font-style: italic;
display: -webkit-box;
-webkit-line-clamp: 5;
-webkit-box-orient: vertical;
overflow: hidden;
max-height: 8em;
transition: max-height 0.5s ease;
}
.crw-comment-text.expanded {
-webkit-line-clamp: unset;
max-height: 1000px;
overflow: visible;
}
/* READ MORE ARROW */
.crw-read-more-btn {
display: none;
font-size: 24px;
color: var(--brand-color);
cursor: pointer;
margin-top: 10px;
line-height: 1;
font-weight: bold;
animation: bounce 2s infinite;
}
.crw-read-more-btn:hover {
transform: scale(1.2);
}
@keyframes bounce {
0%, 20%, 50%, 80%, 100% {transform: translateY(0);}
40% {transform: translateY(5px);}
60% {transform: translateY(3px);}
}
/* POWERED BY FOOTER */
.crw-powered-by {
text-align: center;
margin-top: 20px;
font-size: 10px;
color: #ccc;
}
.crw-powered-by a { text-decoration: none; color: inherit; display: flex; align-items: center; justify-content: center; }
.crw-powered-by img { height: 16px; margin-left: 5px; opacity: 0.6; }
/* EMPTY STATE */
.crw-empty-message { text-align: center; padding: 40px; color: #777; font-style: italic; }
</style>
<script>
(function() {
var widgetContainer = document.getElementById('crw-slider-widget');
if (!widgetContainer) return;
var track = widgetContainer.querySelector('.crw-track');
var items = widgetContainer.getElementsByClassName('crw-card-item');
if (!track || items.length === 0) return;
var currentIndex = 0;
var totalItems = items.length;
var autoSlideInterval;
function getItemsPerSlide() {
var width = window.innerWidth;
if (width <= 600) return 1;
if (width <= 992) return 2;
return 3;
}
window.moveSlider = function(direction) {
var itemsVisible = getItemsPerSlide();
if (totalItems <= itemsVisible) return;
var maxIndex = totalItems - itemsVisible;
currentIndex += direction;
if (currentIndex < 0) {
currentIndex = maxIndex;
} else if (currentIndex > maxIndex) {
currentIndex = 0;
}
updateCarousel();
};
function updateCarousel() {
var itemsVisible = getItemsPerSlide();
var itemWidth = 100 / itemsVisible;
var translateValue = -(currentIndex * itemWidth);
track.style.transform = 'translateX(' + translateValue + '%)';
}
function startAutoSlide() {
stopAutoSlide();
if (totalItems > getItemsPerSlide()) {
autoSlideInterval = setInterval(function() {
moveSlider(1);
}, 5000);
}
}
function stopAutoSlide() {
if (autoSlideInterval) clearInterval(autoSlideInterval);
}
window.toggleExpand = function(elementId, btn) {
var el = document.getElementById(elementId);
if (el.classList.contains('expanded')) {
el.classList.remove('expanded');
btn.innerHTML = '⌄';
} else {
el.classList.add('expanded');
btn.innerHTML = '⌃';
}
};
function checkTextLength() {
var comments = widgetContainer.getElementsByClassName('crw-comment-text');
for (var i = 0; i < comments.length; i++) {
if (comments[i].scrollHeight > comments[i].clientHeight) {
var btn = comments[i].parentNode.querySelector('.crw-read-more-btn');
if (btn) btn.style.display = 'block';
}
}
}
widgetContainer.addEventListener('mouseenter', stopAutoSlide);
widgetContainer.addEventListener('mouseleave', startAutoSlide);
window.addEventListener('resize', function() { updateCarousel(); });
setTimeout(function() {
checkTextLength();
startAutoSlide();
}, 100);
})();
</script>
CSS
▶ Click to expand CSS code
:root {
--brand-color: #fca311;
--card-bg: #ffffff;
--text-main: #333333;
--text-muted: #777777;
--shadow-color: rgba(0,0,0,0.1);
}
Example 2: Testimonial Slider with Stars
Preview
HTML
▶ Click to expand HTML code
<!-- ===== Testimonials (4 per slide, square cards, 5 gold stars, arrows, autoplay 4.5s) ===== -->
<div class="crw-theme-color crw-tst">
<div class="crw-tst-container crw-slides-4" id="crwTstRoot">
<!-- EMPTY MESSAGE -->
<% if (!surveys.length) { %>
<div class="crw-tst-grd-card" style="display:block">
No testimonials at this moment
</div>
<% } %>
<!-- SIDE ARROWS (unicode triangles) -->
<button type="button" class="crw-tst-arrow crw-tst-arrow--prev" aria-label="Previous testimonials" onclick="tstPrev()">◀</button>
<button type="button" class="crw-tst-arrow crw-tst-arrow--next" aria-label="Next testimonials" onclick="tstNext()">▶</button>
<!-- ALL CARDS (JS shows only the current 4) -->
<div id="tstSlideWindow" class="crw-tst-slide-window" aria-live="polite">
<% _.each(surveys, function(survey, index) { %>
<div class="crw-tst-grd-card" data-idx="<%= index %>">
<!-- Five gold stars (solid fill so all cards render consistently) -->
<div class="crw-tst-stars" aria-hidden="true">
<svg viewBox="0 0 110 20" width="90" height="20" role="img" focusable="false" aria-hidden="true">
<g fill="#FFD700">
<path d="M10 1l2.6 5.3 5.9.9-4.3 4.2 1 5.9L10 14.5 4.8 17.3l1-5.9-4.3-4.2 5.9-.9z"></path>
<path transform="translate(22,0)" d="M10 1l2.6 5.3 5.9.9-4.3 4.2 1 5.9L10 14.5 4.8 17.3l1-5.9-4.3-4.2 5.9-.9z"></path>
<path transform="translate(44,0)" d="M10 1l2.6 5.3 5.9.9-4.3 4.2 1 5.9L10 14.5 4.8 17.3l1-5.9-4.3-4.2 5.9-.9z"></path>
<path transform="translate(66,0)" d="M10 1l2.6 5.3 5.9.9-4.3 4.2 1 5.9L10 14.5 4.8 17.3l1-5.9-4.3-4.2 5.9-.9z"></path>
<path transform="translate(88,0)" d="M10 1l2.6 5.3 5.9.9-4.3 4.2 1 5.9L10 14.5 4.8 17.3l1-5.9-4.3-4.2 5.9-.9z"></path>
</g>
</svg>
</div>
<div class="crw-tst-name"><%= survey.customer_data.contact_anon_name %></div>
<div class="crw-tst-date"><%= moment(survey.closed).format('MM/DD/YYYY') %></div>
<!-- Message area (no see-more; truncated to 5 lines) -->
<div class="crw-tst-grd-message crw-tst-grd-message-short" id="message<%= index%>">
<%= survey.comment %>
</div>
</div>
<% }); %>
</div>
</div>
</div>
<!-- ===== Styles (4-column square cards, 5 gold stars, arrows, shadows) ===== -->
<style>
/* Base container */
.crw-tst {
font-family: sans-serif;
font-weight: lighter;
height: auto;
width: 100%;
}
.crw-tst .crw-tst-container {
width: 90%;
margin-left: auto;
margin-right: auto;
padding-bottom: 30px;
text-align: center;
position: relative;
}
.crw-tst .crw-tst-powered {
font-size: 0.6em;
margin-top: 10px;
}
.crw-tst .crw-tst-powered a {
text-decoration: none;
color: inherit;
}
.crw-tst .crw-tst-powered img {
height: 20px;
width: auto;
margin-left: 5px;
vertical-align: middle;
}
.crw-tst .crw-tst-name {
text-align: center;
font-weight: bold;
font-size: 1.05em;
text-transform: capitalize;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
margin-top: 6px;
}
.crw-tst .crw-tst-date {
margin-bottom: 8px;
margin-top: 3px;
text-align: center;
font-size: 0.7em;
opacity: 0.8;
}
.crw-tst .crw-tst-stars {
margin-bottom: 8px;
display: flex;
align-items: center;
justify-content: center;
}
.crw-tst .crw-tst-container.crw-slides-4 {
max-width: 1200px;
margin-left: auto;
margin-right: auto;
}
.crw-tst .crw-tst-slide-window {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 18px;
padding: 0 44px;
}
.crw-tst .crw-tst-container.crw-slides-4 .crw-tst-grd-card {
box-shadow: 0 6px 18px rgba(0,0,0,0.12);
border-radius: 12px;
background: #fff;
display: none;
padding: 16px;
box-sizing: border-box;
aspect-ratio: 1 / 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
}
.crw-tst .crw-tst-grd-message {
font-size: 0.95em;
line-height: 19px;
width: 100%;
margin-top: 8px;
flex: 1 1 auto;
position: relative;
}
.crw-tst .crw-tst-grd-message-short {
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 5;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
}
.crw-tst .crw-tst-arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
background: transparent;
border: none;
color: #333;
font-size: 30px;
line-height: 1;
width: 36px;
height: 36px;
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0;
user-select: none;
}
.crw-tst .crw-tst-arrow:hover { color: #000; }
.crw-tst .crw-tst-arrow:focus {
outline: 2px solid #8ab4f8; border-radius: 4px;
}
.crw-tst .crw-tst-arrow--prev { left: 0; }
.crw-tst .crw-tst-arrow--next { right: 0; }
#crwTstRoot.autoplay-paused::after {
content: "Paused";
position: absolute;
top: -20px;
right: 0;
font-size: 0.85em;
color: #888;
}
@media (max-width: 1100px) {
.crw-tst .crw-tst-slide-window { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 820px) {
.crw-tst .crw-tst-slide-window { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
.crw-tst .crw-tst-slide-window { grid-template-columns: 1fr; }
}
</style>
<script type="application/javascript">
var TST_PAGE = 0;
var TST_PAGE_SIZE = 4;
var TST_AUTOPLAY_MS = 7000;
var TST_AUTOPLAY_TIMER = null;
function renderSlideWindow() {
var container = document.querySelector('.crw-tst-container.crw-slides-4');
if (!container) return;
var cards = container.querySelectorAll('.crw-tst-grd-card');
var total = cards.length;
if (!total) return;
var pageCount = Math.ceil(total / TST_PAGE_SIZE);
if (TST_PAGE >= pageCount) TST_PAGE = pageCount - 1;
if (TST_PAGE < 0) TST_PAGE = 0;
var start = TST_PAGE * TST_PAGE_SIZE;
var end = Math.min(start + TST_PAGE_SIZE, total);
for (var i = 0; i < total; i++) {
cards[i].style.display = (i >= start && i < end) ? 'flex' : 'none';
}
}
function tstNext() {
var cardsCount = document.querySelectorAll('.crw-tst-container.crw-slides-4 .crw-tst-grd-card').length;
var pageCount = Math.ceil(cardsCount / TST_PAGE_SIZE);
if (pageCount < 2) return;
TST_PAGE = (TST_PAGE + 1) % pageCount;
renderSlideWindow();
}
function tstPrev() {
var cardsCount = document.querySelectorAll('.crw-tst-container.crw-slides-4 .crw-tst-grd-card').length;
var pageCount = Math.ceil(cardsCount / TST_PAGE_SIZE);
if (pageCount < 2) return;
TST_PAGE = (TST_PAGE - 1 + pageCount) % pageCount;
renderSlideWindow();
}
function startAutoplay() {
stopAutoplay();
if (TST_AUTOPLAY_MS > 0) {
TST_AUTOPLAY_TIMER = setInterval(function () {
var cardsCount = document.querySelectorAll('.crw-tst-container.crw-slides-4 .crw-tst-grd-card').length;
var pageCount = Math.ceil(cardsCount / TST_PAGE_SIZE);
if (pageCount > 1) {
tstNext();
}
}, TST_AUTOPLAY_MS);
}
}
function stopAutoplay() {
if (TST_AUTOPLAY_TIMER) {
clearInterval(TST_AUTOPLAY_TIMER);
TST_AUTOPLAY_TIMER = null;
}
}
function pauseAutoplayUI(pause) {
var root = document.getElementById('crwTstRoot');
if (!root) return;
if (pause) root.classList.add('autoplay-paused');
else root.classList.remove('autoplay-paused');
}
function bindHoverPause() {
var root = document.getElementById('crwTstRoot');
if (!root) return;
root.addEventListener('mouseenter', function () {
pauseAutoplayUI(true);
stopAutoplay();
});
root.addEventListener('mouseleave', function () {
pauseAutoplayUI(false);
startAutoplay();
});
}
function bindVisibilityPause() {
document.addEventListener('visibilitychange', function () {
if (document.hidden) {
stopAutoplay();
} else {
startAutoplay();
}
});
}
(function initTestimonials() {
var init = function () {
renderSlideWindow();
bindHoverPause();
bindVisibilityPause();
startAutoplay();
};
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
setTimeout(renderSlideWindow, 0);
})();
</script>
CSS
▶ Click to expand CSS code
var ywtCarousel = {
init: function (interval) {
this.interval = interval || 5000;
this.slides = document.querySelectorAll('.crw-tst-carousel .crw-tst-slide');
this.current = 0;
this.total = this.slides.length;
this.container = document.querySelector('.crw-tst-carousel');
if (this.total === 0) return;
this.start();
},
start: function() {
if (this.timer) clearInterval(this.timer);
this.timer = setInterval(() => {
this.next();
}, this.interval);
},
next: function() {
if (this.total <= 1) return;
var container = this.container;
var slideWidth = container.clientWidth;
var slideOffset = this.current * slideWidth;
if (this.current === this.total - 1) {
container.scrollLeft = 0;
this.current = 0;
} else {
container.scrollLeft += slideWidth;
this.current++;
}
},
prev: function() {
if (this.total <= 1) return;
var container = this.container;
var slideWidth = container.clientWidth;
var slideOffset = this.current * slideWidth;
if (this.current === 0) {
container.scrollLeft = (this.total - 1) * slideWidth;
this.current = this.total - 1;
} else {
container.scrollLeft -= slideWidth;
this.current--;
}
}
};
window.onload = function() {
var interval = Math.floor(Math.random() * 5000) + 5000;
ywtCarousel.init(interval);
};
Example 3: Stacked Testimonials
Preview
HTML
▶ Click to expand HTML code
<div class="crw-theme-color crw-tst-modern-stacked-row" id="crw-stacked-widget">
<% if (!surveys.length) { %>
<div class="crw-empty-message">
No testimonials at this moment.
</div>
<% } else { %>
<div class="crw-stacked-container">
<% _.each(surveys, function(survey, index) { %>
<div class="crw-stacked-card">
<div class="crw-card-content">
<div class="crw-col-left">
<div class="crw-quote-icon">
<svg viewBox="0 0 512 512">
<path d="M464 256h-80v-64c0-35.3 28.7-64 64-64h8c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24h-8c-88.4 0-160 71.6-160 160v240c0 26.5 21.5 48 48 48h128c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48zm-288 0H96v-64c0-35.3 28.7-64 64-64h8c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24h-8C71.6 32 0 103.6 0 192v240c0 26.5 21.5 48 48 48h128c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z"/>
</svg>
</div>
<div class="crw-card-header">
<div class="crw-name"><%= survey.customer_data.contact_anon_name %></div>
<% if (survey.customer_data.customer_name) { %>
<div class="crw-company"><%= survey.customer_data.customer_name %></div>
<% } %>
<div class="crw-date"><%= moment(survey.closed).format('MM/DD/YYYY') %></div>
</div>
</div>
<div class="crw-col-right">
<div class="crw-card-body">
<div class="crw-comment-text" id="stack-comment-<%= index %>">
<%= survey.comment %>
</div>
<div class="crw-read-more-btn" onclick="toggleStackExpand('stack-comment-<%= index %>', this)">
⌄
</div>
</div>
</div>
</div>
</div>
<% }); %>
</div>
<div class="crw-powered-by">
<a href="https://www.crewhu.com" target="_blank">Powered by <img src="https://cdn2.hubspot.net/hubfs/445399/crewhu_images/image.png" alt="Crewhu"></a>
</div>
<% } %>
</div>
<style>
<%= cssTemplate %>
</style>
<style>
.crw-tst-modern-stacked-row {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
width: 100%;
margin: 0 auto;
padding: 20px 10px;
box-sizing: border-box;
background-color: transparent;
}
.crw-tst-modern-stacked-row * {
box-sizing: border-box;
}
.crw-stacked-container {
display: flex;
flex-direction: column;
width: 100%;
max-width: 900px;
margin: 0 auto;
}
.crw-stacked-card {
background: var(--card-bg);
border-radius: 12px;
box-shadow: 0 4px 15px var(--shadow-color);
border: 1px solid rgba(0,0,0,0.02);
transition: transform 0.3s ease, box-shadow 0.3s ease;
display: flex;
flex-direction: column;
width: 100%;
margin-bottom: 20px;
overflow: hidden;
}
.crw-stacked-card:hover {
transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(0,0,0,0.15);
}
.crw-card-content {
display: flex;
flex-direction: row;
width: 100%;
min-height: 140px;
}
.crw-col-left {
flex: 0 0 30%;
background-color: transparent;
padding: 25px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-right: 1px solid rgba(0,0,0,0.08);
}
.crw-quote-icon {
margin-bottom: 15px;
}
.crw-quote-icon svg {
width: 32px;
height: 32px;
fill: var(--brand-color);
opacity: 1;
}
.crw-card-header {
text-align: center;
width: 100%;
}
.crw-name {
font-size: 1.1em;
font-weight: 700;
color: var(--text-main);
margin-bottom: 4px;
text-transform: capitalize;
line-height: 1.2;
}
.crw-company {
font-size: 0.9em;
font-weight: 600;
color: var(--text-muted);
margin-bottom: 4px;
text-transform: none;
line-height: 1.2;
}
.crw-date {
font-size: 0.75em;
color: #aaaaaa;
margin-top: 8px;
}
.crw-col-right {
flex: 1;
padding: 25px 30px;
display: flex;
flex-direction: column;
justify-content: center;
}
.crw-comment-text {
font-size: 1em;
line-height: 1.6;
color: #555;
font-style: italic;
display: -webkit-box;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
overflow: hidden;
max-height: 7em;
transition: max-height 0.5s ease;
}
.crw-comment-text.expanded {
-webkit-line-clamp: unset;
max-height: 2000px;
overflow: visible;
}
.crw-read-more-btn {
display: none;
font-size: 24px;
color: var(--brand-color);
cursor: pointer;
margin-top: 10px;
line-height: 1;
font-weight: bold;
align-self: center;
animation: bounce 2s infinite;
}
.crw-read-more-btn:hover {
transform: scale(1.2);
}
@keyframes bounce {
0%, 20%, 50%, 80%, 100% {transform: translateY(0);}
40% {transform: translateY(5px);}
60% {transform: translateY(3px);}
}
.crw-powered-by {
text-align: center;
margin-top: 20px;
font-size: 10px;
color: #ccc;
width: 100%;
}
.crw-powered-by a { text-decoration: none; color: inherit; display: flex; align-items: center; justify-content: center; }
.crw-powered-by img { height: 16px; margin-left: 5px; opacity: 0.6; }
.crw-empty-message { text-align: center; padding: 40px; color: #777; font-style: italic; }
@media (max-width: 600px) {
.crw-card-content {
flex-direction: column;
}
.crw-col-left {
flex: 0 0 auto;
border-right: none;
border-bottom: 1px solid rgba(0,0,0,0.08);
width: 100%;
padding: 20px;
}
.crw-col-right {
padding: 20px;
}
}
</style>
<script>
(function() {
var widgetContainer = document.getElementById('crw-stacked-widget');
if (!widgetContainer) return;
window.toggleStackExpand = function(elementId, btn) {
var el = document.getElementById(elementId);
if (el.classList.contains('expanded')) {
el.classList.remove('expanded');
btn.innerHTML = '⌄';
} else {
el.classList.add('expanded');
btn.innerHTML = '⌃';
}
};
function checkStackTextLength() {
var comments = widgetContainer.getElementsByClassName('crw-comment-text');
for (var i = 0; i < comments.length; i++) {
if (comments[i].scrollHeight > comments[i].clientHeight) {
var btn = comments[i].parentNode.querySelector('.crw-read-more-btn');
if (btn) btn.style.display = 'block';
}
}
}
setTimeout(function() { checkStackTextLength(); }, 100);
window.addEventListener('resize', checkStackTextLength);
})();
</script>
CSS
▶ Click to expand CSS code
:root {
--brand-color: #fca311;
--card-bg: #ffffff;
--text-main: #333333;
--text-muted: #777777;
--shadow-color: rgba(0,0,0,0.1);
}
Example 4: Grid
Preview
HTML
▶ Click to expand HTML code
<div class="crw-theme-color crw-tst-modern-grid" id="crw-grid-widget">
<% if (!surveys.length) { %>
<div class="crw-empty-message">
No testimonials at this moment.
</div>
<% } else { %>
<div class="crw-grid-container">
<% _.each(surveys, function(survey) { %>
<div class="crw-grid-card">
<div class="crw-card-content">
<div class="crw-quote-icon">
<svg viewBox="0 0 512 512">
<path d="M464 256h-80v-64c0-35.3 28.7-64 64-64h8c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24h-8c-88.4 0-160 71.6-160 160v240c0 26.5 21.5 48 48 48h128c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48zm-288 0H96v-64c0-35.3 28.7-64 64-64h8c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24h-8C71.6 32 0 103.6 0 192v240c0 26.5 21.5 48 48 48h128c26.5 0 48-21.5 48-48V304c0-26.5-21.5-48-48-48z"/>
</svg>
</div>
<div class="crw-card-header">
<div class="crw-name"><%= survey.customer_data.contact_anon_name %></div>
<% if (survey.customer_data.customer_name) { %>
<div class="crw-company"><%= survey.customer_data.customer_name %></div>
<% } %>
<div class="crw-date"><%= moment(survey.closed).format('MM/DD/YYYY') %></div>
</div>
<div class="crw-card-body">
<div class="crw-comment-scroll-area">
<%= survey.comment %>
</div>
</div>
</div>
</div>
<% }); %>
</div>
<div class="crw-powered-by">
<a href="https://www.crewhu.com" target="_blank">Powered by <img src="https://cdn2.hubspot.net/hubfs/445399/crewhu_images/image.png" alt="Crewhu"></a>
</div>
<% } %>
</div>
<style>
<%= cssTemplate %>
</style>
<style>
.crw-tst-modern-grid {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 20px 10px;
box-sizing: border-box;
background-color: transparent;
}
.crw-tst-modern-grid * {
box-sizing: border-box;
}
.crw-grid-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 30px;
width: 100%;
align-items: start;
}
.crw-grid-card {
background: var(--card-bg);
border-radius: 12px;
box-shadow: 0 4px 15px var(--shadow-color);
border: 1px solid rgba(0,0,0,0.02);
transition: transform 0.3s ease, box-shadow 0.3s ease;
display: flex;
flex-direction: column;
height: 320px;
overflow: hidden;
}
.crw-grid-card:hover {
transform: translateY(-7px);
box-shadow: 0 12px 30px rgba(0,0,0,0.15);
}
.crw-card-content {
padding: 30px 25px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
height: 100%;
width: 100%;
}
.crw-quote-icon {
margin-bottom: 10px;
flex-shrink: 0;
}
.crw-quote-icon svg {
width: 36px;
height: 36px;
fill: var(--brand-color);
opacity: 0.8;
}
.crw-card-header {
margin-bottom: 15px;
width: 100%;
flex-shrink: 0;
display: flex;
flex-direction: column;
justify-content: center;
min-height: 70px;
}
.crw-name {
font-size: 1.2em;
font-weight: 700;
color: var(--text-main);
margin-bottom: 4px;
text-transform: capitalize;
line-height: 1.2;
}
.crw-company {
font-size: 0.9em;
font-weight: 600;
color: var(--text-muted);
margin-bottom: 4px;
text-transform: none;
line-height: 1.2;
}
.crw-date {
font-size: 0.75em;
color: #aaaaaa;
margin-top: 4px;
}
.crw-card-body {
width: 100%;
position: relative;
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
.crw-comment-scroll-area {
font-size: 0.95em;
line-height: 1.5;
color: #555;
font-style: italic;
height: 100%;
overflow-y: auto;
padding-right: 5px;
scrollbar-width: thin;
scrollbar-color: var(--brand-color) #f0f0f0;
}
.crw-comment-scroll-area::-webkit-scrollbar {
width: 4px;
}
.crw-comment-scroll-area::-webkit-scrollbar-track {
background: #f0f0f0;
border-radius: 4px;
}
.crw-comment-scroll-area::-webkit-scrollbar-thumb {
background-color: var(--brand-color);
border-radius: 4px;
}
.crw-powered-by {
text-align: center;
margin-top: 40px;
font-size: 10px;
color: #ccc;
width: 100%;
}
.crw-powered-by a { text-decoration: none; color: inherit; display: flex; align-items: center; justify-content: center; }
.crw-powered-by img { height: 16px; margin-left: 5px; opacity: 0.6; }
.crw-empty-message { text-align: center; padding: 40px; color: #777; font-style: italic; }
@media (max-width: 600px) {
.crw-grid-container {
gap: 20px;
}
}
</style>
CSS
▶ Click to expand CSS code
:root {
--brand-color: #fca311;
--card-bg: #ffffff;
--text-main: #333333;
--text-muted: #777777;
--shadow-color: rgba(0,0,0,0.1);
}
Final Notes
These examples are meant to serve as starting points. You can customize them to match your website’s design, layout, and branding!
If you need to adapt the code, consider using AI tools to:
- Adjust spacing, fonts, or colors
- Convert the layout to match your website framework
- Add animations or transitions
- Improve responsiveness for mobile devices
These templates are provided as examples. If you modify the HTML or CSS, please do so carefully, as changes to links or code structure may cause the widget to stop working properly. Because these examples may be customized for different environments, we’re unable to provide support for issues caused by code modifications.
Comments
0 comments
Please sign in to leave a comment.