OROR Forge: Figma to Code 도구 제작기 (1) 디자인을 코드로 만들어보자!

프롤로그

안녕하세요, OROR 프론트엔드 팀의 테오입니다! 이번 글에서는 프론트엔드 개발에서 빼놓을 수 없는 중요한 부분, 바로 디자인을 코드로 변환하는 과정에 대해 이야기를 해보려고 합니다. 화면을 만드는 프론트엔드 개발자에게 이 코드 변환 과정은 필수적인데, 언뜻 간단해 보일 수 있지만 실제로는 상당한 시간과 노력이 필요한 작업입니다. 이러한 작업의 복잡성을 줄이고자, 저희는 ‘Figma to Code‘라는 새로운 기술적 접근 방식과 그 기능을 제공하는 ‘OROR Forge’라는 도구를 개발하고 있습니다.

아직도 개발이 진행 중인 단계이지만, 이번 글을 통해 그동안 저희가 직면했던 문제들과 이를 해결하기 위한 과정들을 독자분들과 공유하고자 합니다. 저희의 경험을 공유함으로써, 독자분들이 코드 변환 도구를 구현한 과정에 대해 더 깊이 이해하고, 저희가 발견한 해결책에서 유용한 인사이트를 얻을 수 있기를 바랍니다.

전통적인 프론트엔드 개발의 복잡성

퍼블리싱과 마크업

화면을 만드는 프론트엔드 개발 과정에는 필연적으로 디자인을 코드로 변환하는 작업, 즉 ‘퍼블리싱’이나 ‘마크업’ 과정이 포함됩니다. 정적인 이미지 형태로 된 디자인은 데이터 변경이나 콘텐츠 조정에 한계가 있어, 화면 크기나 내용 변경에 따른 동적인 반응이 어렵습니다. 그렇기에 개발자는 디자인을 이미지 그대로 사용하지 않고 코드로 바꾸는 작업을 통해 동적인 컨텐츠를 제공할 수 있도록 해야 합니다.

이 과정에서 우리는 디자인을 정확하게 코드로 옮겨내야 하는데, 전통적으로는 이는 모두 수동으로 코드로 전환해야 하는 복잡한 작업이 요구됩니다. 그리고 여기서 수많은 문제가 발생합니다.

디자인을 코드로 변경하는 과정의 어려움

프론트엔드 개발에서 디자인을 코드로 변환하는 과정은 필수적이지만, 이 과정에서는 아래와 같은 여러 어려움이 존재합니다.

  1. 수동 HTML/CSS 마크업의 복잡성: 이 작업은 각 요소를 구현하는 과정은 난이도가 높지 않을 수 있지만, 요소들이 모이면 보통 어마어마한 작업량이 요구되므로 결국 많은 시간이 소요되며, 실수가 발생하기 쉽습니다.
  2. 디자인의 정확한 전환 문제: 특히, 위와 같은 실수가 아니더라도 개발자가 종종 디자이너가 구상한 디자인의 일부를 누락하거나 오해할 수 있습니다. 이는 디자인의 섬세한 부분을 개발자가 완전히 이해하지 못했거나 간과할 때 주로 발생합니다(“???: 여기 2px이 틀어졌어요!”).
  3. 커뮤니케이션 비용의 증가: 결국 이러한 디자이너와 개발자 간의 작업 불일치로 인해, 추가적인 검수와 조정이 필요합니다. 때문에 서로 간의 작업이 종속관계가 되며, 이는 결과적으로 프로젝트의 진행속도와 효율성이 저하되는 요인이 됩니다.
  4. 지속적인 관리와 조정으로 효율성 저하: 디자인이 변경될 때마다 새로운 마크업을 작성해야 하며, 이는 1 ~ 3번의 문제가 다시 발생하는 결과를 초래합니다. 또한, 프로젝트가 진행되는 동안 지속적인 관리와 조정이 필요하게 되어, 프로젝트 관리 측면에서도 효율성이 떨어질 수 있습니다.

이러한 문제들은 프론트엔드 개발 과정에서 상당한 시간과 노력을 쏟게 하고, 개발자와 디자이너 모두에게 부담을 주는 요소들입니다. 특히 현재 구현 중인 프로젝트가 디자인 시안을 많이 만들어보고 이를 변경을 해야 하는 과정에 있다면 더욱더 체감이 되는 문제들입니다.
결국 프로젝트 전체 복잡도와 구현 비용을 낮추기 위해서는, 디자이너와 개발자 모두에게 효율적인 방법을 모색하는 것이 꽤 중요하다는 것을 생각해 볼 수 있습니다.

특히 우리에게 더 Figma to Code가 필요했던 이유

당시 저희 팀은 신규서비스를 개발한 후 런칭한 지 얼마 지나지 않았던 상황이었고, 위에서 말씀드린 문제들을 겪으며 이를 해결할 수 있는 해법이 절실했습니다. 저희 팀에게 ‘Figma to Code’가 특히 필요했던 이유는 아래와 같습니다.

  1. 런칭 이벤트와 프로모션: 새로운 서비스 런칭으로 홍보 및 이벤트성의 일회성 페이지가 다수 필요했습니다.
  2. 다수의 뷰 개발 필요성: 추가적인 기능 개발 과정 특성상 많은 뷰의 동작을 실험해야 했습니다.
  3. 빠른 개발과 협업 프로세스: 그 과정에서 기획, 디자인 그리고 개발 조직 간의 빠른 협업이 요구되었습니다.
  4. 지속적인 디자인 변경: 실험적인 접근 과정에서 발생하는 잦은 디자인 변경에도 개발 과정의 효율성 유지하는 것이 중요했습니다.

