Cristián Zapata hace su debut en las Divisiones juveniles del Deportivo Cali, luego de su gran rendimiento en las inferiores, es pasado al equipo profesional del Deportivo Cali, equipo con el cual juega 25 partidos, para luego participar en la selección de Colombia sub-20. Zapata es pretendido por varios clubes europeos y colombianos gracias a sus buenas actuaciones en el Deportivo Cali a pesar de tener 18 años, al final es comprado por el Udinese de Italia.
Udinese
Zapata fue comprado por el Udinese el 31 de agosto de 2005 con sólo 19 años, donde jugaría junto a su compatriota Abel Aguilar, debutaría el 19 de noviembre ante el Mesina. Marcaría su primer gol en la Serie A contra la Sampdoria. El 18 de septiembre de 2006, luego de su gran rendimiento en el Udinese, su contrato se extiende por 5 años hasta junio de 2012. En la temporada 2005/2006 Zapata jugaría 35 partidos en la Liga Italiana, pero en junio de 2008 Zapata se lesionaría y quedaría 6 meses sin jugar. A su regreso, en la temporada 2009/2010 el colombiano tendría una magnífica temporada, pasando las 100 presencias con la camiseta "bianconera" y volviéndose un titular indiscutido en el equipo.
Gracias a sus excelentes participaciones en el Udinese, sería convocado para jugar con la Selección colombiana en las Eliminatorias al Mundial Sudáfrica 2010.
Jugando en las eliminatorias, sufrió una lesión contra Perú que le costó quedarse afuera de las canchas por 3 meses. El 23 de enero de 2011 le marcó un gol al Inter de Milán que le dio la victoria a su equipo por 3-1. La semana siguiente, el 30 de enero, anotó un gol contra la Juventus en la victoria de Udinese de visitante por 2-1. Zapata fue nombrado el Mejor Central de la Serie A durante 2 temporadas consecutivas gracias a su buen rendimiento con el Udinese a pesar de su corta edad. En la temporada 2010/2011, el Villareal llegaría a un acuerdo con el Udinese por el traspaso del colombiano a la Liga española.
Villarreal
El 6 de julio de 2011, durante la Copa América 2011, se confirmó su traspaso, por cinco años, al Villarreal, equipo de la Primera División de España. El costo del traspaso fue de 7 millones de euros, luego de que el Udinese bajara sus pretensiones económicas por el jugador.[3] En el Villarreal Zapata realizó una irregular temporada, cometiendo errores defensivos y siendo finalmente suplente. Al final de la temporada, el equipo consumó su descenso a la Segunda división y Zapata es cedido al Milan de Italia con opción de compra.
Milán
El 8 de agosto de 2012, Zapata se convierte en nuevo jugador del Milan en calidad de cedido, con una opción de compra de 18 millones de euros. Debido al buen rendimiento mostrado por el futbolista colombiano en la temporada 2012/2013, el Milan hace efectiva la opción de compra.
En su primer derbi contra el Inter de Milán que finalizaría 1-1, Zapata fue elegido como una de las Figuras del partido porque jugó un papel clave en la defensa y en los contraataques.
El 26 de noviembre de 2013 juega su partido número 300 como profesional (en clubes) frente al Celtic anotando un gol en la victoria 3-0 del Milan por la quinta fecha de la Liga de Campeones 2013/2014, siendo este también su primer gol con el club "Rosonnero".
En mayo de 2013, Zapata firmaría un acuerdo con el Milan hasta el 2016.[4]
El 14 de enero de 2015 sufre una lesión contra el Sassuolo por un juego de la Copa Italia de Italia, por lo que queda más de un mes fuera de las canchas, después de eso su rendimiento bajó y causa que no tenga continuidad en todo el primer semestre del año, entrando solo los segundos tiempos de algunos de los partidos de final de temporada.[5]
El 22 de septiembre de 2015 marca su primer gol de la temporada 2015/16 dándole la victoria a su club frente al Udinese por 3-2 como visitantes.[6]
El 10 de junio de 2016 renueva su contrato con el Milan hasta 2019.[7]
El 23 de diciembre se corona campeón de la Supercopa de Italia partido jugado en Doha (Catar) el cual terminó 1-1 en los 120 minutos y 4-3 desde la tanda de penales. Partido del cual fue relegado al banco de suplentes sin disputar ningún minuto.
Vuelve a jugar el 25 de enero después de ocho meses un partido en los cuartos de final de la Copa Italia en la derrota 2-1 contra la Juventus. El 5 de febrero juega por primera vez de titular en la Serie A desde el 25 de abril de 2016 en la derrota por la mínima contra la Sampdoria además sería el capitán del equipo. Marca su primer gol de la temporada 2016-17 el 15 de abril dándole el empate a su equipo 2-2 al minuto 97 en el derby de la Madonnina frente al Inter de Milán donde los escogen como la figura del partido.[8]
Luego de empezar mal la temporada 2018-19 se consagra en la titularidad, su primer gol en la temporada lo hace el 13 de diciembre por la UEFA Europa League en la eliminación 3-1 en casa del Olympiakos, donde aparte de marcar gol hace un autogol, termina como uno de los destacados del partido.[9]
Genoa
El 3 de julio se confirma como nuevo jugador del Genoa llegando como agente libre.[10] Debuta el 25 de agosto por la primera fecha de la Liga en el empate a tres goles como visitantes ante el Roma jugando todo el partido. En su segundo partido marca su primer gol con el club abriendo la victoria 2 por 1 sobre Fiorentina.
San Lorenzo
Tras 16 temporadas en fútbol europeo, el día 28 de julio de 2021 firma contrato, por 18 meses, con San Lorenzo, de la Primera División de Argentina. El 30 de agosto de ese mismo año marca su primer gol con el club en la goleada 3-0 sobre Patronato.
Aunque de entrada le costó agarrar ritmo luego de un largo tiempo de poca actividad, con el correr de los partidos mostró toda su calidad.
Su primer gol del 2022 lo marca el 21 de febrero en la derrota como locales 4-3 frente a Defensa y Justicia.
A.Nacional
Después de finalizar su contrato con el San Lorenzo, El 2 de diciembre del 2022 el Club Atlético Nacional oficializa la contratación de Cristian para el 2023.
El 11 de mayo de 2015 fue seleccionado por José Pekerman en los 30 pre-convocados para disputar la Copa América 2015.[18]
Fue seleccionado en la nómina definitiva de 23 jugadores el 30 de mayo.[19]
El 14 de mayo de 2018 fue incluido por el entrenador José Pekerman en la lista preliminar de 35 jugadores para disputar la Copa Mundial de Fútbol de 2018.[20] Finalmente sería seleccionado en la lista final de 23 jugadores, debutando en el partido de octavos de final donde caerían eliminados por penaltis contra Inglaterra ingresando en los últimos minutos de tiempo extra por Santiago Arias.
El 30 de mayo queda seleccionado en la lista final de 23 jugadores que disputaran la Copa América 2019 en Brasil.[21] Debuta como titular el 23 de junio en la victoria por la mínima sobre Paraguay.