Denmark made a dream start, taking the lead through Mathias Jorgensen, who scrambled home a loose ball amidst a body of defenders after just 58 seconds.
The Croatians levelled almost instantly though after a cross from Sime Vrsjalko inadvertently fell to Mario Mandzukic, who made no mistake with a half-volley into the bottom corner.
The Danes surged to grab a second, but a sneaky Martin Braithwaite was unable to pounce on a through ball.
At the other end, the Blazers struggled to break down the opposing defence, forcing Ivan Rakitic to long-range efforts, while Ivan Perisic and Ante Rebic failed to profit from poor goalkeeping.
It was the Danes who threw bodies forward hoping to snatch the win after the break, introducing striker Nicolai Jorgensen at half-time.
The Feyenoord marksman showed instant quality and steel, getting in good positions but, despite that, he was unable to beat goalkeeper Danijel Subasic from close parameters.
With six minutes to go, Perisic took responsibility to get on the end of a free-kick but headed wide after a set-piece as the game eventually entered extra-time.
After a lively extended period, a penalty was awarded to Croatia after Ante Rebic’s path to scoring into an empty net was halted by Mathias Jorgensen, who only received a yellow card.
However, captain Luka Modric was unable to add to his tally at the tournament, as Schmeichel saved the spot-kick to force a penalty shootout.
Three saves from Subasic helped the Croatians clinch the win, as Rakitic converted the decisive spot-kick for a 3-2 triumph and the right to face Russia in the quarter-finals.
Croatia XI: Subasic; Vrsaljko, Vida, Lovren, Strinic; Brozovic, Rakitic; Rebic, Modric, Perisic; Mandzukic.
Denmark XI: Schmeichel; Dalsgaard, Zanka, Kjaer, Christensen; Braithwaite, Knudsen, Delaney, Eriksen; Poulsen, Cornelius.