Mbappe was adjudged to be onside when he slid the ball under Unai Simon after Karim Benzema’s stunning equaliser at Milan’s San Siro.
Spain had taken the lead through Mikel Oyarzabal, who shrugged off defender Dayot Upamecano to beat Hugo Lloris.
Lloris produced two late saves to ensure victory for the world champions.
He first denied Oyarzabal before acrobatically keeping out Yeremi Pino’s effort in stoppage time, as France became the competition’s second winners after Portugal in 2019.
But Mbappe’s winner will prove to be a moment of debate, with the goal standing even though the Paris St-Germain striker was in an offside position when Theo Hernandez played the initial through ball.
Spain defender Eric Garcia touched the ball in his attempt to clear the danger before it came to Mbappe, and the rules state “a player in an offside position receiving the ball from an opponent who deliberately plays the ball… is not considered to have gained an advantage”.
France, who reached the final by coming from 2-0 down to beat neighbours Belgium 3-2 on Thursday, had to fight back again and did so in a game that came alive after an hour of technical but sedate action.
Didier Deschamps’ side’s resilience was on full display again as Benzema cut in on his right foot to curl the ball over Simon, less than two minutes after Oyarzabal’s opener for Spain.
And even though France had less possession (36%), they constantly looked a threat on the counter-attack as Mbappe struck the decisive – and perhaps fortunate – blow.
Benzema, who returned to the international fold before Euro 2020 in the summer, told French television channel M6: “I really wanted to win a trophy with France, and now it’s done.
“We showed strength of character, because this team is very strong, never gives up and we have proven it today.
“It is the sign of a great team not to panic, to be patient and to wait for the right opportunity.”