Selenium ElementClickInterceptedException (tested)
Selenium raises ElementClickInterceptedException: element click intercepted ... Other element would receive the click when another element (a cookie banner, a loading overlay, a fixed header) sits on top of the one you click. Close or wait out that element; element_to_be_clickable does not check for overlays.
Setup used in every block
common.py writes a small HTML page to a local file and starts headless Chrome. Exception messages are cut to their first line (Selenium appends the session info and a documentation link).
import os, pathlib
from selenium import webdriver
CHROME = os.path.expanduser("~/.cache/ms-playwright/chromium-1248/chrome-linux64/chrome")
def page(html):
p = pathlib.Path("/tmp/sl383/page.html"); p.write_text(html); return p.as_uri()
def driver():
o = webdriver.ChromeOptions()
o.binary_location = CHROME
o.add_argument("--headless=new"); o.add_argument("--no-sandbox"); o.add_argument("--window-size=1000,700")
return webdriver.Chrome(options=o)
1. Reproduce it: a cookie banner covers the button
from common import *
from selenium.webdriver.common.by import By
d = driver()
d.get(page('''<button id="buy" onclick="this.textContent='clicked'">Buy</button>
<div id="cookie" style="position:fixed;inset:0 0 auto 0;height:120px;background:#eee">
We use cookies <button id="ok" onclick="this.parentNode.remove()">OK</button></div>'''))
try:
d.find_element(By.ID, "buy").click()
except Exception as e:
print(type(e).__name__ + ":")
print(e.msg.splitlines()[0])
d.quit()
Output:
ElementClickInterceptedException:
element click intercepted: Element <button id="buy" onclick="this.textContent='clicked'">...</button> is not clickable at point (27, 18). Other element would receive the click: <div id="cookie" style="position:fixed;inset:0 0 auto 0;height:120px;background:#eee">...</div>
click() clicks at the centre of the element, like a real user. Chrome checks which element is on top at that point, and if it is a different one it raises ElementClickInterceptedException. The message tells you both the point and the culprit: Other element would receive the click: <div id="cookie" ...>. Read that element first; it says which of the fixes below you need.
2. Fix: close the overlay the way a user would
from common import *
from selenium.webdriver.common.by import By
d = driver()
d.get(page('''<button id="buy" onclick="this.textContent='clicked'">Buy</button>
<div id="cookie" style="position:fixed;inset:0 0 auto 0;height:120px;background:#eee">
We use cookies <button id="ok" onclick="this.parentNode.remove()">OK</button></div>'''))
d.find_element(By.ID, "ok").click()
d.find_element(By.ID, "buy").click()
print("after dismissing the banner:", d.find_element(By.ID, "buy").text)
d.quit()
Output:
after dismissing the banner: clicked
For cookie banners, chat widgets and modals, click their close or accept button first.
3. Fix: wait for a loading overlay to disappear
from common import *
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
d = driver()
d.get(page('''<button id="buy" onclick="this.textContent='clicked'">Buy</button>
<div id="spinner" style="position:fixed;inset:0;background:rgba(0,0,0,.3)"></div>
<script>setTimeout(() => document.getElementById("spinner").remove(), 1500)</script>'''))
el = WebDriverWait(d, 5).until(EC.element_to_be_clickable((By.ID, "buy")))
print("element_to_be_clickable returned:", el.text)
try:
el.click()
except Exception as e:
print("click:", type(e).__name__)
WebDriverWait(d, 5).until(EC.invisibility_of_element_located((By.ID, "spinner")))
el.click()
print("after invisibility wait:", el.text)
d.quit()
Output:
element_to_be_clickable returned: Buy
click: ElementClickInterceptedException
after invisibility wait: clicked
Note the trap: EC.element_to_be_clickable returned the button while the spinner still covered it, and the click failed. That condition only checks that the element is displayed and enabled, not that nothing is on top of it. Wait for the overlay itself with EC.invisibility_of_element_located (it also succeeds when the element is removed from the DOM).
4. Fix: a fixed header covers the element after scrolling
from common import *
from selenium.webdriver.common.by import By
d = driver()
d.get(page('''<header style="position:fixed;top:0;left:0;right:0;height:80px;background:#ccc">Header</header>
<div style="height:2000px"></div>
<button id="buy" onclick="this.textContent='clicked'">Buy</button>
<div style="height:2000px"></div>'''))
el = d.find_element(By.ID, "buy")
d.execute_script("arguments[0].scrollIntoView(true)", el)
print("top after scrollIntoView(true):", d.execute_script("return arguments[0].getBoundingClientRect().top", el))
try:
el.click()
except Exception as e:
print("click:", type(e).__name__, "->", e.msg.split("Other element would receive the click: ")[1].split(">")[0] + ">")
d.execute_script("arguments[0].scrollIntoView({block: 'center'})", el)
el.click()
print("after scrollIntoView center:", el.text)
d.quit()
Output:
top after scrollIntoView(true): 0
click: ElementClickInterceptedException -> <header style="position:fixed;top:0;left:0;right:0;height:80px;background:#ccc">
after scrollIntoView center: clicked
scrollIntoView(true) puts the element at the very top of the viewport (top: 0), exactly under the fixed 80px header, so the header gets the click. Scrolling with {block: 'center'} moves it clear. Without our explicit scrollIntoView(true), the same click() succeeded in our test: chromedriver scrolls the element into view by itself. So if your code scrolls before clicking, check where it scrolls to.
5. ActionChains and JavaScript click are not fixes
from common import *
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
html = '''<button id="buy" onclick="this.textContent='clicked'">Buy</button>
<div id="cookie" onclick="this.dataset.hits=(+this.dataset.hits||0)+1"
style="position:fixed;inset:0 0 auto 0;height:120px;background:#eee">cookies</div>'''
d = driver()
d.get(page(html))
ActionChains(d).move_to_element(d.find_element(By.ID, "buy")).click().perform()
print("ActionChains: no exception; button text:", d.find_element(By.ID, "buy").text,
"| overlay clicks:", d.find_element(By.ID, "cookie").get_attribute("data-hits"))
d.get(page(html))
d.execute_script("arguments[0].click()", d.find_element(By.ID, "buy"))
print("JS click: button text:", d.find_element(By.ID, "buy").text)
d.quit()
Output:
ActionChains: no exception; button text: Buy | overlay clicks: 1
JS click: button text: clicked
ActionChains(...).click() raised nothing, but the click landed on the overlay: the button was not clicked and the banner registered one hit. The test carries on in the wrong state and fails later somewhere confusing. execute_script("arguments[0].click()", el) does click the button, through the overlay, which a real user could not do, so the test stops testing what users see. Use it only when the overlay is something you deliberately do not care about.
6. Checklist
- Read "Other element would receive the click" to see what is on top.
- Banner or modal: click its close button. Spinner:
EC.invisibility_of_element_located. - Fixed header or footer: scroll with
scrollIntoView({block: 'center'}). - Headless Chrome 156 started with a 780x580 window (viewport 780x380) in our test without
--window-size; small viewports trigger mobile layouts and overlap, so set--window-sizeexplicitly.
Related: Selenium element not interactable.
Frequently asked questions
What does element click intercepted mean in Selenium?
Another element covers the centre of the element you clicked, so Chrome would deliver the click to it. The error message names that other element.
Why does element_to_be_clickable not prevent ElementClickInterceptedException?
It only checks that the element is displayed and enabled, not whether an overlay covers it. Wait for the overlay with invisibility_of_element_located instead.
Written with AI assistance. Measured on 2026-10-23 with Selenium 4.51.0 (Python 3.13.5) and headless Chrome for Testing 156.0.8078.4. Each block was run verbatim and the output pasted unedited. PlainHeaders is our extension; Python, Selenium and Chrome are free.