이러한 상황에서 전통적인 방식으로는 디자인을 화면으로 만드는 시간과 노력이 과도하게 소요되었습니다. 따라서, 자동으로 Figma의 디자인을 코드로 정확하게 변환하여, 디자인 변경에 빠르게 대응하고 프로젝트 전체의 효율성을 높일 수 있는 ‘Figma to Code’ 기능이 어느 때 보다 필요한 상황이었습니다.

상용 Figma to Code 기술 검토

저희 팀은 먼저, 상용에서 사용 가능한 다양한 ‘Figma to Code’ 도구들을 살펴보았습니다. Figma to Code Plugin, Anima Studio, builder.io 등 여러 옵션을 고려한 끝에, Amplify StudioLocofy를 주목했습니다.

Amplify Studio

Amplify Studio는 Amazon이 개발한 도구로 Figma 파일에서 직접 디자인 요소를 추출해 자동으로 디자인 시스템을 구축할 수 있습니다. 이 서비스의 핵심적인 특징은 아래와 같습니다.

  • 디자인 시스템 자동화: Figma 파일에서 컴포넌트를 추출하여 자동으로 디자인 시스템을 구성합니다. 이는 개발자의 수작업을 줄여주는 중요한 기능입니다.
  • 컴포넌트 중심 설계: 사용자가 디자인을 모듈화 된 방식으로 관리할 수 있도록, 컴포넌트 중심으로 작동합니다.

Amplify Studio의 장점 및 주목할 만한 특징

Amplify Studio는 Figma 디자인을 코드로 변환하는 것 이상의 기능을 제공하고 있습니다. 주요 장점 및 특징은 아래와 같습니다.

  • CLI(Command Line Interface) 지원: 강력한 자동화와 통합 기능을 제공하여, 개발 과정을 효율적으로 만듭니다.
  • 데이터 바인딩 기능: 데이터와 UI 컴포넌트 간 연동이 용이하여, 동적인 웹 애플리케이션 개발에 유용합니다.
  • 기능 연동 및 확장성: AWS(Amazon Web Services)와의 통합을 통해 백엔드 기능과의 연동이 가능하며, 확장 가능한 애플리케이션 구축을 지원합니다.
  • 사용자 인터페이스 개선: 개발자와 디자이너 모두에게 편리한 작업 환경을 제공합니다.

 

Amazon은 Amplify Studio의 이러한 기능들을 통해, 이 제품이 단순한 코드 변환 도구를 넘어 프론트엔드 개발의 전반적인 생산성을 높이는 강력한 솔루션이 될 수 있도록 했습니다.

Amplify Studio의 한계점

다만 실제 사용 경험에서 Amplify Studio는 아래와 같이 몇 가지 중요한 제약 사항이 있었습니다.

  1. 컴포넌트 제한성: 주로 컴포넌트 중심으로 작동하므로, 컴포넌트가 아닌 다른 디자인 요소의 처리에 제한이 있었습니다.
  2. 실제 사용성 문제: 일부 페이지에서 디자인이 제대로 반영되지 않거나 화면이 깨지는 현상이 발생했습니다.
  3. 용량 제한의 문제: 큰 용량의 디자인 파일 처리에 제한이 있어, 대규모 프로젝트에는 적용하기 어려웠습니다.

이러한 한계에도 불구하고, Amplify Studio의 부가적인 기능들은 매우 인상적이었습니다. 이러한 기능들은 추후 OROR Forge의 컴포넌트 바인딩 기능을 구현하는 데 영감을 주었습니다.

그러나 전체적인 기능들을 사용해 본 경험으로는 실제 프로젝트 환경에 Amplify Studio를 사용하기에는 여러 면에서 부족함을 느꼈습니다.

Locofy

저희 팀은 주목할 만한 또 다른 도구인 Locofy에 대해서도 검토를 진행했습니다. Locofy는 Figma 플러그인과 자체 빌더를 통해 Figma 디자인을 웹용 코드로 생성하는 도구입니다.

Locofy의 특징

Locofy의 특징은 아래와 같았습니다.

  • Figma 플러그인과 자체 빌더: Figma 디자인을 직접적으로 웹용 코드로 변환할 수 있는 기능을 제공합니다.
  • 높은 퀄리티의 코드 생성: 실제 디자인과 거의 유사한 수준의 결과물을 제공하며, 생성된 코드의 퀄리티가 높습니다.

Locofy의 장점

Locofy는 특히 디자인을 코드로 변환하는 과정에서 높은 정확성을 보여주었습니다. 또한, Locofy의 추가적인 주요 장점들은 아래와 같았습니다.

  1. 디자인 정확도: Figma 디자인을 HTML과 CSS 코드로 변환하는 과정에서 높은 정확도를 제공합니다. 이는 프론트엔드 개발 과정에서 아주 중요한 요소입니다.
  2. 코드 퀄리티: 생성된 코드의 퀄리티가 우수하여, 실제 개발 환경에 적용하기 적합합니다.
  3. 직관적인 사용성: Figma 플러그인과 자체 빌더의 조합으로 사용자에게 직관적이고 편리한 작업 환경을 제공합니다.

Locofy의 한계점

그러나 Locofy를 사용하는 과정에서 몇 가지 아쉬운 점들을 발견했습니다.

  1. 가끔씩 디자인과 다른 결과물 생성: Locofy는 준수한 결과물이 생성되는 여러 가지 기능들을 잘 제공하지만, 가끔씩 결과가 틀어지는 경우나 실수가 발생할 수 있습니다.
  2. 이벤트 바인딩과 프로퍼티 유지의 어려움: 디자인 변경 시 클릭 이벤트, 바인딩, 프로퍼티 등이 유지되어야 하는데, 이를 처리하는 과정에서의 UI가 상당히 불편했습니다. 언젠가는 개선이 될 문제이지만 플러그인에서 원하는 노드를 선택할 수 있는 기능이 아직까지 제공하지 않고 있기에, 플러그인을 끄고 피그마에서 선택하고 다시 플러그인을 켜서 작업하는 과정에서 상당한 불편함을 가지고 있습니다.
  3. 지속적인 유지보수의 어려움: 위와 같은 이유들로 디자인이 변경되었을 때, 생성된 코드를 그대로 적용하기가 어려웠습니다.

