The home side had 69 per cent of the ball and created eight chances on goal, while Roma created five.
Lazio went close in the 5th minute thanks to a Luis Alberto effort from 40 yards out that went just over the crossbar, but had Rui Patricio scrambling.
Zaccagni went close in the 29th minute from outside the box, but hit it too close to the keeper.
Things were made difficult for Roma in the 32nd minute when Ibanez was given a second yellow card.
His poor touch that went straight to Milinkovic-Savic needed to be corrected with a foul on the Serbian international in order to prevent a Lazio counterattack.
Despite being a man down, Roma went into the break level.
A thunderbolt distance strike from Luis Alberto at the start of the second half was tipped over the bar by Patricio.
The breakthrough goal came in the 65th minute as Zaccagni got on the end of a Felipe Anderson flick-on to score at Patricio’s far post.
Roma thought they had equalised two minutes later, but VAR ruled the goal offside.
Marusic and Cristante were both given red cards for violent conduct after the final whistle.
Lazio move up to second on the table, while Roma are 5th, one point off a Champions League spot.