Signature Library · Indian
Horn OK Please
The painted back of a lorry, fringe and all; press it and it honks.
States
Default
Hover
Active
Focus
Code
horn-ok-please.html
<button class="sig-horn-ok-please" type="button"> <span class="sig-horn-ok-please__wave" aria-hidden="true"></span> <span class="sig-horn-ok-please__top">Use dipper at night</span> <span class="sig-horn-ok-please__main">Horn OK Please</span> <span class="sig-horn-ok-please__low">Sound horn</span> <span class="sig-horn-ok-please__fringe" aria-hidden="true"></span> </button>
horn-ok-please.css
.sig-horn-ok-please {
--sig-paint: #ffc21a;
--sig-text: #21306e;
--sig-trim: #e8541e;
--sig-w: 270px;
}
.sig-horn-ok-please {
position: relative;
box-sizing: border-box;
display: grid;
justify-items: center;
gap: 2px;
width: var(--sig-w);
max-width: 100%;
padding: 12px 12px 26px;
font-family: Georgia, 'Times New Roman', serif;
color: var(--sig-text);
background: repeating-linear-gradient(90deg, var(--sig-trim) 0 14px, #2f8f46 14px 28px) 0 0 / 100% 7px no-repeat, linear-gradient(180deg, var(--sig-paint) 60%, color-mix(in srgb, var(--sig-paint) 78%, #c8102e));
border: 3px solid #21306e;
border-radius: 6px;
cursor: pointer;
}
.sig-horn-ok-please:focus-visible {
outline: 2px solid var(--sig-paint);
outline-offset: 3px;
}
.sig-horn-ok-please[data-state=honk] {
animation: sig-rattle 180ms steps(4) 3;
--blast: sig-blast 540ms ease-out;
}
.sig-horn-ok-please__wave {
position: absolute;
inset: -3px;
border: 3px solid var(--sig-paint);
border-radius: 10px;
opacity: 0;
animation: var(--blast, none);
pointer-events: none;
}
.sig-horn-ok-please__top {
font-size: 11px;
font-style: italic;
letter-spacing: 0.12em;
}
.sig-horn-ok-please__main {
font-size: 23px;
font-weight: 900;
line-height: 1.05;
text-align: center;
text-transform: uppercase;
letter-spacing: 0.03em;
color: #c8102e;
text-shadow: 1.5px 1.5px 0 #21306e, 3px 3px 0 #fff;
white-space: nowrap;
}
.sig-horn-ok-please__low {
font-size: 11px;
font-weight: 700;
}
.sig-horn-ok-please__fringe {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 16px;
background: repeating-linear-gradient(90deg, #c8102e 0 5px, #21306e 5px 10px, var(--sig-trim) 10px 15px);
clip-path: polygon(0 0, 100% 0, 100% 40%, 95% 100%, 90% 40%, 85% 100%, 80% 40%, 75% 100%, 70% 40%, 65% 100%, 60% 40%, 55% 100%, 50% 40%, 45% 100%, 40% 40%, 35% 100%, 30% 40%, 25% 100%, 20% 40%, 15% 100%, 10% 40%, 5% 100%, 0 40%);
}
@keyframes sig-rattle {
25% { transform: translate(-1px, 1px); }
50% { transform: translate(1px, -1px); }
75% { transform: translate(-1px, -1px); }
}
@keyframes sig-blast {
0% { opacity: 0.8; transform: scale(1); }
100% { opacity: 0; transform: scale(1.14, 1.3); }
}
@media (prefers-reduced-motion: reduce) {
.sig-horn-ok-please,
.sig-horn-ok-please__wave {
animation: none !important;
transition: none !important;
}
}
horn-ok-please.js
document.querySelectorAll(".sig-horn-ok-please").forEach((el) => {
const go = () => {
el.removeAttribute("data-state");
void el.offsetWidth;
el.dataset.state = "honk";
};
const rest = (e) => {
if (e.target === el) el.removeAttribute("data-state");
};
el.addEventListener("click", go);
el.addEventListener("animationend", rest);
return () => {
el.removeEventListener("click", go);
el.removeEventListener("animationend", rest);
};
});
horn-ok-please.tsx
import { useEffect, useRef } from "react";
import type React from "react";
import "./horn-ok-please.css"; // the CSS tab
function attach(el: HTMLElement) {
const go = () => {
el.removeAttribute("data-state");
void el.offsetWidth;
el.dataset.state = "honk";
};
const rest = (e: Event) => {
if (e.target === el) el.removeAttribute("data-state");
};
el.addEventListener("click", go);
el.addEventListener("animationend", rest);
return () => {
el.removeEventListener("click", go);
el.removeEventListener("animationend", rest);
};
}
export function SigHornOkPlease({ children = "Horn OK Please", ...props }: React.ComponentProps<"button">) {
const ref = useRef<HTMLButtonElement>(null);
useEffect(() => attach(ref.current!), []);
return (
<button className="sig-horn-ok-please" type="button" ref={ref} {...props}>
<span className="sig-horn-ok-please__wave" aria-hidden="true" />
<span className="sig-horn-ok-please__top">{"Use dipper at night"}</span>
<span className="sig-horn-ok-please__main">{children}</span>
<span className="sig-horn-ok-please__low">{"Sound horn"}</span>
<span className="sig-horn-ok-please__fringe" aria-hidden="true" />
</button>
);
}
horn-ok-please.html
<button class="sig-horn-ok-please relative [box-sizing:border-box] grid [justify-items:center] gap-[2px] w-[270px] [max-width:100%] [padding:12px_12px_26px] [font-family:Georgia,_'Times_New_Roman',_serif] text-[#21306e] [background:repeating-linear-gradient(90deg,_#e8541e_0_14px,_#2f8f46_14px_28px)_0_0_/_100%_7px_no-repeat,_linear-gradient(180deg,_#ffc21a_60%,_color-mix(in_srgb,_#ffc21a_78%,_#c8102e))] [border:3px_solid_#21306e] rounded-[6px] cursor-pointer focus-visible:[outline:2px_solid_#ffc21a] focus-visible:[outline-offset:3px] [&[data-state=honk]]:[animation:sig-rattle_180ms_steps(4)_3] [&[data-state=honk]]:[--blast:sig-blast_540ms_ease-out] motion-reduce:[animation:none!important]" type="button">
<span class="absolute [inset:-3px] [border:3px_solid_#ffc21a] rounded-[10px] [opacity:0] [animation:var(--blast,_none)] [pointer-events:none] motion-reduce:[animation:none!important]" aria-hidden="true"></span>
<span class="text-[11px] [font-style:italic] [letter-spacing:0.12em]">Use dipper at night</span>
<span class="text-[23px] font-[900] [line-height:1.05] [text-align:center] [text-transform:uppercase] [letter-spacing:0.03em] text-[#c8102e] [text-shadow:1.5px_1.5px_0_#21306e,_3px_3px_0_#fff] whitespace-nowrap">Horn OK Please</span>
<span class="text-[11px] font-[700]">Sound horn</span>
<span class="absolute [left:0] [right:0] [bottom:0] h-[16px] [background:repeating-linear-gradient(90deg,_#c8102e_0_5px,_#21306e_5px_10px,_#e8541e_10px_15px)] [clip-path:polygon(0_0,_100%_0,_100%_40%,_95%_100%,_90%_40%,_85%_100%,_80%_40%,_75%_100%,_70%_40%,_65%_100%,_60%_40%,_55%_100%,_50%_40%,_45%_100%,_40%_40%,_35%_100%,_30%_40%,_25%_100%,_20%_40%,_15%_100%,_10%_40%,_5%_100%,_0_40%)]" aria-hidden="true"></span>
</button>
<!-- A class cannot hold keyframes: keep this in your CSS. -->
<style>
@keyframes sig-rattle {
25% { transform: translate(-1px, 1px); }
50% { transform: translate(1px, -1px); }
75% { transform: translate(-1px, -1px); }
}
@keyframes sig-blast {
0% { opacity: 0.8; transform: scale(1); }
100% { opacity: 0; transform: scale(1.14, 1.3); }
}
</style>
<!-- Needs the script from the JS tab. -->