이러한 한계점에도 불구하고, Locofy는 전반적으로 우수한 툴이었습니다. 특히 다른 도구와 비교했을 때, 디자인을 코드로 변환하는 과정에서 만들어지는 코드의 퀄리티가 우수한 장점을 보여주었습니다.
만일 저희 팀에게 주어진 선택지가 상용 도구를 쓰는 것 밖에 없었다면 저는 아마도 Locofy를 선택했을 것 같습니다.

다만, Locofy는 범용적인 도구의 성격을 지니고 있었기 때문에, 저희 팀의 특수한 요구사항과 상황에는 완전히 부합할 수는 없었습니다. 저희는 이처럼, 두 제품의 벤치마킹을 통해서 저희 팀의 특정 요구사항에 더 정확히 일치하는 ‘Figma to Code’ 솔루션을 만들기 위해, 검토를 계속 진행하였습니다.

OROR Forge: 전략과 목표

“디자인의 정확성을 최우선으로 하는 실전용 코드 생성 도구”

당시 OROR 팀에서는 이벤트 및 프로모션과 같은 싱글 페이지 형태의 뷰를 다수 제작해야 하는 경우가 많았습니다. 이러한 페이지들은 기능적 요구사항보다는 디자인의 정확성과 시각적 요소들이 제대로 표현되는 것이 중요합니다. 따라서, 디자인이 변환된 코드가 원본 디자인과 정확히 일치하도록 하는 것이 OROR Forge 툴의 주요 목표가 되었습니다.

다시 말하면, 저희 팀의 과제는 사용 중인 Figma의 디자인을 그대로 정확한 화면 코드로 만들어 낼 수 있는 ‘픽셀 퍼펙트한 코드(Pixel Perfect Code)’를 생성하면서도, 그 생성 결과가 실 서비스에도 사용할 수 있도록 퀄리티 있는 코드를 만들어내는 것이었습니다. 또한, 별도의 추가적인 작업 없이 디자인 변경 시 페이지를 서비스에 반영될 수 있도록 하는 것이었습니다.

위와 같은 목표를 달성하기 위해, 저희 팀에서는 실전에서 변환 코드를 바로 적용 가능하고 디자인의 정확성을 보장하는 OROR Forge를 개발하게 되었습니다.

핵심 목표

저희 과제의 주요 목표를 세부적으로 설명하면 아래와 같습니다.

  1. 픽셀 퍼펙트한 코드 생성: 디자인 화면과 정확히 일치하는 형태로 코드를 생성하는 것이 중요했습니다. 디자인의 정확한 전환을 보장함으로써, 개발자들이 생성된 코드에 대한 의심 없이 프로젝트에 집중할 수 있다는 것이 중요했습니다.
  2. 사내 프로젝트에의 적용 가능성: 생성된 코드를 회사 프로젝트에 바로 적용할 수 있는 실전성을 보장하는 퀄리티 있는 코드를 만들어 내고, 배포 및 툴을 사용하는 개발 과정에서 효율성을 높입니다.
  3. 비즈니스 로직과 디자인의 분리: 디자인 변경 시 비즈니스 로직에 영향을 주지 않도록, 바인딩 관련 코드의 수정 없이도 디자인을 변경할 수 있어야 합니다.

추가적인 목표

또한, 추후에 보다 많은 요구사항을 만족할 수 있도록 아래와 같은 추가 목표들도 함께 고려해 보았습니다.

  1. 편리한 설정을 위한 Preview 및 디자인 계층 뷰 제공: 사용자가 설정을 보다 쉽게 할 수 있도록 프리뷰 및 디자인 계층 뷰를 통한 편의성을 제공합니다.
  2. 다양한 인터랙션 컴포넌트 제공: 사용자 경험을 풍부하게 만들어줄 다양한 인터랙션 컴포넌트를 제공합니다.
  3. 컴포넌트 Props Interface 관리: 컴포넌트의 속성을 효율적으로 관리할 수 있는 인터페이스를 제공합니다.
  4. 다양한 이벤트 바인딩 지원: onClick 이벤트뿐만 아니라 다른 모든 이벤트 바인딩을 지원하여, 보다 다양한 상호작용을 구현할 수 있도록 합니다.
  5. 외부 모듈 및 컴포넌트 활용 지원: 다양한 외부 모듈과 컴포넌트를 효율적으로 통합하고 활용할 수 있는 방법을 제공합니다.

Figma 플러그인을 통한 HTML/CSS 코드 생성

저희 OROR 프론트엔드 팀은 Figma 디자인을 효율적으로 HTML/CSS 코드로 변환하는 방법을 모색하며, Locofy와 같이 Figma 플러그인 방식으로 해당 기능을 제공하고자 했습니다.

Figma 플러그인의 개념

Figma 플러그인은 Figma가 제공하는 API를 활용하여 개발자들이 원하는 기능을 구현할 수 있게 해주는 강력한 도구입니다. 최근에는 개발자들이 개발 과정에서 Figma를 많이 활용하게 되면서 작업을 도와주는 플러그인들이 다수 등장하고 있습니다.

