Cardiff sealed promotion to the Premier League as Burton and Barnsley slipped out of the Championship on a dramatic final day.
The Welsh side were forced to settle for a goalless home draw against struggling Reading - but Fulham's 3-1 loss at Birmingham meant Neil Warnock's men could celebrate a return to the top flight after a three-year exile.
Birmingham, who went into their game at St Andrew's still under the threat of relegation, took control with first-half goals from Lukas Jutkiewicz (15) and Harlee Dean (43).
Tom Cairney gave the Cottagers hope with six minutes remaining but Che Adams' 89th-minute goal means they must settle for the play-offs.
Championship table | 2017-18 season standings
Barnsley's 4-1 loss at Derby ended their brief stay in the Championship.
Cameron Jerome opened the scoring for the home side with a powerful left-foot shot in the 14th minute, then set up Matej Vydra for the Rams' second goal 10 minutes into the second half.
Substitute Vydra then set up David Nugent for Derby's third midway through the second half. Tom Lawrence made it 4-0 in the 71st, before George Moncur's reply 10 minutes from time. The win secured the Rams' place in the play-offs.
Burton lost 2-1 at Preston, with Louis Moult's goal in added time ending their survival hopes. Callum Robinson gave Preston the lead with a close-range header, before the hosts had Billy Bodin dismissed for two yellow cards - one a handball which saw a goal ruled out, then a dive in the penalty area. Hope Akpan curled in Burton's equaliser in the 63rd minute.
Bolton produced an impressive late finish to escape the clutches of League One as a result of a 3-2 win over Nottingham Forest.
Adam Le Fondre volleyed Wanderers in front midway through the second half but Ben Osborn (70) and Jack Colback (79) turned things around and had Bolton staring relegation in the face.
However, goals from David Wheater (87) and Aaron Wilbraham (88) - who had earlier hit the post - kept the hosts up, sparking joyous scenes at the Macron Stadium.
Play-off hopefuls Middlesbrough drew 2-2 at Ipswich. Freddie Sears (eight) and Martyn Waghorn's 83rd-minute penalty had the hosts ahead twice but Stewart Downing (71) and Patrick Bamford (90) earned the visitors a draw.
The other top six team, Aston Villa, lost 1-0 at Millwall. Shaun Williams got the decisive goal from the penalty spot in the 30th minute, before Lee Gregory missed another spot-kick for the Lions late on.
Elsewhere, bottom club Sunderland stunned champions Wolves 3-0, in front of prospective new owner Stewart Donald.
On-loan duo Ovie Ejaria (19) and Ashley Fletcher (45) had the hosts 2-0 ahead before Paddy McNair got Sunderland's third midway through the second half.
Atdhe Nuhiu (14, 60 and 90) scored a hat-trick in Sheffield Wednesday's 5-1 drubbing of Norwich at Hillsborough. Fernando Forestieri (30) and Frederico Venancio (58) also netted, with Timm Klose (83) replying for Norwich.
Wednesday's city rivals United were also final-day winners, 3-2 at Bristol City.
Leon Clarke opened the scoring in the eighth minute with his 19th league goal of the season, before Billy Sharp (29) and Kieran Freeman (34) made it 3-0. City rallied with goals from Aden Flint (60) and Joe Bryan (75) - but there was to be no leveller.
Leeds beat QPR 2-0 with goals from Kemar Roofe (30) and Kalvin Phillips (47), while Brentford and Hull drew 1-1 at Griffin Park.
Sergi Canos headed the hosts into a 12th-minute lead before Jarrod Bowen levelled in first-half added time. Harry Wilson had the chance to win it for the Tigers in the second half after Luke Daniels fouled Fraizer Campbell - but the goalkeeper redeemed himself with an excellent stop to keep out Wilson's penalty.