Ivan Perisic was the tournament's latest last-gasp hero, marking his 50th cap with a virtuoso performance and an 87th-minute winner that means double-defending champion Spain will play Italy in the next round, having fallen to its first defeat in this tournament since a 1-0 reverse to Portugal at Euro 2004.
Both sides knew they would go through before kick-off, and the lack of tension made for an entertaining contest.
Alvaro Morata's return to Real Madrid had been confirmed earlier on Wednesday (AEST) and the striker opened the scoring after just seven minutes, but Nikola Kalinic netted the first goal Vicente del Bosque's side had conceded in 735 minutes of European Championship action to level the scores before half-time.
Spain captain Sergio Ramos - who became his country's most-capped outfield player on his 134th appearance - had a second-half penalty saved, but the defending champion rarely looked anywhere near its best and Perisic scored a breathtaking goal in the closing stages.
A heavy police presence among Croatia fans also thwarted any potential trouble, with officials claiming pre-match that referee Bjorn Kuipers could be under threat as protests against the country's football federation rumble on.
Croatia was assured of its place in the last 16 as a result of Northern Ireland losing 1-0 to Germany, and a side showing five changes were quickly shredded by a fit, firing and unaltered Spain attack.
David Silva was at the heart of the move, threading a perfect reverse ball into Cesc Fabregas, who dinked the ball over Danijel Subasic and into the path of Morata for an easy finish.
Spain's response to the goal was sloppy, however, and Kalinic pounced on an error from Ramos to force a save from David de Gea.
Clumsy play soon after from De Gea gave Ivan Rakitic a sight of goal, but the Barcelona midfielder's chip somehow stayed out via a combination of the crossbar, post and a backtracking Gerard Pique.
The 30th minute had been anticipated to see a disruption from Croatia fans, who were consequently much more heavily stewarded than Spain's support, but the half passed without any concerns.
A shock equaliser came just before the interval as Perisic turned Juanfran inside out on the left flank before crossing for Kalinic to finish with an improvised flick with the outside of his right boot.
Spain's errors spilled into the second half too, Marko Pjaca sending an overhead kick wide after De Gea had flapped at a Darijo Srna cross.
With the likes of Perisic and Rakitic increasingly influential, Pjaca saw a penalty appeal turned down but Kuipers did point to the spot at the other end as Silva tumbled under Sime Vrsaljko's tackle.
Ramos was thwarted from 12 yards, although Subasic was farcically a good three yards off his line as he saved to his right.
Croatia's winner came from a thrilling counter-attack, as Rakitic fed Kalinic, who held the ball up long enough for Perisic to take command on the left flank, charging towards goal before smashing a shot past De Gea via a slight deflection.
The victory sets up a mouthwatering repeat of the 2012 final between Spain and Italy, with Del Bosque's side having triumphed 4-0 in Kiev four years ago.