또한, Figma 플러그인은 웹 생태계에 기반을 두고 있어 자바스크립트를 활용하여 다양한 기능들을 구현할 수 있습니다. 이는 웹 프론트엔드 개발자가 많은 저희 팀이 플러그인을 수월하게 개발할 수 있는 훌륭한 기반이 되었고, 저희는 Figma 플러그인 생태계의 이러한 장점을 활용하여 사용자에게 친숙하고 효율적인 도구를 제공하고자 했습니다.

HTML/CSS 코드 생성

Figma에서 HTML과 CSS 코드를 추출하는 방법은 아래와 같습니다.

  1. 노드 선택 및 속성 추출: Figma 디자인의 기본 단위인 노드를 선택하고 각 노드의 속성을 분석합니다. 노드 타입에는 프레임 노드, 텍스트 노드, 벡터 노드 등이 있으며, 각각 다양한 속성을 가지고 있습니다.
  2. DOM으로의 변환: Figma 노드를 웹의 DOM 요소로 변환하고 필요한 속성들을 CSS 스타일로 추출합니다. 이 과정을 통해 Figma 디자인을 실제 웹 환경에서 사용할 수 있는 HTML/CSS 코드로 변환합니다.
  3. 픽셀 퍼펙트한 코드(Pixel Perfect Code) 목표: Figma의 디자인 요소와 속성을 CSS의 개념과 속성으로 정확하게 대체할 수 있도록 합니다. 이는 ‘픽셀 퍼펙트’ 한 HTML/CSS 코드를 생성하는 것을 목표로 합니다.

디자인과 코드의 정확한 매칭

우리의 목표는 Figma 디자인과 코드가 정확히 일치하는 것이었습니다. 이를 위해, Figma의 디자인 개념과 속성을 깊이 있게 연구하고, 이를 CSS로 올바르게 변환하는 방법을 탐구했습니다. 이러한 접근은 추후 Figma 디자인의 복잡한 요소들을 정확하고 효율적으로 웹 환경에 구현할 수 있게 해 주었습니다.

이제 본격적으로 아래의 내용들을 통해, Figma 플러그인을 활용하여 HTML/CSS 코드를 생성하는 방법과 Figma 디자인을 웹 코드로 정확히 변환하는 과정을 설명드리겠습니다. 이러한 과정을 하나씩 살펴보며 독자분들이 프론트엔드 개발 효율성을 크게 향상하는 인사이트를 얻을 수 있을 것입니다.

Pixel Perfect를 위한 Figma 디자인 시스템 이해하기

프론트엔드 개발 과정 중 디자인을 코드로 변환하는 절차에서 ‘픽셀 퍼펙트’를 달성하는 것은 중요한 목표 중 하나입니다. 이를 위해, 먼저 Figma 디자인 시스템을 깊이 있게 이해하고, 이를 어떻게 효과적으로 CSS 코드로 변환할 수 있는지 탐색해 보겠습니다.

Figma Property to CSS Property

Figma에서 디자인을 구성할 때 사용하는 주요 요소들 중 하나는 노드의 기본 정보입니다. 예를 들어, 아래와 같이 프레임 정보에는 X, Y 위치, 너비(width), 높이(height), 회전(rotate), 테두리 둥근 정도(border radius) 및 내용물 잘림 여부(clip) 등이 있습니다.

				
					.Frame {
 /* Use Absolute Position */
 position: absolute;
  /* X */
 left: -8901px;


 /* Y */
 top: 2336px;


 /* W */
 width: 409px;


 /* H */
 height: 308px;


 /* Rotation */
 transform: rotate(90deg);


 /* Corner radius */
 border-radius: 0;


 /* Clip content */
 overflow:hidden;
}

				
			

이러한 요소들은 CSS 속성과 직접적으로 연결됩니다. 다행히도 Figma의 속성들과 CSS 속성들 사이에는 1대 1 대응 관계가 많습니다. 하지만 Figma에서 절댓값으로 표현된 포지셔닝 값(예: -8901px)은 CSS에서 직접 사용하기 어려운 경우가 있습니다. 예시로 음수인 -8901px의 값을 그대로 사용한다면 실제 화면에는 아무것도 보이지 않을 것입니다. 

이 문제를 해결하기 위해, 절댓값을 상대 좌표로 변환하여 CSS에 적용할 수 있는 방법을 고려해야 합니다. 예를 들어, 아래와 같이 선택된 Figma 노드에서 상대적인 위치, 크기 등의 속성을 추출하면 이를 CSS 스타일로 변환하는 코드를 작성할 수 있습니다.

				
					// 선택된 Node를 가져옴
const node = figma.currentPage.selection[0]


// 속성 추출
const rect1 = node.parent.absoluteBoundingBox
const rect2 = node.absoluteBoundingBox


const x = rect2.x - rect1.x
const y = rect2.y - rect1.y


const width = node.width
const height = node.height


// CSS 스타일 생성
addStyle("position", "absolute")
addStyle("top", px(y))
addStyle("left", px(x))
addStyle("width", px(width))
addStyle("height", px(height))

				
			

이와 같은 접근 방식을 사용하여, Figma의 디자인 요소를 CSS로 효과적으로 변환할 수 있습니다. 이는 ‘픽셀 퍼펙트’ 한 결과를 달성하는 데 중요한 역할을 합니다.

Figma의 AutoLayout: CSS Flexbox로의 전환

Figma의 AutoLayout은 프론트엔드 개발 과정 중 디자인을 코드로 변환하는 과정에서 중요한 역할을 합니다. AutoLayout은 Figma 내에서 자동으로 요소를 배치하는 기능으로, 개발자들에게 큰 편의를 제공합니다. 이 기능을 이해하고 CSS의 Flexbox로 올바르게 변환하는 것은 효율적인 웹 개발을 위한 필수적인 과정입니다.

