Snell (11-9) held the Cardinals to two hits and five walks while striking out nine batters. Josh Hader sealed the victory for his 28th save.
Matt Carpenter drove in the other run for the Padres, who won for just the third time in the last nine games.
Paul Goldschmidt hit a homer for the Cardinals, who lost their fourth straight game and their 10th in 12 games. They fell 20 games under .500 for the first time since the 1995 season.
Cardinals starting pitcher Adam Wainwright (3-10) allowed one run on eight hits and three walks in six innings.
Snell escaped trouble in the first inning by inducing Nolan Arenado's double-play grounder after walking Tyler O'Neill and Goldschmidt.
With two outs in the fourth inning, Cooper hit a single and Carpenter walked before Gary Sanchez grounded into a threat-ending forceout.
Goldschmidt hit a single in the bottom of the inning and advanced on a wild pitch. Willson Contreras and Nolan Gorman drew walks to load the bases and Snell went to a 3-0 count on Andrew Knizner.
But Snell struck out Knizner and Jordan Walker to end the threat.
The Padres broke the scoreless tie in the sixth inning. Fernando Tatis Jr. and Xander Bogaerts hit singles, then Tatis took third on a flyout and scored on Carpenter's single into right field.
Bogaerts was thrown out going to third base. Sanchez hit a double, then Trent Grisham walked before He-Seong Kim hit into a forceout to end the inning.
San Diego doubled its lead to 2-0 in the seventh inning. With one out, Machado hit a single, Tatis walked, and Cooper hit a two-out RBI single.
Goldschmidt cut the lead to 2-1 with his eighth-inning homer.
But the Padres pushed their advantage to 4-1 in the ninth inning. Soto walked, Tatis hit a single, Bogaerts was hit by a pitch, and Cooper hit a two-run single.
—Field Level Media