Real looked on course for a sixth consecutive league win when Casemiro leapt highest to meet a Toni Kroos cross and head Real in front midway through the first half, Reuters reported.
But Girona, which had not won in the league since November, came out with a vengeance in the second half, leveling in the 65th minute with a Cristhian Stuani penalty after a handball by Ramos.
Spanish striker Cristian Portu gave Girona an unlikely lead 10 minutes later, nipping in front of Madrid’s lackluster defender Marcelo to nod in on the rebound after Thibaut Courtois could only parry a shot from visiting forward Anthony Lozano.
Madrid substitutes Gareth Bale and Vinicius Jr. each squandered opportunities to level for the European champion and things got worse when Ramos earned a second yellow card in added time and was sent off for the 25th time in club football.
Real goalkeeper Courtois came close to salvaging an equalizer but headed wide deep in stoppage time, leaving Real third in the standings on 45 points, nine behind table topper Barcelona and seven back from second-placed Atletico Madrid.