AutoLayout의 중요성

  • 자동 배치 기능: AutoLayout은 요소들을 자동으로 배치해 주는 기능으로, 복잡한 디자인을 간단하게 구현할 수 있게 해 줍니다.
  • Flexbox와의 상호작용: Flexbox는 현대 웹 개발에서 매우 중요한 CSS 기술입니다. Figma의 AutoLayout 기능은 Flexbox와 유사한 점이 많아 Figma 디자인을 Flexbox를 사용하여 웹에 적용하기 용이합니다.

Figma AutoLayout을 CSS Flexbox로 변환하기

Figma의 AutoLayout 기능을 CSS Flexbox로 변환하는 과정은 아래와 같습니다.
  1. Flexbox 사용: display: flex;를 사용하여 Flexbox를 활성화합니다.
  2. Flow 설정: flex-flow: row; 또는 column, wrap으로 요소의 흐름 방향을 설정합니다.
  3. 정렬 방식 설정: align-itemsjustify-content를 사용하여 요소들의 정렬 방식을 설정합니다.
  4. 간격 조정: gap 속성 또는 justify-content: space-between;을 사용하여 요소 간 간격을 조절합니다.
  5. 패딩 적용: padding 속성을 사용하여 요소의 내부 여백을 설정합니다.
				
					.AutoLayout {
 /* 1. Flexbox 사용 */
 display: flex;


 /* 2. Flow 설정 */
 flex-flow: row; /* 또는 column, wrap */


 /* 3. 정렬 */
 align-items: flex-start; /* 또는 center, baseline, flex-end */
 justify-content: flex-start; /* 또는 center, flex-end */


 /* 4. 간격 */
 gap: 8px;
 /* 또는 */ justify-content: space-between; /* Gap: Auto */


 /* 5. 패딩 */
 padding: 10px 20px 30px 40px; /* 위 오른쪽 아래 왼쪽 */
}

				
			

이러한 변환을 통해 Figma의 AutoLayout이 가진 특성을 그대로 CSS에서 구현할 수 있으며, 이는 디자인과 코드 간의 일관성을 유지하면서도 ‘픽셀 퍼펙트’ 한 결과를 얻는 데 핵심적인 역할을 합니다.

tip: 현대 CSS에서 가장 중요한 요소 중 하나는 Flexbox이며, OROR Forge에서 AutoLayout으로 제작한 디자인은 모두 Flexbox로 변환 결과가 만들어집니다. 그렇기에 원본 디자인을 변환하여 생성되는 코드의 퀄리티를 높이기 위해서는, 대부분의 디자인 작업이 AutoLayout으로 구현되어 있으면 좋습니다. 따라서 디자이너와의 소통을 통해, 가급적 AutoLayout을 사용해 디자인을 생성하는 것으로 협의가 된다면 변환 시 높은 퀄리티의 코드를 생성할 수 있습니다.

Figma AutoLayout to CSS Flexbox

Figma의 AutoLayout과 CSS Flexbox는 유사한 기능을 제공하지만, 몇 가지 중요한 차이점이 있습니다. 이러한 차이점을 이해하는 것은 Figma 디자인을 정확하게 웹 개발에 정확히 적용하기 위한 중요한 부분입니다.

1. Gap: Auto

  • Figma AutoLayout: Figma의 AutoLayout에서 gap: auto는 컨텐츠의 크기에 따라 자동으로 간격을 조정합니다. 특히 자식 요소가 하나뿐인 경우 가운데 정렬을 하도록 설계되어 있습니다.
  • CSS Flexbox: CSS에서는 justify-content: space-between;을 사용하여 유사한 기능을 구현할 수 있습니다. CSS에서는 아래처럼 구현할 수 있습니다.
				
					.gap-auto { justify-content:space-between; align-content:space-between; }
.gap-auto:only-child { margin:auto; }

				
			

2. 음수 Gap

  • Figma AutoLayout: Figma는 음수 값의 gap을 지원하여, 요소들이 겹치도록 배치할 수 있습니다. 이는 특정 디자인 요구사항에 매우 유용할 수 있습니다.
  • CSS Flexbox: CSS에서는 음수 gap를 지원하지 않기 때문에 gap 값이 음수라면 다른 CSS를 작성해야 합니다. 이는 margin 속성과 CSS 선택자 (> * + *)를 사용하여 구현할 수 있습니다. 예를 들어 .hgap--10을 사용하여 가로 방향의 음수 gap을 만들 수 있습니다.
				
					.hgap--10 > * + * {
 margin-left: -10px;
}


.vgap--10 > * + * {
 margin-top: -10px;
}
				
			

3. Canvas Stacking: First on Top

  • Figma AutoLayout: Figma의 “First on Top” 기능은 캔버스에서 처음 배치된 요소가 상단에 표시되도록 합니다. 이는 특정 디자인 요구사항에서 중요할 수 있는 기능입니다.
  • CSS Flexbox: CSS에서는 이와 정확히 일치하는 기능이 없습니다. 하지만 z-index를 사용하여 유사한 효과를 낼 수 있습니다. 그러나 이는 사이드 이펙트를 유발할 수 있으므로 주의가 필요합니다.
				
					/* 예시: First on Top */
.FirstOnTop > *:nth-child(1) { z-index: 10; }
.FirstOnTop > *:nth-child(2) { z-index: 9; }
/* 추가 순서에 따른 z-index 설정 */
				
			

이러한 차이점들을 고려하여 Figma의 AutoLayout을 CSS Flexbox로 변환할 때는 적절한 조정과 추가적인 구현이 필요합니다. 이를 통해 Figma의 디자인을 정확하게 웹 개발에 적용할 수 있게 됩니다.

Auto Resize: Figma의 Sizing 개념을 CSS로 변환하기

