diff --git a/layout/forms/nsHTMLButtonControlFrame.cpp b/layout/forms/nsHTMLButtonControlFrame.cpp
index a8144045fe9..cfb98d945e2 100644
--- a/layout/forms/nsHTMLButtonControlFrame.cpp
+++ b/layout/forms/nsHTMLButtonControlFrame.cpp
@@ -96,6 +96,17 @@ nsHTMLButtonControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists)
{
+ // Clip to our border area for event hit testing.
+ Maybe eventClipState;
+ const bool isForEventDelivery = aBuilder->IsForEventDelivery();
+ if (isForEventDelivery) {
+ eventClipState.emplace(aBuilder);
+ nsRect rect(aBuilder->ToReferenceFrame(this), GetSize());
+ nscoord radii[8];
+ bool hasRadii = GetBorderRadii(radii);
+ eventClipState->ClipContainingBlockDescendants(rect, hasRadii ? radii : nullptr);
+ }
+
nsDisplayList onTop;
if (IsVisibleForPainting(aBuilder)) {
mRenderer.DisplayButton(aBuilder, aLists.BorderBackground(), &onTop);
@@ -104,7 +115,7 @@ nsHTMLButtonControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
nsDisplayListCollection set;
// Do not allow the child subtree to receive events.
- if (!aBuilder->IsForEventDelivery()) {
+ if (!isForEventDelivery) {
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
if (IsInput() || StyleDisplay()->mOverflowX != NS_STYLE_OVERFLOW_VISIBLE) {