Joe Root scored an unbeaten 106 and shared a swashbuckling partnership with Ben Stokes as England put the brakes on a hostile South African attack to reach 238 for five at the close of the second day of the third Test on Friday.
Bad light and rain brought a premature end to the day's play with England trailing the hosts' first innings total by 75 runs, but with momentum having swung back in their favour at the Wanderers.
Root led an England fightback and Stokes scored 58 as the tourists piled on the runs after South Africa had seized the initiative with early wickets.
The pair shared a rapid-fire fifth wicket partnership of 111 runs in just under 16 overs after England had been in trouble at 91-4 just after lunch.
Hardus Viljoen took the wicket of England captain Alastair Cook with his first ball in Test cricket and there were two wickets each for Kagiso Rabada and Morne Morkel as South Africa unleashed a barrage of pace.
Root, however, reached his ninth Test century in just 126 balls with 16 boundaries and Stokes was equally severe on the bowling, scoring his 58 off 54 balls before being caught and bowled by Morkel.
Jonny Bairstow was not out on four when the players were taken off with just over an hour’s play left. Rain then began to fall and play was officially called off.
Earlier, Alex Hales, who has been struggling with a stomach virus, went for one when he edged Rabada to AB de Villiers at second slip and Cook's poor form continued after edging Viljoen’s first ball down the leg side to be caught by wicketkeeper Dane Vilas for 18.
Nick Compton was caught in the slips by Dean Elgar off Rabada for 26 and James Taylor departed for seven, caught at short leg by Temba Bavuma off Morkel.
South Africa had resumed on 267 for seven overnight and England removed Chris Morris and Rabada for the addition of only 14 runs, both caught by wicketkeeper Bairstow off Stuart Broad and James Anderson, who claimed his first wicket after toiling for 22 overs without success.
But debutant Viljoen, who hit a boundary from the first ball he faced as a Test batsman, and Morkel frustrated the bowlers by adding 32 runs for the last wicket. Bairstow dropped an easy catch off Anderson which denied him a chance to equal the world record of seven dismissals in an innings.
Anderson’s follow-through after the delivery led him to encroach on the wicket and having been warned twice for running on the pitch, he was removed from the England attack by umpire Aleem Dar after an acrimonious exchange between the pair.
He had bowled just two balls of his over and Stokes was brought on to complete it, finishing off the innings with the next ball when Morkel edged to Cook at first slip to give the all-rounder his 50th Test wicket.
Due to the early close, play will start 30 minutes early on Saturday.