Figma에서의 Auto Resize 기능은 디자인 요소의 크기를 자동으로 조절하는 데 중요한 역할을 합니다. 이는 화면 크기나 내용 변경에 따라 유동적으로 반응하는 반응형 웹 디자인을 실현하는 데 필수적입니다.

Figma는 이를 위해, ‘Fixed Width’, ‘Hug Contents’‘Fill Container’로 대표되는 세 가지의 주요 사이징 개념을 제공합니다.

1. Fixed Width

‘Fixed Width’는 지정된 수치대로 엘리먼트의 크기를 고정합니다. CSS에서는 width: 300px;와 같이 간단하게 값을 지정하면 됩니다. 다만, Flexbox 컨테이너 내부에서는 flex-shrink: 0;을 추가해야, 지정된 크기가 유지됩니다.

				
					.fixed-width {
 flex-shrink: 0;
 width: 300px;
}
				
			

2. Hug Contents

‘Hug Contents’는 내부 컨텐츠의 크기에 따라 엘리먼트의 크기가 조정됩니다. CSS에서는 width: max-content;를 사용하여 컨텐츠의 크기를 따라가도록 설정할 수 있습니다.

				
					.hug-contents {
 width: max-content;
}

				
			

3. Fill Container

‘Fill Container’는 부모 엘리먼트의 크기에 따라 엘리먼트의 크기가 조정됩니다. 이는 주로 Flexbox에서 flex: 1; 또는 align-self: stretch;를 사용하여 구현됩니다.

				
					.fill-container {
 flex: 1; /* 메인축 */
 align-self: stretch; /* 교차축 */
}

				
			

Min and Max Width

또한, Figma는 ‘Min Width’와 ‘Max Width’를 통해 엘리먼트의 최소 및 최대 크기를 지정할 수 있도록 합니다. 이는 CSS에서 min-width: 100px;max-width: 600px;과 같이 지정할 수 있습니다.

				
					.min-max-width {
 min-width: 100px;
 max-width: 600px;
}
				
			

이러한 사이징 개념을 이해하고 CSS에 적용함으로써, Figma의 사이즈 디자인을 웹 페이지에 정확하게 반영할 수 있으며, 이는 반응형 웹 디자인 구현에 있어 매우 중요한 부분입니다.

				
					.width-of-figma {


 /* 1. Fixed width */
 flex-shirink: 0;
 width: 300px;


 /* 2. or Hug contents */
 /* width: auto; */
 width: max-content; /* force */


 /* 3. or Fill Container */
 flex: 1; /* 메인축 */
 /* or */ align-self: stretch; /* 교차축 */


 /* 4. Min Width, Max Width */
 min-width:100px;
 max-width:600px;
}

				
			

이러한 조건들을 통해, 아래와 같이 Figma의 속성들을 적절한 CSS의 width로 표현할 수 있었습니다.

				
					const addStyleWidth = (node: FrameNode, addStyle: AddStyle) => {
 const {constraints, layoutSizingHorizontal, absoluteRenderBounds, width: _width, minWidth, maxWidth} = node
 const {horizontal = "MIN"} = constraints ?? {}
 const width = node.type === "Text" ? absoluteRenderBounds?.width ?? _width : _width


 if (isAbsoluteLayout(node) && (horizontal === "STRETCH" || horizontal === "SCALE")) {
 } else if (layoutSizingHorizontal === "HUG") {
 } else if (layoutSizingHorizontal === "FIXED") {
   addStyle("width", px(width))
 } else if (layoutSizingHorizontal === "FILL") {
   if (node.parent.layoutMode === "HORIZONTAL") addStyle("flex", 1)
   else if (node.parent.layoutMode === "VERTICAL") addStyle("align-self", "stretch")
   else addStyle("width", "100%")
 }


 minWidth !== null && addStyle("min-width", px(minWidth))
 maxWidth !== null && addStyle("max-width", px(maxWidth))
}

				
			

Figma Constraints to CSS Position

Figma의 Constraints 기능은 CSS Position 속성을 사용하여 구현할 수 있습니다. Constraints는 요소의 위치를 부모 컨테이너에 대해 상대적으로 정의하는 기능입니다. 이를 CSS에서 구현하기 위해, 다양한 Position 속성과 값을 사용합니다.

Constraints의 핵심 개념

Constraints는 요소의 위치를 정의할 때 아래와 같은 방향 요소들을 고려해야 합니다.

  1. 시작 방향(Left)
  2. 끝 방향(Right)
  3. 좌우 기준(Left and Right)
  4. 가운데 기준(Center)
  5. 비율 기준(Scale)

CSS Position 변환 예시

Figma의 Constraints를 CSS로 변환하는 과정은 아래와 같이 구현할 수 있습니다.

				
					.Constraints {
 position: absolute;
  /* 1. Left */
 left: 10px;


 /* 2. Right */
 right: 10px;


 /* 3. Left and Right */
 left: 10px;
 right: 10px;


 /* 4. Center */
 left: calc(50% + 10px);
 transform: translateX(-50%);


 /* 5. Scale */
 left: 2%;
 right: 2%;
}

				
			

CSS 구현 방식

각 Constraint 유형에 따라, CSS에서는 아래와 같은 방식으로 요소의 위치를 정의합니다.

  • Left: 요소를 왼쪽에서 고정된 위치에 배치합니다.
  • Right: 요소를 오른쪽에서 고정된 위치에 배치합니다.
  • Left and Right: 요소를 양쪽에서 고정하여, 중앙에 배치합니다.
  • Center: calc()transform을 사용하여 요소를 정확히 중앙에 배치합니다.
  • Scale: 퍼센트 값을 사용하여 부모 컨테이너의 크기 변화에 따라 요소의 위치를 동적으로 조절합니다.
				
					const rect1 = node.parent.absoluteBoundingBox
