Quinton de Kock's stubborn resistance provided some consolation for South Africa but Sri Lanka had the better of the opening day of the first Test.
The hosts were all out for 235 after being put into bat in Durban, where De Kock's eye-catching 80 salvaged something approaching respectability after a poor start.
Vishwa Fernando was in fine form as he took 4-62, while Kasun Rajitha (3-68) provided excellent support to help Sri Lanka establish a solid platform for success.
They had reached 49-1 in reply when bad light intervened, with captain Dimuth Karunaratne (28 not out) and Oshada Fernando (17no) steadily building a partnership after Lahiru Thirimanne had departed for a 15-ball duck.
The tourists won the toss and were quick off the mark to leave South Africa reeling as Dean Elgar was dismissed without scoring and Hashim Amla followed soon after.
Amla had already enjoyed a reprieve after umpire Aleem Dar ruled Sri Lanka had taken too long to ask for a review following an lbw appeal that replays suggested would have succeeded.
That would have left the Proteas on 0-2, although they were soon treading water after Aiden Markram's departure saw them slip to 17-3.
The hosts enjoyed a brief rally as Temba Bavuma and Faf du Plessis put on a 72-run partnership, but Rajitha had the Proteas captain caught behind trying to flick to leg before lunch.
Suranga Lakmal thought he had De Kock caught behind early in the afternoon, only for a review to spare the wicketkeeper-batsman, but Bavuma fell three runs short of his half-century in the most unfortunate circumstances.
Standing at the non-striker's end, Bavuma was run out after De Kock's drive deflected off Vishwa Fernando's boot and onto the stumps with the right-hander short of his ground.
Rajitha accounted for Vernon Philander caught and bowled and Keshav Maharaj edged a Vishwa Fernando delivery behind as the home side limped to tea on 181-7.
Sri Lanka were soon back on the offensive after the interval, Kagiso Rabada easily caught after misjudging a low full toss from the lively Vishwa Fernando.
Lasith Embuldeniya clean bowled Dale Steyn (15) and De Kock was, perhaps fittingly, the last to go.
Sri Lanka's reply suffered an early setback as opener Thirimanne failed to survive in the gloomy conditions, but Karunaratne and debutant Oshada Fernando will return on Thursday well set.