A counter-attacking 60 from Matt Prior pushed England up to 385 all out, despite a spirited fightback from the South Africa bowlers on day two of the first Investec Test.
In reply, the Proteas also recovered from the loss of an early wicket to post 86 for one at stumps after rain cut into the last session's play. Captain Graeme Smith and Hashim Amla were at the crease, 299 runs adrift after England started the day strongly at 267 for three.
A resurgent Steyn removed England centurion Alastair Cook, and then Ravi Bopara for a duck, among four wickets for only 59 runs this morning.
Cook (115) dug in, but the game changed in two successive wicket maidens from Steyn.
The seamless accumulation of day one was replaced by England's struggle to retain control as Steyn upped the ante with Morne Morkel tightening up things at the other end. Morkel added to his overnight tally of two wickets to finish with four for 72.
In his second over of the day, Steyn tempted Cook to drive and bowled him off an inside edge to end his 295-ball vigil. With Cook gone, a big moment came and went for Bopara - returning for his first Test since last year at this venue.
He was bamboozled by an odd, looping bouncer from Steyn. Bopara lined himself up for the pull, and when he tried to bail out somehow managed only to offer a straightforward catch behind.
It was a soft dismissal, and left Ian Bell and new batsman Prior with much work to do to try to re-establish England's dominance.
They survived Steyn, only for Bell to fall in the first over from his replacement Jacques Kallis.
He might already have gone, run out by half the pitch had Alviro Petersen managed to throw down the stumps from gully.
But that mattered little when Bell left a delivery from Kallis which brushed over the off bail, just enough contact to dislodge it.
It took until the 19th over of the morning for England to bring up the 300 with Tim Bresnan's flamboyant extra-cover drive for four.
Then Bresnan succumbed in Imran Tahir's first over.
England had lost five wickets for 62, and this heavyweight contest was very much back in the balance. So it remained, despite a 75-ball half-century from Prior.
Prior lost Stuart Broad, another bowled by one that just clipped the bails - this time from Philander.
Prior went himself, edging Morkel behind, and last man James Anderson became AB de Villiers' fifth catch in the same over.
Petersen opened the innings with Smith but was out in the third over of the innings.