Sri Lanka were 60 for three at the close at St George’s Park after bowling out South Africa for 222.
Earlier, Vishwa Fernando and Kasun Rajitha both took three wickets as Sri Lanka followed up their surprise win in the first Test in Durban with a disciplined bowling performance on a slow but well-grassed pitch.
Some of their good work was undone after Dimuth Karunaratne and Lahiru Thirimanne gave the Sri Lankan innings a reasonable start, putting on 25 for the first wicket.
Captain Karunaratne was caught behind off Kagiso Rabada for 17 in the 12th over. Duanne Olivier then bowled Oshada Fernando and had Kusal Mendis caught behind.
South Africa, needing a win to share the series, made a poor start after winning the toss, losing three wickets with the total on 15, two of them off successive balls from Vishwa Fernando.
They never recovered fully despite three half-century stands, two of which involved top-scorer Quinton de Kock, who made 86.
Aiden Markram and captain Faf du Plessis put on 58 for the fourth wicket but it was 73 for four when captain Du Plessis was bowled by opposite number, part-time bowler Karunaratne, with the last ball before lunch.
The hosts seemed to be recovering when Markram and De Kock put on 57 at almost a run a ball for the fifth wicket before Kasun Rajitha took three wickets in successive overs.
Markram was leg before wicket for 60 and Rajitha followed up with the wickets of new cap Wiaan Mulder for nine and Keshav Maharaj for nought.
The left-handed De Kock went to his third half-century of the series off 51 balls but was dropped on 55 when Dhananjaya de Silva could not hold a high chance at gully off Rajitha.
De Kock and Rabada added 59 for the eighth wicket before De Kock, who was suffering from cramp, was bowled by off-spinner Dhananjaya de Silva, who then had Rabada caught behind before Vishwa Fernando finished off the innings by having Olivier caught behind.
Sri Lankan left-arm spinner Lasith Embuldeniya injured his left thumb trying to take a sharp return catch from Rabada shortly before tea and did not return to the field.
De Kock made his 86 off 87 balls with 12 fours. He was clearly struggling from soon after reaching his half-century and needed treatment on the field. There was concern that he might have aggravated a groin injury which kept him out of a recent Twenty20 series against Pakistan but he kept wicket without any apparent discomfort and a team spokesman said he had been treated for cramp. AFP