Upul Tharanga top-scored with 83 as Sri Lanka sought to rebuild their innings after losing their big hitters on the third day of the first Test against South Africa on Friday.
Tharanga, making a Test comeback after more than six years, stood out with his sparkling 155-ball innings that contained 14 fours and a six.
At tea, Sri Lanka were 182-4 with skipper Angelo Mathews batting on 24 and Lahiru Thirimanne on 32.
The hosts trail the visitors by 273 runs with six wickets in hand, South Africa having declared their first innings at 455-9.
Tharanga, 29, defied the hostile fast bowling and looked set for his second Test century. But he was undone by part-time spinner Jean-Paul Duminy who had him stumped by wicketkeeper Quinton de Kock.
Thirimanne and Mathews then got together to repair the damage, having put on 46 runs so far for the fifth wicket.
Thirimanne looked solid, especially against the spinners, hitting Imran Tahir for two fours on the trot.
Earlier, Dale Steyn got rid of opener Kaushal Silva and star batsman Mahela Jayawardene (three) while Morne Morkel sent back run-machine Kumar Sangakkara (24).
Silva tried to hook a bouncer from Steyn but edged it to long leg where Vernon Philander dived forward and plucked the ball inches off the ground to complete a spectacular catch.
His dismissal brought in Sangakkara, coming into the match on the back of a record seven successive fifty-plus scores.
The left-hander looked his normal poised self, pulling and driving Steyn for two fours in an over, which included his trademark cover drive.
Tharanga provided solid support to his more famous partner, reaching his fourth half-century with a four off Duminy.
Tharanga dished out similar treatment to Tahir, the only specialist spinner in the South African squad, whacking him around for two boundaries is his consecutive overs.
Sudden rain close to the lunch break held up the game briefly. And just as the match resumed, Sangakkara paid the price for losing his concentration, inside edging Morkel on to his stumps.
Jayawardene, who has announced that he will retire in August, was trapped leg before by Steyn while trying to defend against a stinging yorker from the bowler.
The former skipper asked for a review but replays validated the on-field umpire's call.