Lucas Piazon's calm finish gave the visitors a deserved 1-0 half-time lead.
Fulham's Floyd Ayite capitalised on sloppy defending to feed Tom Cairney, who fired in the second.
The win lifted Slavisa Jokanovic's side to within six points of the top six, with a game in hand, while City have lost 10 of their past 13 league games.
Milan Djuric had arguably the hosts' best chance before the break, but he headed David Cotterill's dangerous cross narrowly over the crossbar.
The visitors had time on the ball early on and some neat passing fed Piazon, who delicately lifted the ball past the on-rushing Fabian Giefer for the opener.
A poor clearance from Adam Matthews then led to Fulham's second, as Cairney lashed Ayite's pass into the top corner.
Fulham, who have now won five of their past seven games in all competitions, could have added to their tally, but Kevin McDonald glanced a corner just over the bar.
Boos greeted the half-time and full-time whistles at Ashton Gate, as well as the second goal, with the Robins fans venting their frustration as they watched their side lose for a 13th time in 17 league games.
Bristol City head coach Lee Johnson told BBC Radio Bristol: "I'm obviously angry, hurting and disappointed.
"We didn't have the team energy today. I've got to find a team and a formation that gives us the talent and the energy to go and get close to people.
"I don't think some players did enough, in terms of energy. But we have to go back to the drawing board.
"I understand the fans' frustrations completely. 100%, I'm with them."
Fulham manager Slavisa Jokanovic: "We played a very good game. We won three points, we took a clean sheet and we cut the distance between us and the top teams in the Championship.
"I have to be satisfied with how my team is fighting and how they concentrated after our FA Cup exit a few days ago.
"Lucas Piazon is fighting for every ball. He has been working very hard all season and today he scored a very nice goal."
Match ends, Bristol City 0, Fulham 2.
Second Half ends, Bristol City 0, Fulham 2.
Attempt missed. Bobby Reid (Bristol City) right footed shot from outside the box is too high. Assisted by Matty Taylor.
Offside, Bristol City. Gary O'Neil tries a through ball, but Bobby Reid is caught offside.
Foul by Sone Aluko (Fulham).
Scott Golbourne (Bristol City) wins a free kick in the defensive half.
Delay over. They are ready to continue.
Delay in match Kevin McDonald (Fulham) because of an injury.
Hand ball by Matty Taylor (Bristol City).
Attempt missed. Kevin McDonald (Fulham) header from the centre of the box is just a bit too high. Assisted by Stefan Johansen with a cross following a corner.
Corner,  Fulham. Conceded by Aden Flint.
Corner,  Fulham. Conceded by Fabian Giefer.
Attempt saved. Bobby Reid (Bristol City) right footed shot from outside the box is saved in the bottom right corner. Assisted by Joe Bryan.
Tom Cairney (Fulham) wins a free kick in the defensive half.
Foul by Bailey Wright (Bristol City).
Substitution, Fulham. Sone Aluko replaces Neeskens Kebano.
Foul by Kevin McDonald (Fulham).
Bobby Reid (Bristol City) wins a free kick in the defensive half.
Tim Ream (Fulham) is shown the yellow card for a bad foul.
Foul by Tim Ream (Fulham).
Milan Djuric (Bristol City) wins a free kick on the right wing.
Substitution, Fulham. Ryan Fredericks replaces Lucas Piazon.
Neeskens Kebano (Fulham) wins a free kick in the attacking half.
Foul by Bailey Wright (Bristol City).
Attempt missed. Milan Djuric (Bristol City) left footed shot from outside the box misses to the right. Assisted by Matty Taylor with a headed pass.
Attempt missed. Stefan Johansen (Fulham) left footed shot from outside the box is just a bit too high. Assisted by Kevin McDonald.
Attempt blocked. Matty Taylor (Bristol City) right footed shot from the centre of the box is blocked. Assisted by Milan Djuric with a headed pass.
Offside, Fulham. Tom Cairney tries a through ball, but Chris Martin is caught offside.
Neeskens Kebano (Fulham) wins a free kick in the defensive half.
Foul by Bailey Wright (Bristol City).
Substitution, Bristol City. Gary O'Neil replaces Jens Hegeler.
Substitution, Fulham. Chris Martin replaces Floyd Ayité.
Jens Hegeler (Bristol City) is shown the yellow card.
Tom Cairney (Fulham) wins a free kick in the defensive half.
Foul by Jens Hegeler (Bristol City).
Corner,  Bristol City. Conceded by Kevin McDonald.
Substitution, Bristol City. Lee Tomlin replaces Adam Matthews.
Offside, Fulham. Tomas Kalas tries a through ball, but Floyd Ayité is caught offside.
Offside, Bristol City. Fabian Giefer tries a through ball, but Milan Djuric is caught offside.
Goal!  Bristol City 0, Fulham 2. Tom Cairney (Fulham) left footed shot from the left side of the box to the top right corner. Assisted by Floyd Ayité.
Fulham claimed a third Championship win in a row with a comfortable victory at Ashton Gate that left Bristol City just two points above the relegation zone.