Steyn got rid of star batsman Mahela Jayawardene (three) and opener Kaushal Silva while Morkel sent back run-machine Kumar Sangakkara (24) as Sri Lanka went in to lunch at a shaky 104-3.
The hosts trail the visitors by 351 runs with seven wickets in hand, with South Africa making 455-9 declared in their first innings.
Tharanga, making a Test comeback after more than six years, defied the hostile fast bowling to make a fine 65 with the help of 12 boundaries.
Silva tried to hook the bouncer but edged it to long leg where Vernon Philander dived forward and plucked the ball inches off the ground to complete a spectacular catch.
More From This Section
His dismissal brought in Sangakkara, coming into the match on the back of a record seven successive fifty-plus scores.
The left-hander looked his normal poised self, pulling and driving Steyn with contempt for two fours in an over, including his trademark cover drive.
The left-hander dished out similar treatment to Imran Tahir, the only specialist spinner in the South African squad, whacking him around for two boundaries is his consecutive overs.
Sudden rains close to the lunch break held up the game briefly. And just as the game resumed, Sangakkara paid the price for losing his concentration, inside edging Morkel on to his stumps.
Jayawardene, who has announced that he will retire in August, was trapped leg before by Steyn while trying to defend against a stinging yorker from the bowler.