Captain Hashim Amla struck a gritty 139 not out but failed to stop Sri Lanka from taking the driver's seat in the second and final Test against South Africa on Saturday.
Amla, 31, batted for more than eight hours to frustrate the Sri Lankan spinners who shared nine wickets between them to bowl out South Africa for 282 in their first innings.
Sri Lanka, who made 421 in their first essay, were 11-0 at stumps in their second innings for an overall lead of 150.
Off-spinner Dilruwan Perera (5-69) grabbed a five-wicket haul, his second in five Tests, while left-armer Rangana Herath chipped in with 4-71.
South Africa's weaknesses against spin were left exposed as none of the batsmen, barring Amla, could even make a half-century despite the fact the wicket was no minefield.
For Amla, it was his first century as South Africa's Test captain. He faced 382 balls and hit 12 fours in his marathon effort.
His century, also the first by a South African captain in Sri Lanka, proved crucial and helped the visitors avoid the embarrassment of a follow-on.
The South African innings was wrapped up in the final session with Herath having Dale Steyn (30) caught by Kumar Sangakkara and Imran Tahir by Upul Tharanga at deep mid-off.
Perera then sent back Morne Morkel for a duck to bowl out the Proteas with five overs remaining in the day.
Sri Lankan openers Kaushal Silva (five) and Upul Tharanga (six) saw off the overs without any hiccups.
South Africa lost Jean-Paul Duminy and Vernon Philander (nine) to spin in the second session that saw them put on 71 runs at less than three runs an over.
Duminy (three) fiddled around for more than an hour before he was stumped by Niroshan Dickwella off Herath while Philander was bowled by Perera.
Amla, dropped on 93 at short cover by Silva, completed his 22nd Test hundred with a single off Herath, a fitting reward for his lonely toil on the crease.
The bearded batting wizard is leading the side for the first time in this two-Test series after being named skipper last month following the retirement of Graeme Smith.
The first session saw Herath get rid of AB de Villiers (37) and Quinton de Kock for a duck in the space of three balls after South Africa had resumed at their overnight 98-3.
Amla and de Villiers had started off positively and saw off the first hour without harm.
South Africa lead the series 1-0 after winning the opener in Galle by 153 runs.