Cape Town - England took a 46-run first innings lead when South Africa were bowled out for 223 on the third day of the second Test at Newlands on Sunday.
James Anderson completed the 28th five-wicket haul of his Test career by taking both South Africa's remaining wickets. He finished with five for 40.
Ben Stokes set an England Test record when he held his fifth catch of the innings to dismiss last batsman Anrich Nortje.
Anderson struck with the first ball of the day when Kagiso Rabada was caught behind.
It put Anderson on a hat-trick after finishing the second day with the wicket of Keshav Maharaj.
Nortje survived but South Africa added only eight runs to their overnight 215 for eight before he was caught by Stokes.