France started strong, grabbing an early lead through a Kylian Mbappe assist headed in by Randal Kolo Muani. But Mbappe, playing without his protective mask for the first time since a broken nose, couldn't prevent Spain's comeback.
Yamal's moment of brilliance arrived in the 21st minute with a stunning curled effort from 25 yards that beat Mike Maignan and nestled in the net.
Just four minutes later, Dani Olmo's shot took a deflection off Jules Kounde, putting Spain ahead. (The goal was initially credited as an own-goal but later awarded to Olmo.)
Despite dominating possession in the second half, France failed to convert their chances. Theo Hernandez and Mbappe both missed opportunities, while Yamal nearly extended Spain's lead with another powerful strike that sailed just over the bar.
Spain will now face the winner of the England vs. Netherlands match in the Euro 2024 final on Sunday in Berlin.