황산은 지금의 충청남도 논산시 연산(連山) 지방이다.
의자왕 초, 왕권 중심의 지배 체제를 확립한 백제는 중국과 신라에 대해 강경 노선을 취하고 있던 고구려와 연결해 신라에 압박을 가하였다.
특히 642년(의자왕 2)에 대야성(大耶城 : 지금의 경상남도 합천)을 비롯한 신라 남부의 40여 성을 함락한 사건은 신라에게 커다란 충격을 주었다.
이에 신라는 김춘추(金春秋)를 당나라에 파견해 적극적인 외교 교섭을 벌인 결과, 당나라와 군사 동맹을 맺는 데 성공하였다. 660년에 이 나당연합군이 드디어 백제 공격을 단행하였다.
소정방(蘇定方)이 이끄는 13만 명의 당군은 산둥반도(山東半島)의 내주(萊州)를 출발해 서해를 건너 백제로 진군했고, 김유신(金庾信)과 흠춘(欽春)·품일(品日) 등이 거느린 5만 명의 신라군은 육로로 백제를 공격하였다. 급보를 접한 의자왕은 군신을 모아 대책을 강구하였다.
이 때 좌평 의직(義直)은 당군과 먼저 결전할 것을 주장했고, 달솔(達率) 상영(常永)은 신라군을 먼저 쳐서 예봉을 꺾은 뒤에 당군을 막자고 해 의견이 갈렸다.
그리고 귀양 중이던 흥수(興首)가 왕의 요청에 응해, 평야에서 접전하면 불리하므로 백강(白江 : 지금의 금강 하구)을 지켜 당군이 상륙하지 못하게 하고 탄현(炭峴)을 막아 신라군이 넘지 못하게 해 양 군이 피곤해지기를 기다렸다가 공격하자고 건의하였다.
반면에 대신들은 당군이 백강에 들어오고 신라군이 탄현을 오른 뒤에 공격하는 것이 이롭다고 주장하였다. 이처럼 백제 조정이 아무런 대책을 세우지 못하고 있을 때 신라군은 그 해 5월 26일 왕경을 출발해 6월 18일 남천정(南川停 : 지금의 경기도 이천)에 이른 뒤, 7월 10일 백제의 도성인 사비에서 당군과 합세하기로 하였다.
그리고 김유신이 이끄는 5만 명의 신라군은 7월 9일 이미 탄현을 넘어 황산벌로 진군해 오고 있었다. 탄현을 진수하지 못한 의자왕은 장군 계백(階伯)에게 5,000명의 결사대를 조직하게 해 신라군을 저지하도록 하였다.
출병에 즈음해 계백은 “처자가 적국의 노비가 되어 살아서 욕보기보다는 죽는 것이 낫다.”라고 하며 처자를 죽이고 비장한 각오로 출병하였다.
황산벌에 먼저 이른 계백은 험준한 곳을 가려 3개의 영채를 세우고 신라군을 기다렸다. 김유신도 신라군을 3도(道)로 나누어 이에 대항하였다. 그러나 죽기로 싸우는 백제의 5,000결사대는 신라군과 네 번 싸워 네 번 모두 승리하였다. 이로 말미암아 신라군은 기력이 다하고 사기가 떨어졌다.
이 때 신라의 장군 흠춘이 군사들의 사기를 돋우기 위해 아들 반굴(盤屈)로 하여금 적진에 뛰어들어 전사하게 하고, 장군 품일도 16세의 어린 아들 관창(官昌)을 백제군 속에 뛰어들어가 싸워 죽도록 하였다.
이와 같은 청년 화랑들의 목숨을 아끼지 않는 용감한 행동에 감격한 신라군은 사기가 크게 올라 총공격을 가하였다. 백제의 결사대는 여기에 맞서 용감히 싸웠으나 중과부적으로 대패하고 말았다. 이 싸움에서 계백은 전사하고, 좌평 충상(忠常)·상영 등 20여 명은 신라의 포로가 되었다.
황산벌전투가 얼마나 치열했는지는, 소정방이 당군과 합세하기로 한 신라군이 기일을 어겨 도착했다고 해 신라독군(新羅督軍)인 김문영(金文穎)을 참하려 했을 때, 김유신이 “대장군이 황산벌의 싸움을 보지 못하고 다만 기일을 어긴 것으로 죄를 주려 하니, 기필코 먼저 당군과 결전한 뒤에 백제를 격파하겠다.”라고 한 말에서도 알 수 있다.