iframe 내의 css 수정 가능할까?

jhson·2024년 9월 2일
0

css

목록 보기
27/28

문제 상황

iframe으로 starpi를 이용하여 동적으로 컨텐츠를 GET 해와서 렌더링하고 있다.
그런데 font를 전역으로 설정하였는데 해당 영역 안에서는 starpi에서 기본적으로 세팅하고 있던 font-family가 적용되어 있어 내가 전체 페이지에서 전역으로 설정한 font-family가 먹히지 않는 문제가 있었다.
구글링을 해보니 iframe은 새로운 창이나 다름 없기 때문에 전역으로 폰트 적용을 해도 해당 영역에서는 먹히지 않는다는 사실을 알게 되었다.
그러나 이미 strapi에 등록된 컨텐츠들이 많은 상태였고 이걸 일일이 수정하기에는 해당 담당자는 마크다운의 이해도가 없다는 사실과 일일이 수정하기에는 분명히 휴먼에러가 발생할 수도 있을 것 같았다.

생각 흐름

  1. iframe 내에서 적용된 font-family를 강제로 삭제하고 새로운 font-famliy를 덮어씌우면 되겠다?
    현재 strapi에서 받아오는 content들이 모두 iframe을 필요로 하지는 않은 상황임.
    따라서 iframe으로 렌더링해야하는 컨텐츠들의 font를 장제로 덮어씌워보자!
  • 인라인 스타일로 font-family가 적용되어 있는 케이스도 고려함

function getIframeContentWithFonts(content: string): string {
return `

<link rel="stylesheet" href="/fonts/pretendard/pretendard.css">
<style>
  /* 기본적으로 모든 요소에 Pretendard 폰트를 강제로 적용 */
  body, p, div, span, h1, h2, h3, h4, h5, h6, a, li, ul, ol, input, button, textarea {
    font-family: "Pretendard", -apple-system, BlinkMacSystemFont, "Malgun Gothic", "맑은 고딕", helvetica, "Apple SD Gothic Neo", sans-serif !important;
  }
  /* 인라인 스타일을 가진 요소에도 적용 */
  * {
    font-family: "Pretendard", -apple-system, BlinkMacSystemFont, "Malgun Gothic", "맑은 고딕", helvetica, "Apple SD Gothic Neo", sans-serif !important;
  }
</style>
<script>
  // 모든 요소의 인라인 스타일에서 font-family를 제거하고 새로운 폰트 적용
  document.addEventListener('DOMContentLoaded', function() {
    document.querySelectorAll('*').forEach(el => {
      el.style.fontFamily = '';
    });
  });
</script>
${content}

`
}

결과 : 작동하지 않았다...

개발자 모드로 들어가서 console로 iframe이 적용된 영역의 font-family를 강제로 수정하여봤지만 택도 없었다.

  1. react parser를 이용하여 jsx 형태로 들고오기
    현재 strapi에 저장되어있는 contet에는 html 코드에 style이 적용되어있는 것과 단순히 태그들만 붙어있는 content가 존재하고 있다.
    (이후 strapi 컨텐츠 등록은 운영 쪽에서 관리를 하게 되므로 style 작업을 일일이 그들이 하는 것은 무리이고 따라서 그냥 태그만 붙어있는 html(strapi에서는 기본적인 스타일 에디터가 있으며 이를 통해 자동적으로 태그 생성이 됨) 을 그대로 가져오는 편이 낫겠다는 판단이 됨)

step 1) 우선 style이 적용되어있는 content는 그대로 살리고 싶다는 요구사항이 있었으므로 이걸 그대로 들고 왔다.

  • 문제 발생 :
    style 적용되어 있는 컨텐츠에는 font-family가 적용되어 있었고 홈페이지의 global 스타일이 먹히지 않는 문제가 있었다.
  1. react parser를 이용하면 dangerouslysetinnerhtml 를 이용하여 html string 그대로 들고 오는 것에 비해 보안적인 측면에서는 안정적이라고 할 수 있지만 strapi 서버에 데이터를 등록하는 것은 이미 내부에서 등록하는 것이기 때문에 충분히 신뢰할 만하다는 가정하에 react 파싱보다 dangerouslysetinnerhtml를 사용하는게 렌더링 속도라든지 하는 측면에서 더 좋을 것이라 판단함.
    그러면 jsx로 가져오면 dom을 건드려야하는데 그냥 html로 들고오면 변경이 될까?

결과 : 그러나 당연히 변경이 안되었다...

이유 :
왜 그럴까?
** 이유 :
CSS 모듈의 기본적인 특성 때문!
id나 특정 클래스보다 태그 선택자를 우선시하는 것은 CSS의 일반적인 규칙에 위배되기 때문.
이걸 순간 망각하고 있었다.

Inline styles (HTML 요소에 직접 정의된 스타일) — 가장 높은 우선순위.
IDs — 스타일 우선순위가 높음.
Classes, pseudo-classes (:hover 등), attributes — 중간 우선순위.
Elements (태그) 및 pseudo-elements (::before, ::after 등) — 가장 낮은 우선순위.

즉, 이미 inline style로 적용되어 있던 content의 스타일을 global 스타일로 덮어씌워서 변경할 수 없었던 것.

css 기본 규칙에 의한 문제

jsx 형태이든 html 형태이든 이미 인라인 스타일로 적용된 content를 불러온 것이므로 font-family를 홈페이지의 global 스타일로 덮어씌우는 것은 애초에 불가능 했던 것

해결

iframe 내의 css 수정 가능할까? 에 대한 답은 불가능...
특히 이미 인라인 형태로 되어있는 경우는 strapi 에 적용된 font-family를 제거하는 것이 가장 깔끔하고 효율적인 방법이라는 결론이 내려졌다.

profile
게임회사 주니어 개발pm에서 프론트엔드 개발자로 전향하는 과정

0개의 댓글