It was their second successive win in Paris and means they are still in the mix for overall Six Nations glory, despite having lost to England in their opening match.
"We have a good record against France," Wales coach Warren Gatland told the BBC. "I thought the forwards were sensational. We scrummaged well, the line-out was good and I thought we deserved to win.
"The next game is massive against Ireland at home and hopefully we will play Italy on the final day with the championship alive."
For France, who were loudly jeered at the final whistle, it was yet another disappointing performance and leaves their Six Nations hopes in tatters after a second straight loss.
They will do well to beat last year's fourth-placed finish at this rate, particularly with trips to Rome and Twickenham to come.
Gatland had restored George North to his starting line-up but it veryn quickly became clear that Jamie Roberts was the key man for the visitors.
With France coach Philippe Saint-Andre leaving Mathieu Bastareaud on the bench, Wales targeted the midfield with Roberts crashing over the gain line time and again.
Wales went in front from a Leigh Halfpenny penalty after Romain Taofifenua was pinged for going to ground at the breakdown.
France responded with some long-forgotten flair but Yoann Huget couldn't control Camille Lopez's cross-kick.
Remi Lamerat went off with a hamstring problem and the barrel-chested Bastareaud joined the fray after just 18 minutes, just as Lopez kicked France level after Wales went offside.
Lopez missed a long-range penalty and Halfpenny restored Wales's lead after France were penalised for not releasing after a tackle.
That seemed to spark France into life, though, and a miss-pass from Lopez put Huget in space on the wing, the Toulouse man cutting inside Halfpenny's tackle to dive over.
The crowd went wild but South African referee Jaco Peyper had spotted the pass was forward and the try was rightly refused.
France should have gone into half-time level but Lopez badly missed a very kickable penalty.
In an uninspiring first half, France had made 77 tackles to Wales's 22 yet still came far closer to scoring a try.
France changed kicker at the start of then second half but Morgan Parra fared no better, missing his first penalty attempt.
Wesley Fofana made a scything break down the left to take France deep inside the Welsh 22 but they couldn't maintain the pressure as Guilhem Guirado was penalized for providing a screen for Bastareaud.
France were starting to find some self-confidence, though, and Brice Dulin was just a fraction off collecting a Lopez chip inside the Wales 22.
The pressure paid off and with kicking duties restored to him, Lopez notched a penalty from right in front of the posts.
Curiously, Saint-Andre picked that moment to make a raft of substitutions and France lost their momentum.
Within minutes Wales were back in front as Halfpenny kicked his third penalty.
The tide seemed to have turned and Dan Biggar was unlucky to hit the post with a drop-goal attempt as Wales camped in French territory.
They made their pressure count, though, as Rhys Webb sold a dummy to Taofifenua before Dan Lydiate's delightful no-look offload allowed Biggar to sprint into the corner.
Although Halfpenny missed the extras, he then landed a penalty as Wales stretched their lead out to 17-6.
But, after 10 minutes of total Welsh domination, France did manage to get back on the front foot and Dulin slid over in the corner with Lopez landing the difficult conversion from right out on the touchline.
Yet almost immediately, the hosts gave Wales a kickable penalty and Halfpenny didn't miss, leaving the visitors 20-13 ahead with seven minutes left.
They had one last chance after kicking a penalty to the corner but with space out wide, Dulin cut inside into traffic and Wales smothered any chance France had a snatching a late draw.