const rect2 = node.absoluteBoundingBox


if (!rect1 || !rect2) {
 return
}


const {horizontal = "MIN", vertical = "MIN"} = node.constraints ?? {}


const x = rect2.x - rect1.x
const y = rect2.y - rect1.y
const right = rect1.x + rect1.width - rect2.x - rect2.width
const bottom = rect1.y + rect1.height - rect2.y - rect2.height


const offsetXFromCenter = rect2.x - rect1.x - (rect1.width / 2 - rect2.width / 2)
const offsetYFromCenter = rect2.y - rect1.y - (rect1.height / 2 - rect2.height / 2)


const percentLeft = (x / rect1.width) * 100
const percentRight = (right / rect1.width) * 100


const percentTop = (y / rect1.height) * 100
const percentBottom = (bottom / rect1.height) * 100


// position: absolute
addStyle("position", "absolute")


// 'CENTER' origin
if (horizontal === "CENTER" && vertical === "CENTER") {
 addStyle("transform", "translate(-50%,-50%)")
} else if (horizontal === "CENTER") {
 addStyle("transform", "translateX(-50%)")
} else if (vertical === "CENTER") {
 addStyle("transform", "translateY(-50%)")
}


// x: 'MIN' | 'CENTER' | 'MAX' | 'STRETCH' | 'SCALE'
switch (horizontal) {
 case "MIN": {
   addStyle("left", px(x))
   break
 }
 case "MAX": {
   addStyle("right", px(right))
   break
 }
 case "CENTER": {
   if (Math.abs(offsetXFromCenter) <= 1) addStyle("left", "50%")
   else addStyle("left", `calc(50% + ${px(offsetXFromCenter)})`)
   break
 }
 case "STRETCH": {
   addStyle("left", px(x))
   addStyle("right", px(right))
   break
 }
 case "SCALE": {
   addStyle("left", percent(percentLeft))
   addStyle("right", percent(percentRight))
 }
}

				
			

Figma Text to CSS

Figma의 텍스트 속성 대부분은 1:1로 CSS에 쉽게 매핑할 수 있습니다. 단, Figma와 CSS의 디자인은 텍스트 정렬 방식에서 차이가 있습니다.

Figma 텍스트 속성과 CSS 매칭 예시

Figma에서 제공하는 텍스트 속성과 그에 해당하는 CSS 속성의 예시는 아래와 같습니다.

  • 폰트 크기(Font Size): Figma의 fontSize는 CSS의 font-size와 일치합니다.
  • 줄 높이(Line Height): Figma의 lineHeight는 CSS의 line-height와 매칭됩니다.
  • 문자 간격(Letter Spacing): Figma의 letterSpacing는 CSS의 letter-spacing과 동일합니다.
  • 폰트 두께(Font Weight): Figma의 fontWeight는 CSS의 font-weight에 해당합니다.
  • 폰트 스타일(Font Style): Figma의 fontName과 CSS의 font-familyfont-style이 연결됩니다.

Figma 텍스트 정렬

Figma에서는 다양한 텍스트 정렬 옵션이 제공되지만, CSS에서는 이와 정확히 일치하는 속성이 없습니다. Figma의 텍스트 정렬 방식은 크게 ‘자동 너비(Auto-Width)’, ‘자동 높이(Auto-Height)’, ‘고정 크기(Fixed-Size)’ 그리고 ‘수직 정렬(Vertical Alignment)’로 나눠볼 수 있습니다.

아래 이미지와 같은 Figma의 텍스트 정렬 기능들은 CSS와 1:1로 매칭이 되는 것이 아니므로, 각각의 특징을 잘 반영해야 합니다.

자동 너비(Auto-Width)

  • Figma의 자동 너비는 텍스트의 길이에 따라 너비가 조절됩니다.
  • CSS에서 이를 구현하기 위해서는 width: max-content;white-space:nowrap;를 함께 사용합니다. 이와 같이 구현 시, 텍스트가 줄바꿈 없이 한 줄로 표시되며 그 길이에 따라 너비가 결정됩니다.
				
					.AutoWidth {
 white-space: nowrap;
 width: max-content;
}

				
			

자동 높이(Auto-Height)

  • Figma에서 자동 높이는 텍스트의 내용에 따라 높이가 조절됩니다.
  • CSS에서의 기본 설정이 height: auto;이기 때문에, 특별히 높이를 지정하지 않으면 자동으로 높이가 조절됩니다. 이 경우 너비를 지정해야 텍스트가 해당 너비 내에서 자동으로 높이를 조절합니다.
				
					.AutoHeight {
 width: 200px;
 /* height: auto;*/
}

				
			

고정 크기(Fixed-Size)

  • 고정 크기는 너비와 높이 모두 사전에 정해진 값으로 고정됩니다.
  • CSS에서는 widthheight 속성을 사용하여 이를 구현합니다.
				
					.FixedSize {
 width: 200px; /* Fixed Width */
 height: 200px; /* Fixed Height */
}

				
			

수직 정렬(Vertical Alignment)

  • Figma에서 수직 정렬은 텍스트의 상단, 중단, 하단 정렬을 결정합니다.
  • CSS에서는 기본적으로 텍스트가 상단에 정렬됩니다. 중단과 하단 정렬은 CSS에 직접적인 속성이 없으므로 Flexbox를 사용하여 구현합니다.
				
					.Text-Vertical-Center {
 display: flex;
 flex-flow: column;
 justify-content: center;
}


.Text-Vertical-bottom {
 display: flex;
 flex-flow: column;
 justify-content: flex-end;
}

				
			

이러한 방식을 통해 Figma에서 설정한 텍스트 정렬을 CSS에서 구현할 수 있습니다. 이는 웹 페이지에서 디자인의 정확성을 보장하는 데 중요한 역할을 합니다.

