CSS로 SVG 색상 제어하기
초보자에게는 다소 어려운 CSS 사용 방법입니다.
벡터 이미지 포맷인 SVG와 웹에서 사용하는 방법에 대한 기본적인 이해가 있어야 합니다.
완성된 소스와 예제 SVG 파일들은 다음 링크에서 다운로드 할 수 있습니다.
크기를 변경해도 이미지가 거칠어 보이지 않는 장점때문에 아이콘이나 UI 디자인 용으로 벡터 이미지 포맷인 SVG가 많이 사용되지만, 벡터 편집 프로그램을 조금은 사용할 줄 알야아하는 단점이 있습니다.
예를 들어 다음의 트위터 로고 파일은 벡터 이미지 포맷인 SVG 포맷이고 파일 크기가 1.58Kb 밖에 안되지만, 크기를 크게 해도 이미지가 거칠어지지 않습니다.
단, 비트맵 이미지와 마찬가지로 마우스 호버 반응을 처리할 때도 색상을 다르게 한 2개의 SVG 파일이 필요하고, 웹 사이트의 컬러 톤이라도 바뀌게 되면, 모든 벡터 이미지의 색상을 바꿔야 하는 번거로움도 똑같이 있습니다.
그러나 SVG 포맷은 잘 활용하면 여러 색상으로 된 추가의 벡터 이미지 파일을 만들지 않아도 컬러를 바꿀 수 있는 방법이 있습니다.
제한적이지만 텍스트 편집기로 SVG 이미지의 색상을 바꿀 수도 있습니다.
조금 더 제한적이지만 인라인 CSS로 SVG 벡터 이미지의 색상을 바꿀 수도 있습니다.
만들때는 조금 번거롭지만, 일단 만들고 나면 텍스트 편집기, 또는 CSS 만으로 색상 조정이 가능하기 때문에 유지보수 측면에서 유연한 대응이 가능해지는 장점이 있습니다.
예를 들어 앞의 트위터 SVG 파일을 텍스트 편집기에서 열면 다음과 같은 내용이 표시됩니다.
SVG 파일을 제작한 프로그램에 따라 표시되는 내용과 태그는 다소 다를 수 있습니다.
기본적으로는 HTML과 유사한 XML 포맷이므로 HTML에 익숙하면, 태그로 벡터 데이터를 표현한 것이라는 것쯤은 쉽게 이해할 수 있습니다.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 172 140" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,-282.321,-396.307)">
<path id="path1" style="fill:rgb(42,169,224);fill-rule:nonzero;" d="M453.826,412.806C447.516,415.605 440.734,417.496 433.617,418.347C440.882,413.992 446.461,407.097 449.088,398.88C442.289,402.913 434.759,405.84 426.743,407.418C420.326,400.58 411.181,396.307 401.06,396.307C381.629,396.307 365.874,412.061 365.874,431.493C365.874,434.25 366.185,436.936 366.785,439.511C337.542,438.044 311.615,424.036 294.26,402.747C291.232,407.944 289.496,413.988 289.496,420.436C289.496,432.644 295.708,443.414 305.149,449.724C299.382,449.541 293.956,447.958 289.212,445.323C289.208,445.469 289.208,445.617 289.208,445.765C289.208,462.813 301.337,477.033 317.434,480.268C314.481,481.072 311.373,481.502 308.164,481.502C305.897,481.502 303.693,481.281 301.544,480.871C306.022,494.849 319.016,505.022 334.414,505.305C322.371,514.743 307.2,520.369 290.714,520.369C287.874,520.369 285.073,520.201 282.321,519.876C297.892,529.861 316.388,535.686 336.258,535.686C400.978,535.686 436.371,482.07 436.371,435.572C436.371,434.046 436.337,432.529 436.269,431.019C443.143,426.059 449.108,419.863 453.825,412.806L453.826,412.806Z"/>
</g>
</svg>
SVG 파일은 XML 태그로 데이터를 표현하며, 내용은 텍스트 편집기에서 읽고 수정할 수 있습니다.
물론 우리가 이 SVG 데이터를 기술하는 모든 태그를 알 필요는 없습니다.
웹에서 사용하는 SVG 이미지는 간단한 아이콘이나 벡터 도형이 대부분이며, 우리가 색상을 조정할 SVG 파일도 이런 이미지입니다. 이보다 복잡한 큰 이미지는 우리가 웹에서 색상을 바꿔가면서 사용할 이미지의 범위 밖입니다.
앞서의 XML 데이터에서 우리가 알아야 하는 중요한 내용은 다음 3가지입니다. 앞서의 트위터 로고 SVG 텍스트 내용을 참고해서 보면 됩니다.
- SVG 파일의 실제 벡터 드로잉 데이터는 <svg></svg> 태그 안에 표현됩니다.
- 좌표를 보정하는 태그는 <g></g>태그이며 <svg></svg> 태그 안에 옵니다.
- 실제 도형을 그리는 태그들은 <g></g> 안에오면 부정형 경로는 <path/>로 정형 도형은 <ellipse/>, <rectangle/>, <circle/> 등의 도형 태그로 표현합니다.
우리가 알아야 하는 것은 3번째 항목의 도형 태그 안에 오는 "style", 또는 "fill" 속성입니다. 이 속성이 벡터 경로 데이터에 색상을 채우는 컬러 값을 지정하는 속성입니다.
앞서의 트위터 로고 SVG 데이터는 부정형 경로(path) 1개로 로고 아이콘을 그렸고 "style" 속성으로 채우기 색상을 정의했습니다.
앞서의 트위터 로고 XML 텍스트 데이터의 5번 째 줄 "<path/>" 태그를 보면
style="fill:rgb(42,169,224);"
이 있습니다. 이 "style" 속성을 보면 "fill" 속성이 있고, 컬러 값을 RGB(rgb(42,169,224);)로 정의했습니다. 두에 붙은 추가적인 속성들은 몰라도 되므로 여기서는 색상을 바꾸는 방법에만 집중합니다.
"style" 속성은 SVG 파일을 생성하는 프로그램에 따라서는 태그 맨 끝에 올 수도 있고, "style" 속성 없이 "fill" 속성으로 직접 컬러 값을 다음과 같이 정의하기도 합니다.
fill="rgb(42,169,224)"
fill="red"
SVG 포맷에서 채우기 속성을 어떻게 정의하는지 알았으므로 이점을 활용해 벡터 편집 프로그램 없이 색상을 변경해 보겠습니다. 그리고 이 색상 변경을 CSS를 이용해 변경하도록 해서 유지 보수를 간편하게 할 수 있도록 하겠습니다.
1. 텍스트 편집기로 색상 변경하기
앞서의 트위터 로고 SVG 파일을 텍스트 편집기에서 열어 "fill:rgb(42,169,224);" 을 "fill:red;" 로 변경한 후 저장합니다.
저장한 SVG 파일을 웹 브라우저에서 열어보면 다음과 같이 빨강색 트위터 로고로 변경된 것을 확인할 수 있습니다.
SVG 포맷으로 아이콘을 여러 개 만들어 사용하는 경우 텍스트 편집기의 일괄 변경 기능으로 SVG 파일 아이콘의 색상을 관리할 수도 있습니다.
2. CSS로 색상 변경하기
앞서 SVG 파일의 채우기 색상을 텍스트 편집기로 변경할 수 있다는 것을 알았습니다.
HTML 태그에 인라인으로 CSS 속성을 적용하는 방법과 같은 방법입니다.
여기에 더해서 SVG 파일은 HTML 파일과 마찬가지로 "<svg></svg>" 안에 "<style></style>" 태그로 클래스를 정의하거나, 외부 CSS 파일을 링크해서 외부 CSS 파일에 정의된 CSS 클래스를 경로 태그에 적용할 수 있습니다.
먼저 "<style></style>" 태그로 클래스를 정의해서 경로 채우기 클래스로 적용해보겠습니다.
먼저 <svg> 시작 태그 밑에 다음과 같은 스타일을 추가합니다.
SVG 포맷에는 채우기 속성이 별도로 있으며 "fill: blue;" 와 같이 사용합니다.
<style>
.blue{
fill: blue;
}
</style>
그리고 "<path/>" 태그의 "style" 속성을 모두 삭제하고 앞서 정의한 클래스를 추가합니다. 스타일 적용은 HTML 태그에 스타일을 적용하는 방법과 같습니다.
<path id="path1" class="blue" ... />
다음 소스를 SVG 파일로 저장하면
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 172 140" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<style>
.blue{
fill: blue;
}
</style>
<g transform="matrix(1,0,0,1,-282.321,-396.307)">
<path id="path1" class="blue" d="M453.826,412.806C447.516,415.605 440.734,417.496 433.617,418.347C440.882,413.992 446.461,407.097 449.088,398.88C442.289,402.913 434.759,405.84 426.743,407.418C420.326,400.58 411.181,396.307 401.06,396.307C381.629,396.307 365.874,412.061 365.874,431.493C365.874,434.25 366.185,436.936 366.785,439.511C337.542,438.044 311.615,424.036 294.26,402.747C291.232,407.944 289.496,413.988 289.496,420.436C289.496,432.644 295.708,443.414 305.149,449.724C299.382,449.541 293.956,447.958 289.212,445.323C289.208,445.469 289.208,445.617 289.208,445.765C289.208,462.813 301.337,477.033 317.434,480.268C314.481,481.072 311.373,481.502 308.164,481.502C305.897,481.502 303.693,481.281 301.544,480.871C306.022,494.849 319.016,505.022 334.414,505.305C322.371,514.743 307.2,520.369 290.714,520.369C287.874,520.369 285.073,520.201 282.321,519.876C297.892,529.861 316.388,535.686 336.258,535.686C400.978,535.686 436.371,482.07 436.371,435.572C436.371,434.046 436.337,432.529 436.269,431.019C443.143,426.059 449.108,419.863 453.825,412.806L453.826,412.806Z"/>
</g>
</svg>
다음과 같이 파랑색 트위터 로고로 변경됩니다.
클래스를 정의해 경로에 채우기 속성을 적용할 수 있다는 것을 알았으므로, "<style></style>" 로 정의한 클래스를 별도의 파일로 분리할 수 있다는 것도 짐작할 수 있을 겁니다.
앞서 작성한 클래스를 별도의 CSS 파일로 분리합니다. 예를 들어 "svg.css" 파일로 저장해보겠습니다.
그리고 다음과 같이 <svg> 시작 태그 밑에 CSS 파일 링크를 합니다.
<link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="svg.css" type="text/css"/>
완성된 SVG 파일은 다음과 같습니다.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 172 140" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="svg.css" type="text/css"/>
<g transform="matrix(1,0,0,1,-282.321,-396.307)">
<path id="path1" class="twitter" d="M453.826,412.806C447.516,415.605 440.734,417.496 433.617,418.347C440.882,413.992 446.461,407.097 449.088,398.88C442.289,402.913 434.759,405.84 426.743,407.418C420.326,400.58 411.181,396.307 401.06,396.307C381.629,396.307 365.874,412.061 365.874,431.493C365.874,434.25 366.185,436.936 366.785,439.511C337.542,438.044 311.615,424.036 294.26,402.747C291.232,407.944 289.496,413.988 289.496,420.436C289.496,432.644 295.708,443.414 305.149,449.724C299.382,449.541 293.956,447.958 289.212,445.323C289.208,445.469 289.208,445.617 289.208,445.765C289.208,462.813 301.337,477.033 317.434,480.268C314.481,481.072 311.373,481.502 308.164,481.502C305.897,481.502 303.693,481.281 301.544,480.871C306.022,494.849 319.016,505.022 334.414,505.305C322.371,514.743 307.2,520.369 290.714,520.369C287.874,520.369 285.073,520.201 282.321,519.876C297.892,529.861 316.388,535.686 336.258,535.686C400.978,535.686 436.371,482.07 436.371,435.572C436.371,434.046 436.337,432.529 436.269,431.019C443.143,426.059 449.108,419.863 453.825,412.806L453.826,412.806Z"/>
</g>
</svg>
주의할 점이 있습니다.
위의 예제는 "svg.css" 파일과 SVG 파일이 같은 경로에 있어야 합니다.
경로가 다를 경우 상대 경로로 "svg.css" 파일의 경로를 지정해야 "svg.css" 파일 CSS 정보를 가져올 수 있습니다.
그리고 SVG 파일을 HTML 파일에 연결할 때는 "<img>" 태그가 아닌 "<object>" 태그로 연결해야 합니다.
"<img>" 태그로 연결할 경우 SVG 파일 안에 연결한 CSS 파일을 읽지 못합니다.
반드시 다음과 같이 "<object>" 태그로 연결해야 합니다.
<object data="./backup/812/img/twitter_logo_css.svg" class="twitter"></object>
마우스 호버나 상태 변화에 대한 CSS 또한 SVG 파일 안에 클래스를 정의해서 사용할 수 있습니다. 예를 들어 앞의 트위터 로고는 다음과 같이 마우스 호버 CSS를 추가할 수 있습니다.
.twitter{
fill: blue;
}
.twitter:hover{
fill: green;
}
이렇게 하면 CSS로 벡터 아이콘의 색상의 정의해서 관리할 수 있으며, 벡터 편집 프로그램을 사용할 일이 현저히 줄어들게 됩니다.
실제 프로젝트에서는 벡터 아이콘에 적용하는 CSS 속성과 마우스 호버 등의 사용자 액션을 모아서 정의한 CSS 파일을 정의해서 관리하고, 이 CSS를 메인 CSS에서 임포트해서 사용하는 방식으로 관리를 하게 됩니다.