Fast-bowler Dale Steyn grabbed 5-50 to help restrict Sri Lanka to 283-9 in reply to South Africa's first-innings score of 455-9 declared on day three of the first Test.
South Africa first innings 455-9d
Sri Lanka first innings
K Silva c Philander b Steyn 8
U Tharanga st de Kock b Duminy 83
K Sangakkara b Morkel 24
M Jayawardene lbw b Steyn 3
Lu Thirimanne c de Kock b Steyn 38
A Mathews b Tahir 89
D Chandimal c Petersen b Steyn 6
D Perera c de Kock b Steyn 0
R Herath not out 12
S Lakmal c de Kock b Morkel 6
Extras: (4b, 7lb, 2w, 1nb) 14
Total: (for 9 wickets) 283
Fall of wickets: 1-39, 2-98, 3-104, 4-136, 5-190, 6-200, 7-201, 8-278,
It was the 23rd five-wicket haul in 73 Tests for Steyn, who gained appreciable reverse swing to rip through the middle order after taking two wickets in the first session.
Steyn took 3-8 in a five-over spell in the post-tea session as Sri Lanka slipped from 190-4 to 201-7 and stared at the prospect of following-on.
He was spot on during that five-over spell as Lahiru Thirimanne (38) was caught behind, Dinesh Chandimal (eight) pulled straight to short mid-wicket, and Dilruwan Perera (0) inside-edged one to be caught behind.
At stumps, Rangana Herath was not out on 12 with last man Shaminda Eranga due to come in as Sri Lanka was still 172 runs behind.
Earlier, captain Angelo Mathews produced a fine counter-offensive to save home blushes with another staunch innings of 89 which came with the help of one six and 14 fours.
Mathews once smashed Morne Morkel for five fours in an over to get past the 50-run mark for the 15th time in his career. He added 71 for the eighth wicket with Herath in what was the best partnership of the innings.