Sri Lanka hit back with the ball but the tourists face a major battle to avoid a series whitewash after South Africa took four wickets before bad light cut short day two of the third Test at The Wanderers.
Hashim Amla (134) added just nine runs on Friday after making a century in his 100th Test on day one as the Proteas collapsed to 426 all out, having resumed on 338-3.
Nuwan Pradeep (4-78) and teenager Lahiru Kumara (4-107) inspired the fightback, but Sri Lanka were reduced to 80-4 in reply when stumps were prematurely drawn in Johannesburg.
Kusal Mendis (41) got a start, but was one of two batsman to be dismissed by Kagiso Rabada (2-26) and Vernon Philander (2-23) struck twice to leave Sri Lanka trailing by 346 and facing the prospect of following on.
Sri Lanka endured a gruelling first day in the field and were clearly in no mood for another, with captain Angelo Mathews rewarded for a probing opening spell when debutant and nightwatchman Duanne Olivier (3) was given out caught behind following a review.
Pradeep came to the fore after that breakthrough, taking four wickets for just one run in a magnificent spell of seam bowling to turn the tide.
Faf du Plessis (16) was struck on several occasions and dropped by Mendis, who redeemed himself by hanging on when the Proteas skipper edged Pradeep to second slip for a second time.
Pradeep snared Temba Bavuma caught behind without scoring to a fine catch from Kaushal Silva and ended Amla's magnificent 265-ball knock, which included 16 boundaries, as the procession of South Africa wickets continued.
Philander was also dismissed for a duck, but Quinton de Kock (34) and Wayne Parnell (23) held Sri Lanka up with a stand of 47 for the ninth wicket before Kumara claimed the last two wickets.
Sri Lanka needed a strong start to their reply in order to have any hope of making a game of it, but Dimuth Karunaratne was caught behind for a duck in the first over from Philander after already surviving a review.
Kaushal went the same way to Rabada, who also got rid of Mendis after the number three had pulled Philander for six in a promising innings.
Dhananjaya de Silva (11) became Philander's second victim before the weather prevented South Africa from doing any more damage, the covers coming on at 16:20 local time.
As a result, play will start at 10am on Saturday with 15 minutes added to the second two sessions to make up some time.