텍스트 말 줄임(Text Truncate)

텍스트 말 줄임은 CSS에서도 잘 알려진 기능입니다. 이 기능은 긴 텍스트를 보여주는 영역이 제한되었을 때, 텍스트의 나머지 부분을 줄임표(…)로 처리하는 방법입니다.

한 줄 말 줄임: CSS에서 text-overflow: ellipsis;white-space: nowrap;를 조합하여 구현할 수 있습니다.

				
					.truncate {
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
 }

				
			

여러 줄 말 줄임: CSS의 -webkit-line-clamp 속성을 사용하여 구현할 수 있으며, 이는 웹킷 기반의 브라우저에서 지원됩니다.

				
					.truncate-multiline {
   display: -webkit-box;
   -webkit-line-clamp: 3; /* 줄임을 적용할 줄 수 */
   -webkit-box-orient: vertical;
   overflow: hidden;
 }

				
			

Figma의 Fill, Gradient 및 Effect: CSS로 구현하기

Figma의 다양한 디자인 요소를 CSS로 변환하는 것은 프론트엔드 개발에서 매우 중요한 부분입니다. 여기서는 특히 Figma의 Fill(채우기), Gradient(그라데이션), Effect(효과) 등을 CSS로 어떻게 구현할 수 있는지 살펴보겠습니다.

Figma의 Fill을 CSS로 구현

  • Figma의 Fill 옵션을 사용하면 객체에 색상, 그라데이션 등을 적용할 수 있습니다.
  • CSS에서는 background 속성을 사용하여 이와 유사한 효과를 낼 수 있습니다. 예를 들어 단색 채우기는 background-color로, 이미지나 그라데이션 채우기는 background-image로 구현할 수 있습니다.

Figma의 Gradient를 CSS로 구현

  • Figma에서 그라데이션은 선형(linear) 또는 방사형(radial) 등으로 적용될 수 있습니다.
  • CSS에서는 linear-gradient 또는 radial-gradient 함수를 사용하여 비슷한 효과를 구현할 수 있습니다. 각 함수에는 시작 색상, 끝 색상, 그리고 그라데이션의 방향이나 모양을 지정할 수 있는 인자들이 포함됩니다.

Figma의 Effect를 CSS로 구현

  • Figma의 Effect 옵션을 통해 객체에 그림자, 블러 등의 시각적 효과를 추가할 수 있습니다.
  • CSS에서는 box-shadow, filter 등의 속성을 사용하여 이러한 효과를 구현할 수 있습니다. 예를 들어, 그림자 효과는 box-shadow로, 블러 효과는 filter: blur() 함수로 구현할 수 있습니다.

결과 화면: Preview

이 과정을 통해 Figma의 모든 디자인 개념을 CSS로 변환할 수 있으며, 최종적으로는 Figma 디자인에 충실한 웹 페이지를 제작할 수 있습니다.

<실제 HTML과 CSS로 구현된 결과물>

끝으로…

Figma의 디자인 개념을 따라가면서 개발에 필요한 코드를 작성하다 보니, Figma가 디자이너에게 UI를 디자인을 할 수 있는 도구이면서 동시에, 웹뿐만 아니라 생각할 수 있는 모든 디자인을 Web, iOS, Android와 같은 다양한 UI 환경을 고려하여 디자인할 수 있도록 구현된 것을 알 수 있었습니다. 아울러 Figma는 개발에 대한 개념을 포함하는 반응형 디자인을 구현할 수 있도록 고심하여 구현된 도구인 점도 알 수 있었습니다. Figma가 디자인과 개발의 중간 지점에 있는 도구인 만큼, OROR Forge 구현 과정에서 Figma의 디자인 개념을 이해해 보는 경험은 디자인과 개발 그리고 웹과 앱을 넘나드는 UI 디자인을 종합적으로 파악해 보는 정말 뜻깊은 기회였습니다.

지금까지 소개했던 개념들에서, 어렴풋이 알고 있었던 Figma의 디자인 개념을 코드를 통해서 확실히 이해할 수 있는 계기가 되었으면 좋겠습니다. 기회가 된다면 HTML과 CSS뿐만 아니라 iOS와 Andoird 코드를 생성하는 기능 또한 구현하여, 독자분들에게 Figma의 디자인 개념이 더 잘 와닿도록 소개할 수 있으면 좋겠습니다. 모쪼록 이 글이 웹 개발자가 Figma 디자인을 이해하고, 그 디자인을 개발 코드로 옮기는 과정 전반에 대한 이해를 높일 수 있기를 바랍니다.

이제 이렇게 생성된 코드가 실제 웹 개발에 사용될 수 있기 위해서는 실전 프레임워크에서 사용할 수 있는 수준의 코드가 되어야겠지요. 그래서 앞으로 이어질 2부에서는 이렇게 만들어진 CSS 코드를 실전 개발에 사용할 수 있도록, HTML과 CSS를 React와 TailwindCSS 코드로 전환하는 과정에 대해 이야기를 하고자 합니다. 다음편도 많은 기대를 부탁드립니다.

written by teo.v
edited by June.6

📚관련 글 목록:

카카오톡 공유 보내기 버튼

Latest Posts

큐라스: 메시지 광고 추천 플랫폼 / 제4회 Kakao Tech Meet

12월 12일에 진행한 제4회 Kakao Tech Meet의 발표 영상과 발표자 이야기를 공유합니다. https://youtu.be/OXQ-uk7tE94 #메시지광고추천플랫폼 #광고추천서비스 #mlops #추론시스템 #데이터파이프라인 #대용량트래픽 발표자 Cookie(김영찬님), Eric(신호석님)