목표
CSS의 기본 구조와 문법
CSS로 글자 꾸미기
CSS로 박스 꾸미기
CSS Document Layout
CSS Reset
CSS Visibility
CSS Application Layout - Flexbox
CSS Application Layout - Overlay와 Position
Overflow
1부: Figma 디자인을 CSS로 옮기기 - HandOff (이게 핵심 킬러 컨텐츠가 되어 줄거라고 생각합니다.)
2부: 반응하는 디자인 만들기
사용자의 행동에 반응하기
화면 크기에 반응하기
시간에 따라 반응하기
#CSS
#CSS/1_머리말
현대사회에서 특히 개발 쪽 자료는 책보다는 인터넷에 훨씬 더 많은 자료가 있다고 생각을 합니다. 학습을 하는 거라면 지금은 인터넷 강의를 통해서도 배울 수가 있고, 레퍼런스와 같은 부분들은 책보다 인터넷으로 찾는 게 훨씬 더 검색도 효율적이고 용이할 거라고 생각을 합니다.
그러면 IT서적, 즉 책이 갖춰야 될 어떤 덕목은 무엇일까라고 생각을 해보면 작가만이 알고 있는 잘 짜여진 체계와 흐름을 잘 담아서 전달하여 좋은 체계를 공유해주는 것이라고 생각을 했습니다.
그래서 이 책 한 권에 어떤 식으로 구성을 하고 어떤 순서로 지식들을 전달하고 연결할 수 있을지 많이 고민을 했습니다. 그리고 의도적으로 중요하지 않은 부분들을 깊게 설명하지 않으려고 했습니다.
이 책에서는 전문적인 지식을 깊이 다루기보다는 실무자의 입장에서 실제로 더 유용하고 실용적인 정보들을 골라내어 핵심만 담아내고자 하였습니다.
그렇지만 완전 CSS를 처음 접하는 사람에게도 유용하고 앞으로 이런식으로 공부를 해야하는 구나 하는 로드맵의 어떤 역할도 되고 싶었습니다.
또한, 일반적인 CSS 교재와는 다른 차별화 역시 주고 싶었습니다. 그래서 일반적인 CSS 교재에서 배우는 순서나 구성을 조금 비틀었고, 필요없다고 생각하는 부분은 과감히 버렸습니다.
자주 사용하는 20%가 전체의 약 80%를 차지한다는 파레토의 법칙이 있습니다. CSS에서도 마찬가지입니다. 실무에서는 실제로 자주 사용되는 것들은 몇 가지 정해져있습니다. 오히려 고급기법이나 난이도가 있는 내용들은 실전에는 잘 쓰이지 않습니다.
그래서 자주 쓰이고 중요한 부분들을 먼저 책의 초반부에 몰아두어 공부를 하다가 말더라도 이 책의 어떤 유용함을 다 알 수 있도록 만들고자 했습니다.
그리고 학습서적인만큼 자가 테스트를 할 수 있는 법 그리고 이 책에서 이 장에서 무엇을 공부해야 되는지 내가 무엇을 남겨야 되는지 알 수 있도록 구성을 하고자하였습니다.
이 책을 접할 때는 한 장 한 장 깊게 들어가려고 하지 마시고 최대한 다독한다는 마음으로 최대한 가볍게 읽어주세요. 이야기 형식으로 많이 읽을거리들을 많이 만들어두었습니다. 전체적 체계와 구성을 머리속에 넣어 두는 것을 목적으로 해주세요.
그래서 실습과 학습내용들을 포함하고 있지만 대부분 읽을 거리와 이론 위주로 준비를 했습니다. 이런 내용들이 머릿속에 있으면 내가 비슷한 상황이 발생했을 때 언제든지 찾아낼 수 있는 지도와 같은 역할이 되어 줄 수 있기를 바랍니다.
프론트엔드 개발자라면 한 번쯤은 CSS를 깊게 배워야 합니다. 한번 배우고 나면 잘 배우지 않는 CSS인데 기왕 배울 거 한번에 잘 배우면 좋지 않을까요?
이 책이 그런 역할이 되어주기를 바랍니다.
감사합니다.
#CSS/1_머리말
웹은 문서를 공유하기 위한 용도로 탄생했습니다. 이후 이 문서들을 조금 더 잘 보여주기 위해서 혹은 개성을 위해서 디자인적인 요소들을 추가하고자 했고, 이는 디자인과 컨텐츠가 뒤섞여 아주 복합한 형태의 HTML을 만드는 문제가 발생했습니다. 이러한 문제를 해결하고자 문서에서 컨텐츠와 서식을 분리하고자 하는 과정에서 서식만을 기술하는 CSS라는 언어가 탄생하게 됩니다.
문서를 꾸미기 위한 목적에서 만들어진 CSS이지만, 웹은 문서에만 그치지 않고 사용자와의 인터렉션이 더 많아지는 웹 서비스로 그리고 웹 어플리케이션으로 발전을 하게 되었습니다. 그러다 보니 CSS의 역할은 본래의 목적을 넘어 확장을 요구받았습니다.
그러나 각 브라우저마다 동작방식이 달랐고 심지어 같은 인터넷 익스플로러에서도 6, 7, 8등 버전마다 각기 다른 CSS 환경들은 CSS의 발전을 더디게 만들었습니다. 그러다 보니 현재의 문서를 만드는 방식을 온갖 방법으로 응용하여 화면을 만드는 자기들만의 방법들이 등장하기 시작했습니다.
급격하게 성장한 웹과 그것을 따라잡기 위해 더 성장을 해야하는 CSS는 성장통을 겪으면서 필요한 스펙들을 만들어 보았지만, 웹은 이렇게 한번 만들어진 스펙을 버릴 수 없기 때문에 어떤 부분은 좋고 어떤 부분은 부족하고 어떤 부분은 해결된 채로 어떤 부분은 아직도 계속 방법을 찾아내는 중으로 계속 변하고 있습니다.
웹은 점점 거대 산업으로 발전을 하게 되면서 HTML, CSS 등을 배우려고 하는 사람들도 굉장히 많아졌습니다. 그러다 보니 학습컨텐츠가 시대를 따라잡지 못한 채 계속 확대 재생산되면서 이제는 잘 쓰이지 않는 예전 방식를 공부한다거나 예전에는 중요했지만 지금은 중요해지지 않은 부분들이 여전히 중요한 것 처럼 설명되고있어 현재와는 맞지 않는 괴리감이 느껴집니다.
CSS가 어려운 점 하나로 알려진 "같은 화면을 만들 수 있는 수많은 방법들이 존재한다"는 문제점은 입문자나 초보자들에게는 어떤 것이 더 나은 방법인지를 모르게 합니다. 그냥 화면이 나오는 것에 만족을 하고 예전의 방식을 그대로 학습하게 됩니다.
다행히(?) CSS의 스펙이 변화하는 속도는 점점 줄어 들고 있지만, 같은 스펙을 가지고도 사람들이 같은 화면을 어떻게 하면 더 효율적으로 만들 수 있는지 어떤 식으로 CSS를 관리를 하면 좋을지 방법론등에 대해서는 예전보다 더 많이 발전을 하고 있는 상태입니다.
그래서 저는 여러분이 기본적으로 학습한 CSS의 스펙을 실제로 사용하는 방법들 가운데 2022년 지금 시대에 맞는 연구가 된 트렌드한 방법을 알려드리고 싶었습니다. 어떤 것들은 제가 연구한 방법으로 다소 주관적일수도 있는 부분들은 근거를 들어 왜 좋은지도 설명을 함께 드릴 예정입니다.
아울러 왜 이렇게 하는게 더 좋은 방법이 되었는지 간단한 역사와 내용을 짚어 볼 생각입니다. 흐름을 이해하고자 알려드리는 이야기이기 때문에 지나간 방법에 대한 자세한 기술적인 이야기는 일부러 하지 않을 생각입니다.
15년 넘게 발전한 CSS의 내용 중에서 지금 당장 필요한 것들만 최대한 추려서 제가 생각하는 지금의 Best Practice를 공유하려 합니다.
이 책이 현대 CSS의 체계를 빨리 이해하는데 도움이 되기를 바랍니다.
#CSS
#CSS/1_머리말
이 책에서는 다음과 같은 특징을 중심으로 작성하였습니다.
첫째, 이 책은 CSS의 역사를 바탕으로 입문 개념부터 시작하여 핵심 및 고급 개념으로 넘어가면서 점진적으로 CSS 개념을 학습할 수 있도록 구성하고자 하였습니다. 이러한 구성을 통해 입문자나 초급자, 고급자까지 원하는 부분부터 학습을 할 수 있게 하면서 동시에 복잡한 CSS 개념을 더 쉽게 이해하고 순서대로 지식을 쌓을 수 있도록 하였습니다.
둘째, 이 책은 CSS의 핵심 개념에 초점을 맞추고 자주 사용하지않는 기능은 과감히 생략하였습니다. 더 자세한 정보는 인터넷에서 얼마든지 찾아서 볼 수가 있습니다. CSS가 진화해오는 과정에서 필요하다고 생각해서 만들었지만 잘 사용하지 않는 기능이나 속성들이 많이 생겼습니다. 중요하지 않은 세부 사항에 얽매이지 않고 가장 중요한 CSS 개념을 빠르게 이해할 수 있도록 작성하였습니다.
셋째, 이 책은 실제 웹 개발 프로젝트에서 CSS를 사용하기 위한 실용적인 팁과 모범 사례를 제공합니다. 사전이나 레퍼런스식의 정보가 아니라 실제 지난 10년간의 CSS의 변화과정을 몸으로 체험하고 실제 작업 경험을 기반으로 하며 학문이 아니라 실용적인 관점에서 작성하여 CSS를 효과적이고 효율적으로 사용하는 데 도움이 되고자 하였습니다.
넷째, 이 책은 학습서적인 만큼 혼자서 공부할 수 있도록 실습과 실용적인 예제와 같은 기능을 포함하여 스터디용으로 사용 할 수 있도록 작성하였습니다. 여러분들은 이 책을 순서대로 다 읽고 나면 CSS를 사용하여 잘 디자인되고 잘 구성된 웹 페이지를 만들 수 있게 될 것입니다.
CSS는 학문보다는 운동과도 같아서 기능의 이해보다 숙달이 훨씬 더 중요한 분야입니다. 꼭 주어진 실습과제를 진행해보면서 몸소 체험하고 본인만의 Best Practice를 정립하고 익숙해지기를 바랍니다.
이 책은 입문자를 대상으로 하는 책이지만 CSS만을 중심으로 다룹니다. 그러기에 코드 에디터나 환경설정, HTML에 대한 기초등에 대한 이야기는 하지 않습니다.
그런 부분들은 인터넷을 통해서 최신의 방식으로 세팅을 하는 것을 권장합니다.
(@TODO: 어떤식으로 공부하면 좋을지에 대한 이야기를 적어 주는 것도 좋을 듯하다.)
#CSS
#CSS/1_머리말
CSS는 HTML에서 스타일을 분리하여 디자인과 레이아웃을 쉽게 다룰 수 있도록 만들어진 스타일 시트 언어로, 웹 페이지의 구조와 스타일을 분리하여 코드를 간결하게 하고 유지보수를 용이하게 하기 위해 개발되었습니다.
1장<역사편>에서는 지금까지 CSS의 지난 역사를 돌아보면서 CSS가 어떻게 태어났고, 어떤 문제를 해결하고자 했으며, 그 뒤로 어떤 발전의 방향성을 가졌는지 알아보면서 우리가 무엇을 어떻게 배워야할지 생각해볼 수 있는 배경지식을 설명합니다.
2장<입문편>에서는 이러한 CSS의 기본적인 구문과 특징을 소개합니다. CSS는 UI 디자인을 구현하는 데 있어 다른 언어에 비해 간결하고 직관적인 문법과 유연한 방식을 제공하는 매우 유용한 언어로 설계되었습니다. 그래서 CSS를 사용하면 웹 페이지의 레이아웃, 색상, 글꼴 등 다양한 디자인 요소를 쉽게 구현할 수 있습니다.
하지만 다른 언어도 그렇듯 CSS 역시 시간이 지나고보니 최초의 설계에서 몇 가지 결점이 드러났습니다. 대표적인 예로 Global Scope와 Specificity 기반의 스타일 우선순위 규칙은 지금까지도 CSS 작성을 어렵고 복잡하게 만들고 있습니다. 이미 만들어진 스펙은 되돌리기가 힘들기 때문에 이러한 CSS의 특징을 이해하고 문제점을 극복하기 위해 적절한 방법을 찾는 것이 중요합니다.
웹은 문서를 공유하기 위해 시작되었으며, CSS는 이러한 문서를 꾸미기 위해 만들어졌습니다. 하지만 웹이 성장하면서, 문서뿐만 아니라 서비스와 어플리케이션을 위한 웹의 역할이 확장되면서 CSS 역시 이러한 고도화를 요구받았습니다. 지속적인 업데이트를 하지 못하는 인터넷 익스플로러의 구조적인 문제와 더불어 CSS의 발전 속도가 변화를 따라잡지 못했기에 그 당시 따라서 개발자들은 원하는 레이아웃을 만들기 위해 문서를 꾸미기위한 다양한 속성들을 조합하는 트릭을 사용하게 되었습니다. 이 과정에서 동일한 화면을 만들기 위한 다양한 방법과 트릭이 생겨나면서, 어떤 방법이 더 적절한지 판단하기 어렵게 되었습니다.
3장 <핵심편>에서는 이러한 과도기적으로 만들어졌던 속성들을 추려내고 핵심 속성을 통해 디자인을 만드는 Best Practice를 설명하려고 합니다. 이를 통해 여러분들은 더욱 효과적이고 핵심적인 CSS 작성 방법을 습득할 수 있게 될 것입니다. 이제 인터넷 익스플로러는 퇴출이 되었고 flexbox를 비롯한 레이아웃을 다루기 위한 좋은 모듈들이 정립되었지만, "여전히 CSS로 같은 화면을 만들기 위해서 여러가지 방법이 존재한다. "라고 하는 것은 저마다 다른 방식으로 CSS를 작성하게 되면서 CSS를 어렵게 만드는 이유가 되고 있습니다. CSS에서 가장 많이 쓰고 필수적인 스펙을 골라 Figma라고 하는 디자인툴의 개념을 기반으로 특정 화면을 만들기 위한 최적의 방법을 설명합니다.
4장 <심화편>에서는 CSS의 문제와 그 해결책, 다양한 도구들이 생겨나는 맥락과 방향성, 그리고 발전 방향에 대해 자세하게 설명하고 있습니다. 현대 웹 생태계는 계속해서 성장하고 있으며, 이에 따라 CSS도 더욱 복잡해지고 있습니다. 이러한 상황에서 단순한 CSS만으로는 충분하지 않기 때문에, CSS 방법론, CSS 전처리기, CSS Module, CSS in JS, Atomic CSS 등과 같은 현재 다양한 CSS 도구들이 개발되고 있습니다. 이제 CSS로 개발하기 위해서는 이러한 도구들을 알고 사용하는 것이 중요한 선택이 되었습니다. 이 책에서 특정한 라이브러리를 선택해 주지는 않지만 이러한 맥락을 이해함으로써 향후 새로운 기술이나 도구가 출시되더라도 선택 기준을 명확히 하고 더 나은 방향성을 이해할 수 있도록 하고자 하였습니다.
CSS는 오랜 역사와 급격한 변화를 거쳐왔습니다. 이에 따라 많은 트릭과 이야기들이 생겨나게 되었습니다. 그렇기에 이 책은 CSS 전체를 완벽하게 다루는 가이드보다는 실무에서 꼭 알아야 할 핵심적인 내용을 선별하여 설명하고자 하였고 중요하지 않은 부분은 의도적으로 작성하지 않으려 하였습니다.
5장<확장편>에서는 부록의 형태로 다뤄볼 예정입니다. 핵심적인 기술은 아니지만 알고 있으면 좋거나 흥미로울만한 내용을 준비해보았습니다. 이 책을 통해 여러분은 CSS의 핵심 내용뿐만 아니라 더 깊이 있는 이해와 흥미로운 이야기들까지 함께 배울 수 있을 것입니다.
#CSS
#CSS/1_머리말
웹은 문서를 공유하기 위해서 만들어졌습니다. 그리고 문서를 조금 더 잘 보여주기 위해서 서식이 만들어졌습니다. 이러한 서식과 데이터가 복잡하게 공존하게 되면서 서식과 컨텐츠를 분리해야겠다는 의도에서 CSS가 탄생하게 되었습니다.
초기에는 문서와 서식을 잘 분리해서 보다 적은양의 코드를 통해서 같은 컨텐츠를 다양한 서식을 적용할 수 있도록 발전을 하였습니다.
그러나 웹 산업이 급격히 발전을 하게 되면서 웹은 단순히 문서의 역할을 너머 서비스와 어플리케이션의 형태로 발전을 하게 되었습니다.
문서에서 어플리케이션까지 웹 서비스의 범위가 확장이 됨에 따라 CSS에도 여러가지 요구사항들이 생겨났고 그에 맞는 여러 가지 좋은 스펙들이 발명이 되었습니다. 또한 그 과정에서 여러가지 시행착오를 겪기도 했었습니다. 특히 문서을 만들기 위해서 시작된 설계를 바탕으로 이후 어플리케이션을 위한 추가 방안을 마련하는 과정이 더욱 그랬습니다. 이렇게 이미 한번 만들어진 스펙은 되돌릴수가 없기에 좋았던 부분과 그렇지 못한 부분들을 우리는 함께 사용하고 있습니다.
또한 당시에는 시대에 맞게 의도대로 설계를 했지만 웹 산업이 급격하게 발전을 하면서 생겨난 새로운 요구사항을 이미 만들어진 스펙이나 설계가 못 따라오는 시기가 존재했고, 그 안에서 어떻게든 방법을 찾다 보니 의도와는 다른 방식으로 CSS 스펙을 차용해서 화면을 만들게 되었습니다.
또한 이렇게 우회해서 해결하는 방식들이 Tip에서 출발해 하나의 정석(?) 이 되어 공부를 해야하는 것이 되고 이런것들이 웹 문서로도 커리큘럼으로도 재생산이 되게 됩니다.
그리고 안타깝게도 최초 문서를 위해 설계된 방법들은 여전히 어플리케이션을 제작하기 위한 개념과는 충돌하는 부분이 존재를 하고 있습니다. 이러한 부분들은 현대 산업에서 덩치가 큰 CSS를 이용한 프로젝트를 안정적으로 유지하게 어렵게 만드는 원인이 되고 있습니다. 그리고 이를 개선하기 위해서 CSS 스펙으로 해결하지 못하는 부분들은 여러가지 도구들을 발명해서 또 해결을 하고자 하게 됩니다. 그러면 또 우리는 이 새로운 도구를 배워야 하죠.
이후 이러한 문제를 해결할 수 있는 새로운 스펙 출시가 되거나 더 나은 방법이 발견이 되면 기존에 찾아냈던 방식들은 전부 좋지 못한 방법이 됩니다. 그렇지만 예전에 이미 생산된 커리큘럼이나 작성된 내용들은 남아있기에 뭐가 더 나은 방식인지 모른 채 학습을 하게 되죠.
그렇다고 무조건 최신을 따르자니 새로운 스펙이 모든 브라우저에 보편적으로 적용이 되기까지에는 또 시간이 필요합니다. 그러다 보니 특정 브라우저에는 제대로 보이지 않을수도 있기에 무조건 새로운 스펙을 바로 도입할수도 없죠. 그러니 기존의 방식 역시 알고는 있어야 하는 상황이 발생하게 됩니다.
당장의 최신 기술을 쓸 수 없으니 그렇다고 안정성만 추구해 계속 현재의 방법만 고수를 한다면 변화하는 웹 생태계에 따라가지 못한채 낡은 코드와 낡은 패러다임으로 인해 우리의 코드는 레거시가 되게 됩니다. 언제나 더 나은 방법을 찾아내고 개선을 하고자 하는 것이 개발자들이니까요.
그러기에 언제 새로운 스펙으로 갈아탈지 어떤 기능이 나왔는지 어떠한 관점과 기술들이 나왔는지 우리는 꾸준히 관찰을 하고 학습을 하여 적당한 시기에 더 나은 방법으로 꾸준히 업데이트를 해나가야만 합니다.
종합하자면, 문서에서 어플리케이션으로 넘어오는 과도기적 시행착오로 인해 CSS 자체가 규모가 큰 서비스를 만들기에 이미 태생적인 문제가 있다는 것이 첫번째 어려움이며, 이를 극복하기 위해 새롭게 만들어지는 스펙들과 도구들이 범람을 하는데 그 중에서 무엇이 좋은지 알기가 어렵고 무조건적으로 최신기술을 선택할 수는 없기에 적절한 기준점을 가지고 적당히 좋은 도구를 적당히 좋은 시기에 꾸준히 업데이트를 해야하는 것이 두번째 어려움입니다.
웹 산업의 분야는 다양하기에 하나의 기술과 패러다임이 정답이 아닙니다. CSS 기술은 항상 시대를 반영해서 발전을 해왔고 내가 홈페이지를 만들고 있는지 솔루션을 만들고 있는지 백엔드 입장인지 프론트엔드 입장인지에 따라서 좋은 방법과 나쁜 방법이 다 달라지게 됩니다.
CSS 역시 어디에서든 통하는 은빛총알 같은 것은 없습니다. CSS에는 상황에 맞는 여러가지 도구들이 존재하고 있으며 어떠한 도구가 어디에 잘 어울리지는 지 역시 스스로 알아야 하겠지요.
제가 항상 CSS를 알려드릴때 하는 말이 있습니다. CSS를 잘 하기 위해서는 본인만의 Best Practice를 가져야 된다고 말입니다. CSS는 JS와는 달리 깊은 이해도 어느 정도 필요하겠지만 그것보다는 숙달이 되어 있는 것이 훨씬 더 중요합니다.
왜냐하면 디자인을 내가 원하는 대로 만들 수 있고 요구하는 디자인을 정확하고 신속하게 만들어줘야 CSS를 잘 한다는 장점을 챙길 수 있기 때문에 CSS는 깊은 이해보다는 상대적으로 연습이 더 중요합니다. 그렇기에 내가 거대한 CSS와 디자인을 잘 다루기 위해서는 반복 숙달이 필요하고 그러다 보면 자기만의 루틴이 만들어지게 됩니다.
이 루틴이라는 것은 좋고 효율적인 걸 가지고 있어야겠죠. CSS와 브라우저는 계속 성장을 하고 있기에 처음에 배웠던 그 방식이 지금은 최선이 아닐수도 있습니다. 그렇기에 내 도구들을 항상 점검하고 새로운 스펙들을 주시하고 있어야 합니다. 아쉽게도 무조건 최신을 택할 수도 없는 것이, 브라우저는 여러 종류가 있고 데스크탑과 모바일 그리고 아직 업데이트를 하지 않은 유저들도 있기 때문에 적절한 밸런스를 잡아야 합니다.
또한 그간 CSS 신문물의 척화비 역할을 하던 IE11의 퇴출이 확정이 되었고, CSS에도 JS의 영역이 가세하면서 CSS의 도구나 패러다임이 업그레이드가 될 예정입니다. 최신 스펙뿐만이 아니라 CSS를 개발하기 위한 좋은 도구들을 꾸준히 바꿔가는 것 역시 우리가 낡은 개발자가 되지 않는 길이기도 합니다.
출처: https://github.com/ManzDev/frontend-evolution
어느 분야든 역사를 공부한다는 것은 지금 이것이 왜 이렇게 만들어져있으며 앞으로는 어떻게 될지 방향성을 예측해 볼 수 있는 좋은 공부가 됩니다. 특히 CSS의 경우 웹 문서로 출발해 홈페이지, 게시판 그리고 현재 웹 어플리케이션으로 넘어가는 과정에서 당시에는 CSS 스펙이 지원하지 않아서 만들어졌던 방법들이나 패러다임의 전환등이 많았기에 CSS를 지금 처음 배우는 사람들 입장에서는 예전과는 다른 환경에 쓰여진 말들이 어느 것이 맞는건지 잘 모르게 되는 경우가 생기게 됩니다.
CSS뿐만 아니라 모든 개발의 내용은 필요에 의해 생기고 필요는 그때 당시의 상황을 반영하게 됩니다. CSS의 역사를 이해함으로써 앞으로 CSS 관련 글들을 읽었을때 어떠한 갈래와 패러다임에 해당하는 내용인지 알 수 있는 넓은 시야가 생기는데 도움이 되었으면 좋겠습니다. 또한 앞으로 새로운 스펙이나 도구 기술등이 나왔을 때에도 어떠한 맥락에서 이게 만들어졌는지 이해할 수 있는 단초가 되어 줄거라 생각합니다.
CSS(Cascading Style Sheets)는 현재 웹 개발에서 필수적인 기술 중 하나입니다. 그러나 CSS가 웹 개발에서 어떤 역할을 하며, 어떤 변화 과정을 거쳐 현재의 모습을 갖추게 되었는지에 대한 이해는 아직도 많은 개발자들이 부족한 상태입니다.
CSS는 초기 웹에서 문서의 서식을 담당하는 역할로 시작되었습니다. 이 때문에 초기 CSS는 HTML과 매우 유사한 구조를 갖추고 있었습니다. 그러나 시간이 지나면서 웹의 변화에 맞추어 CSS도 변화하게 되었습니다.
CSS가 변화한 가장 큰 이유 중 하나는 웹의 발전입니다. 초기 웹에서는 웹 페이지의 디자인이 크게 중요하지 않았습니다. 따라서 CSS도 간단한 서식을 담당하는 역할로 사용되었습니다. 그러나 웹이 발전함에 따라 웹 서비스나 애플리케이션의 디자인이 중요해지게 되면서 CSS도 이에 맞게 발전하게 되었습니다.
또한 CSS가 발전하는 또 다른 이유는 브라우저의 발전입니다. 초기 웹에서는 브라우저마다 CSS의 기능이 다르거나 제대로 지원되지 않는 경우가 많았습니다. 이 때문에 개발자들은 동일한 디자인을 구현하기 위해 많은 노력을 기울여야 했습니다. 그러나 브라우저의 발전으로 인해 이러한 문제들은 점점 해결되었습니다. 따라서 CSS의 기능도 더욱 다양해지고 복잡해지게 되었습니다.
이러한 변화 과정에서 CSS는 매우 복잡하고 다양한 기능들을 제공하게 되었습니다. 예를 들면, CSS의 레이아웃 구현 방법 중 float와 position이 있습니다. 이 중 float는 초기 CSS에서부터 지원되는 기능이며, 주로 이미지를 감싸는 데 사용됩니다. 그러나 float는 사용하기 쉽지 않아서, 개발자들이 다양한 해결책을 찾아내기도 했습니다. 이에 반해 position은 CSS2에서 도입된 기능으로, float보다 사용하기 쉽고 강력한 기능을 제공합니다.
CSS의 발전 과정에서는 다양한 방법들이 존재합니다. 그 중에서도 어떤 방법이 최선인지는 상황에 따라 다를 수 있습니다. 예를 들면, CSS의 레이아웃을 구현하는 방법으로는 float, flexbox, grid 등 다양한 방법이 있습니다. 각 방법마다 장단점이 있으며, 상황에 따라 적합한 방법을 선택해야 합니다.
이러한 상황에서 CSS의 역사를 이해하면서, 어떤 방법이 어떤 상황에서 좋은 선택인지 판단할 수 있습니다. 예를 들어, flexbox는 단일 행 또는 열로 구성된 요소들을 배치할 때 적합한 방법입니다. 반면에 grid는 복잡한 레이아웃을 구현할 때 유용합니다.
CSS의 발전 과정은 여러 요인들이 작용하면서 진행되었습니다. 이러한 요인들은 개발자들이 CSS를 사용하는 데 있어서 매우 중요한 역할을 합니다. 따라서 CSS의 역사를 알아야 하는 이유는, 현재 CSS가 어떤 모습인지 이해하고, 어떤 방법이 최적인지 판단하기 위해서입니다.
또한 CSS의 발전 과정은 웹 개발 분야에서 일어나는 변화를 이해하는 데도 큰 도움이 됩니다. 예를 들어, CSS가 발전하면서 웹 디자인에서 사용되는 이미지의 해상도가 높아졌습니다. 따라서 개발자들은 고해상도 이미지를 사용할 수 있는 방법들을 찾아내야 했습니다.
마지막으로, CSS의 역사를 이해하면서 개발자들은 CSS의 장단점을 파악할 수 있습니다. CSS는 강력한 기능을 제공하지만, 사용하기 쉽지 않은 경우도 있습니다. 또한, CSS를 사용하면서 발생하는 성능 이슈 등도 고려해야 합니다. 이러한 문제들을 파악하면서, 개발자들은 보다 효과적인 CSS 사용 방법을 찾아내고, 더 나은 웹 개발 경험을 제공할 수 있습니다.
종합적으로, CSS의 역사를 이해하는 것은 현재 CSS를 활용하는 데 있어서 매우 중요한 요소입니다. 또한, CSS를 사용하여 디자인을 구현할 때, 최적의 방법을 찾기 위해서도 CSS의 역사를 이해하는 것이 필수적입니다. 따라서 CSS의 역사를 공부하는 것은 모든 웹 개발자들에게 권장되는 일입니다.
역사를 공부하는 것은 해당 분야의 현재 상황을 이해하고, 미래를 예측할 수 있는 좋은 방법입니다. CSS의 경우 초기에는 웹 문서의 서식을 담당하는 역할을 하다가 웹의 발전과 함께 웹 디자인에서 필수적인 기술로 자리 잡게 되었습니다.
CSS의 발전 과정에서는 브라우저의 발전과 웹 서비스의 발전 등 다양한 요인들이 작용하면서 다양한 기능들이 추가되었습니다. 이러한 변화 과정에서 CSS는 매우 복잡하고 다양한 기능을 제공하게 되었습니다. 이러한 기능들을 이해하면서 현재의 CSS를 이해하고, 효과적으로 사용할 수 있습니다.
CSS의 발전 과정에서는 다양한 방법들이 존재합니다. 이러한 방법들은 상황에 따라 다르게 적용해야 하며, 이를 판단하기 위해서는 CSS의 역사를 이해하는 것이 중요합니다.
CSS의 역사를 이해하면서 개발자들은 CSS의 장단점을 파악할 수 있습니다. 이러한 문제들을 파악하면서, 개발자들은 보다 효과적인 CSS 사용 방법을 찾아내고, 더 나은 웹 개발 경험을 제공할 수 있습니다.
따라서 CSS의 역사를 공부하는 것은 모든 웹 개발자들에게 권장되는 일입니다. CSS뿐만 아니라 모든 개발의 내용은 필요에 의해 생기고, 필요는 그때 당시의 상황을 반영하게 됩니다. CSS의 역사를 이해함으로써 앞으로 CSS 관련 글들을 읽었을 때 어떠한 갈래와 패러다임에 해당하는 내용인지 알 수 있는 넓은 시야가 생기는데 도움이 됩니다. 또한 새로운 스펙이나 도구 기술이 나왔을 때에도 어떠한 맥락에서 이게 만들어졌는지 이해할 수 있는 단초가 되어 줄 것입니다.
CSS는 현재 웹 개발에서 필수적인 기술 중 하나입니다. 그러나 CSS가 웹 개발에서 어떤 역할을 하며, 어떤 변화 과정을 거쳐 현재의 모습을 갖추게 되었는지에 대한 이해는 아직도 많은 개발자들이 부족한 상태입니다.
CSS의 초기 버전은 HTML과 유사한 구조를 갖추고 있었으며, 주로 문서의 서식을 담당하는 역할로 사용되었습니다. 그러나 웹의 발전과 함께 웹 디자인이 중요해지면서 CSS도 이에 맞게 발전하게 되었습니다. 브라우저의 발전으로 인해 CSS의 기능도 더욱 다양해지고 복잡해지게 되었습니다.
CSS의 발전 과정에서는 다양한 방법들이 존재합니다. 그 중에서도 어떤 방법이 최선인지는 상황에 따라 다를 수 있습니다. 예를 들면, CSS의 레이아웃을 구현하는 방법으로는 float, flexbox, grid 등 다양한 방법이 있습니다. 각 방법마다 장단점이 있으며, 상황에 따라 적합한 방법을 선택해야 합니다.
CSS의 발전 과정은 웹 개발 분야에서 일어나는 변화를 이해하는 데도 큰 도움이 됩니다. 예를 들어, CSS가 발전하면서 웹 디자인에서 사용되는 이미지의 해상도가 높아졌습니다. 따라서 개발자들은 고해상도 이미지를 사용할 수 있는 방법들을 찾아내야 했습니다.
CSS의 역사를 이해하면서, 개발자들은 CSS의 장단점을 파악할 수 있습니다. CSS는 강력한 기능을 제공하지만, 사용하기 쉽지 않은 경우도 있습니다. 또한, CSS를 사용하면서 발생하는 성능 이슈 등도 고려해야 합니다. 이러한 문제들을 파악하면서, 개발자들은 보다 효과적인 CSS 사용 방법을 찾아내고, 더 나은 웹 개발 경험을 제공할 수 있습니다.
종합적으로, CSS의 역사를 이해하는 것은 현재 CSS를 활용하는 데 있어서 매우 중요한 요소입니다. 또한, CSS를 사용하여 디자인을 구현할 때, 최적의 방법을 찾기 위해서도 CSS의 역사를 이해하는 것이 필수적입니다. 따라서 CSS의 역사를 공부하는 것은 모든 웹 개발자들에게 권장되는 일입니다.
CSS의 발전 과정은 웹 개발에서의 변화와 발전과 밀접한 관련이 있습니다. 따라서 CSS의 역사를 이해함으로써, 어떤 맥락에서 CSS가 만들어졌고, 어떻게 발전해 왔는지를 이해할 수 있습니다. 이를 통해 앞으로 CSS가 어떤 방향으로 발전해 나갈지 예측할 수도 있습니다. 또한, CSS의 역사를 이해하면서, 개발자들은 CSS의 각 기능들의 특징과 장단점을 파악할 수 있습니다. 이를 토대로 개발자들은 효과적으로 CSS를 활용하여 보다 나은 웹 개발 경험을 제공할 수 있습니다.
#CSS/1장_역사
"CSS는 컨텐츠와 표현을 분리하는 도구다."
출처: https://github.com/ManzDev/frontend-evolution
HTML(HyperText Markup Language)
은 1980년대 후반 Tim Berners-Lee가 웹에서 문서를 구조화하고 표시할 목적으로 만들었습니다. 처음에는 과학 및 학술 정보를 게시하는 데 사용되었으며 결국 웹 페이지를 만들기 위한 표준 마크업 언어가 되었습니다.
우리는 이제 HTML을 사용하여 제목, 단락, 목록, 링크 및 기타 콘텐츠 요소가 있는 웹 페이지를 만들고 간단한 태그 및 특성으로 페이지의 서식을 지정할 수 있습니다.
HTML 초기에는 글꼴 색상과 크기, 볼드체 또는 이탤릭체 정도의 단순하고 제한된 기본적인 수정만 할 수 있었습니다. 이후 웹이 발전하면서 보다 시각적으로 매력있는 문서를 꾸미고자하는 요구가 생겨나게 되었습니다.
<h1>예전 HTML에서 꾸미는 것은 제목</h1>
<p>문단, 그리고 <b>굵게<b/> <i>이탤릭</i> 정도 뿐이었다.</p>
그리하여, 1997년 HTML4에서 코드 내의 개별 요소에 특정 스타일을 직업 추가할 수 있는 기능인 inline-style 이 탄생합니다. 이 새로운 기능을 통해 디자이너는 웹 페이지의 각 요소에 대한 배경색, 글꼴 크기 및 기타 고급 스타일 옵션을 변경할 수 있게 되었습니다.
가령, 내가 강조하는 서식에 빨간색과 밑줄을 추가로 넣고 싶은 경우 다음과 같은 방식으로 빨간색과 밑줄을 추가할 수 있게 되었습니다.
<p>이제는 이렇게 <strong style="color:red; text-decoration:underline">빨간색과 밑줄표기로 강조</strong>하는 등의 서식을 추가할 수 있게 되었습니다.</p>
이러한 inline-style을 통해 보다 다채로운 웹 문서를 만들 수 있게 되었습니다.
inline-style을 통해서 웹 문서를 훨씬 더 다양한 디자인이 적용된 문서가 되었습니다. 점점 웹 문서가 커지고 복잡해지면서 inline-style은 새로운 문제에 직면하게 됩니다.
대개 동일한 의미는 동일한 디자인으로 작성이 됩니다. 가령 문서에서 강조를 하고 싶은 서식이 빨간색+밑줄이었다면 모든 강조 구문에는 동일한 서식을 각 항목에 작성을 해야만 했습니다.
<p>이 문장에서 <strong style="color:red; text-decoration:underline">중요한 부분</strong>입니다.</p>
...
<p>안녕! <strong style="color:red; text-decoration:underline">여기를 빨간색으로 강조</strong>하고 싶어</p>
...
<p>새로운 문장에서도 여전히 <strong style="color:red; text-decoration:underline">중요한 부분은</strong>존재합니다.</p>
그래서 위와 같이 매번 반복해서 작성을 해야하는 복잡한 문서가 만들어지게 됩니다. 그런데 여기서 빨간색이 마음에 들지 않아서 파란색으로 바꾸고 싶다면 어떻게 해야 할까요?
이미 다 만들어 놓은 서식에서 색깔 부분만 찾아내 빨간색을 파란색으로 일일이 다 바꿔야 할 것입니다. 찾아 바꾸기를 한다고 해도 글자색이 아닌 다른 색을 수정할 수도 있고, 실수로 본문에 있는 글자가 바뀔 수도 있는 문제가 발생을 합니다.
이렇듯 사용자 스스로 반복을 하는 것은 개발자 세계에서는 아주 좋지 못한 것이죠.
그래서 HTML에서 스타일을 분리하여 작성하므로써 반복적인 부분을 일괄적으로 적용을 해주는 방법을 생각해내게 됩니다.
- inline-style이 기록된 부분들을 하나로 묶어 별도의 스타일을 선언(declarations) 해두고,
- HTML에서 원하는 태그를 찾아서 선택(selector) 하여 스타일을 적용하는 언어인 CSS를 만들게 되었습니다.
선택자(selector) 와 선언(declarations) 이 둘을 합쳐 CSS Ruleset이라고 부릅니다.
<p>이 문장에서 <strong>중요한 부분</strong>입니다.</p>
...
<p>안녕! <strong>여기를 빨간색으로 강조</strong>하고 싶어</p>
...
<p>새로운 문장에서도 여전히 <strong>중요한 부분은</strong>존재합니다.</p>
<!-- 컨텐츠에서 스타일을 CSS로 분리해내어 반복을 제거하였다. -->
<style>
.strong { color: red; text-decoration:underline }
</style>
이렇듯 CSS는 반복해서 입력을 해야 했던 귀찮은 행동들을 대신 해주는 일종의 매크로 와 같은 역할을 한다고 생각해주세요. 그러면 CSS의 작동원리에 대해서 더 이해하기 쉬울겁니다.
앞서 설명드린 매크로와 같이 여러개의 서식을 일괄적으로 적용을 방식이다 보니 CSS의 Ruleset의 적용 대상과 서식이 겹칠 경우에는 어떤 서식을 더 우선을 해야할지 규칙이 필요했습니다.
이러한 규칙을 CSS는 Cascade라는 특징을 가지고 만들어졌습니다. (CSS의 첫글자이기도 한 이 Cascade는 한국어로 명확하게 번역을 하기 애매해서 많이들 헷갈려 하는 개념입니다.)
Cascade란 서식을 겹겹이 덧칠해 쌓아나가는 방식입니다. CSS에서는 여러개의 룰에서 적용한 서식들은 모두 적용됩니다.
(쌓이는 그림이 있으면 좋겠다)
반복적인 작업을 줄이기 위해서 기초가 되는 서식을 먼저 전체에 적용을 하고 점점 더 구체적인 서식들을 적용을 해 나가는 식으로 만들면 좋을 거라고 생각을 했습니다.
기초 화장 먼저 칠하고 색조 화장을 하는 장면이나 '그림을 그립시다'의 밥 아저씨가 그림을 그릴때 처럼 밑칠을 먼저 하면서 장면을 만든 다음 그 위에 더 구체적인 것들을 덧칠하는 것들을 상상해 보세요.
그래서 CSS는 작성된 순서가 아니라 CSS Rule이 가지고 있는 고유의 명시도(Specificity)에 따라서 우선순위가 다르게 적용을 할 수 있도록 설계가 되었습니다.
이 방법은 코드의 순서를 강제하지 않고 응집력이 높도록 코드를 작성할 수 있도록 도와줄 거라고 생각했습니다.
/* 아래 4가지 코드는 순서가 변해도 동일한 결과를 나타낸다 */
h1 { font-size: 2em; color: #000; font-family: Georgia}
.small { font-size: 1em }
[href] { color: red; }
#id { color: #ccc; }
/* 순서가 변경이 되어도 위 코드와 결과가 같다. */
#id { color: #ccc; }
.small { font-size: 1em }
h1 { font-size: 2em; color: #000; font-family: Georgia}
[href] { color: red; }
이후 웹 산업이 단순히 문서를 데이터를 교환하는 Form이 중심이 되면서 우리가 알고 있는 게시판이나 쇼핑몰과 같은 데이터를 주고받고 저장을 하는 매체로 성장을 하게 됩니다.
그래서 단순히 정적으로 서식과 함께 생성하던 문서에서 데이터들이 결합하여 동적으로 생성을 해야 하다보니 HTML를 작성하는 주체가 백엔드 개발자가 됩니다.
그러면서 게시판, 포럼, 장바구니, 로그인과 같은 기능이 필요한 페이지들은 백엔드를 중심으로 하는 솔루션의 형태로 발전하게 됩니다.
이러한 이유로 솔루션의 HTML을 CSS를 이용해서 디자인을 커스텀해야하는 요구사항이 높아지면서 HTML을 건들지 않고 CSS만으로 디자인을 할 수 있는 방법이 중요해지게 됩니다.
이러한 시멘틱한 HTMl를 이용해서 하나의 컨텐츠에서 여러가지 CSS의 서식을 입힐 수 있도록 작성하는 것은 HTML5와 CSS3를 제대로 사용하는 하나의 기준이 되었고 이를 제대로 보여주는 사이트인 CSS Zen Garden이 등장하였습니다.
CSS Zen Garden은 시멘틱한 원본 HTML이 존재하고 디자이너가 CSS만으로 전혀 다른 스타일을 적용할 수 있다는 것을 보여줍니다.
(같은 컨텐츠로 전혀 다른 디자인을 만들 수 있다!)
아직까지도 시멘틱 웹과 CSS를 배우고 연습하기에는 이만한 자료도 없습니다. CSS를 연습해야할 자료가 없다면 지금과는 디자인 트렌드가 많이 다르긴 하지만 시멘틱웹과 CSS의 기초를 익히기에는 좋습니다.
이러한 컨셉을 바탕으로 추후 CSS를 커스텀 할 수 있는 블로그나 워드 프레스와 같은 CMS 서비스들이 인기를 끌게 됩니다.
다만, 이때까지는 HTML을 먼저 만들고 CSS를 나중에 디자인을 커스텀할 수 있도록 하는 방법이 유효했지만 점점 하나의 웹페이지가 거대해지면서 하나의 컨텐츠를 여러 디자인으로 커스텀 하는 방식보다는 하나의 디자인과 컴포넌트를 중심으로 서비스를 키워나가는 형식으로 발전을 하게 됩니다. 그래서 하나의 HTML에 여러 서식을 넣도록 만드는 이러한 방식은 현대 웹 서비스개발과는 맞지 않습니다.
그렇지만 CSS Style을 override하여 커스텀한 테마를 이용하여 홈페이지를 만드는 워드프레스와 같은 방식은 당연히 유효하며 실제로도 웹 페이지의 대다수를 차지하고 있습니다. 이것이 CSS를 어렵게 만드는 이유이기도 합니다.
시멘틱 패러다임은 HTML과 CSS의 학습의 교과서와 같은 항목이자 현재 가장 많이 쓰이고 있으면서도 최신 프론트엔드 개발 서비스와는 맞지 않는 부분이 있어 우리는 어떠한 부분이 필요하고 어떠한 부분이 이제는 필요없는지를 잘 구분 할 수 있어야 합니다.
하나의 변하지 않는 컨텐츠와 다양한 변경가능한 디자인이라는 컨셉을 통해 HTML과 CSS에는 시멘틱이라는 것이 중요해졌습니다.
시멘틱이란 시각적으로 어떻게 보일지가 아니라 의미에 중점을 두는 것입니다. HTML이 어떻게 보여질지는 HTML이 결정하는 것이 아니라 CSS에 의해 커스텀될 수 있어야 재사용성이 커지기 때문입니다.
HTML에서 시멘틱요소는 컨텐츠에 의미를 부여해서 보다 나은 검색결과를 얻고자하는 SEO와도 관련이 있지만 이 글은 CSS를 다루기에 해당 내용은 생략하도록 하겠습니다.
이해를 돕기 위해 예시를 들어보겠습니다.
<div class="error">에러 메시지</div>
<div class="red">에러 메시지<div>
<div class="#ff0">에러 메시지</div>
<style>
.error { color: #f00 }
.red { color: #f00 }
.\#ff0 { color: #f00 }
</style>
여기에 동일한 서식을 가지는 .error
, .red
, .#f00
3가지 클래스 이름이 있습니다.
모두 빨간색으로 표기하는 서식이기에 결과는 같습니다.
이 중 어느 이름이 더 시멘틱 한걸까요?
.error
라는 이름이 더 시멘틱하다고 생각할거라 생각합니다.
이 상황에서 에러 메시지의 색깔을 오렌지색으로 바꿔야 하는 요구사항이 생겼습니다.
(단, HTML을 수정할 수가 없어요!)
CSS를 어떻게 바꾸면 될까요?
<div class="error">에러 메시지</div>
<div class="red">에러 메시지<div>
<div class="#ff0">에러 메시지</div>
<style>
.error { color: #f90 }
.red { color: #f90 }
.\#ff0 { color: #f90 }
</style>
.error { color: #f90 }
은 전혀 문제가 없어보입니다. 에러색이 오렌지색으로 변했으니까요.
.red
는 어떨까요? 내가 아는 빨간색은 이제 아니게 되었지만 그쪽 계열(?)이라고 우겨볼수는 있으려나요? 파란색으로 바꿔달라고 하면 어떡하죠?
.#ff0
은 이제 명백히 잘못된 디자인을 표기하게 될 겁니다.
HTML을 수정할 수가 없다면 class의 이름이 시각적인 내용이기보다 의미를 나타내어야 디자인을 커스텀할 수 있는 영역이 다양해집니다.
HTML을 수정할 수 없으나 원하는 디자인을 만들기 위해서는 조금더 정교하고 고도화된 Selector가 필요하게 됩니다. 그래서 CSS는 점점 더 Selector가 복잡해지는 방향으로 발전을 하게 됩니다.
하지만 이렇게 Selector가 복잡해지면 Specificity가 높아지게 되고 새로운 스타일을 그 뒤에 덮기 위해서는 더 높은 Specificity의 Selector가 필요하고 그러지 못할 경우에는 !important를 사용하게 되는 부작용이 있어 CSS가 어렵고 복잡해진다는 것을 느껴갑니다.
문서를 더 시각적으로 휼륭하게 보이게 하기 위해서 HTML에 서식ㅇㄹ
--> 컨텐츠와 서식을 분리하고자 하는 시도
--> 본격적으로 컨텐츠와 서식의 분리가 강조되고 원 컨텐츠 + 다 테마의 기조
--> 웹 2.0과 더불어 블로그, 워드프레스와 같이 솔루션 + CSS 테마방식의 부흥
Selector를 복잡하게 사용해야 하고 CSS에서 반복해서 사용하는 글자 크기가 색상들을 작성을 하고 나서 수정이 용이하지 않다는 점을 해결하고 CSS를 확장하여 사용하고자 하는 시도가 만들어집니다.
Nested한 Selector와 variable를 등록할 수 있는 추가적인 문법으로 작성하면 CSS로 변환을 시켜주는 pre-processor인 Sass가 만들어집니다.
이후 2009년 less, 2010년 stylus와 같은 새로운 pre-processor들을 만들어지게 되었으나 sass가 계속 점유율 1위를 이어갔습니다.
https://blog.logrocket.com/how-to-write-reusable-css-with-sass/
Pre-processor는 CSS를 로직이 있는 언어로 접근하고 재사용을 하기 위한 방법을 모색했다는 데에 의미가 있습니다. 물론 CSS는 구조상 재사용이 거의 힘들기 때문에 실제로는 재사용을 거의 하지 못했습니다. 이후 Atomic CSS라는 방식을 통해서야 CSS를 재사용하기 위한 방법들이 발견되게 됩니다.
#CSS
#CSS/1장_역사
세부 목차
1. jQuery, Ajax의 보편화, 2006
2. 스마트폰의 등장과 모바일 웹, 2007
3. 웹 어플리케이션과 Framework, 2013
4. Cascade와 Specificity - 절망편
5. 방법을 찾아보자. CSS 방법론와 BEM, 2009
6. Flexbox의 등장, 2009
7. IE11 등장, 2013 (이제 flexbox를 모두가 쓸 수 있다!)
8. Handoff툴의 등장! Zeplin, 2015
@TODO: Twitter Bootstrap, 2011 (*세부 글 추가 필요)
문서에서 어플리케이션으로의 발전
프론트엔드 개발에서 Ajax라는 혁신과 jQuery의 등장으로 인해 백엔드에서 HTML이 아니라 JSON을 만들게 되었습니다.
이제는 HTML이 백엔드에 있는게 아니라 HTML과 CSS를 함께 작성을 하고 데이터를 연동해서 출력하는 작업을 JS로 하는 방식으로 개발을 하게 됩니다. 사실상 프론트엔드의 탄생입니다.
이때부터는 HTML와 CSS를 작업하는 주체가 백엔드와 프론트엔드가 나뉘지 않고 점점 프론트엔드로 옮겨지기 시작하면서 복잡한 Selector를 사용해야할 빈도가 줄어들기 시작했습니다.
HTML의 편집권이 프론트엔드로 서서히 옮겨오기 시작하면서 Selector를 복잡하게 만들기 보다는 HTML에 class를 추가하는 등 의 HTML 수정을 통하여 단순한 Selector를 만드는 방식으로 발전을 하게 되었습니다.
페이스북의 성장으로 인해 웹 어플리케이션이라는 영역이 확대되고 React를 비롯한 Web Framework가 만들어지면서 HTML를 작성하는 주체는 온전히 프론트엔드의 영역이 되기 시작합니다. 그러면서 페이지단위로 문서 기반이 아니라 컴포넌트 기반의 개발 방식이 자리를 잡게 됩니다.
이렇게 JS의 개념이 발전하게 되면서 프론트엔드는 계속 발전하게 되지만 CSS는 그만큼의 변화의 속도를 따라오기 못하게 됩니다.
문제의 비극은 여기서 출발을 합니다.
이미 웹 산업은 홈페이지를 넘어 웹 애플리케이션의 세상으로 넘어왔지만 CSS는 예전의 문서를 꾸미기 위한 스펙을 가지고 있었습니다. 그러다보니 문서를 꾸미기 위한 방법들로 애플리케이션을 만들게 되었습니다. 그러라고 만든 스펙이 아니다보니 온갖 방법을 동원해서 엘리먼트를 가운데 정렬을 하고자 합니다.
당시에는 '엘리멘트는 가운데 정렬하는 7가지 방법' 과 같은 컨텐츠들이 중요한 토픽이었습니다. 이것은 현재도 meme으로 쓰입니다.
이러한 문제로 인해서 문서를 편하게 꾸미를 수 있도록 설계된 CSS는 문서를 꾸미는데 있어서는 유용했을테지만 어플리케이션스러운 UI와 컴포넌트 방식의 개발과는 맞지 않는 설계가 되어버렸습니다.
CSS의 가장 큰 문제점은 CSS가 global scope를 가지고 있다는 점과 Cascade의 Specificity입니다.
모든 문서에 일괄적으로 적용되기 위해서 만들어졌던 기능은 다른 컴포넌트 영역의 스타일을 수정할수도 있다는 문제가 되었습니다. CSS는 외부 변화에 의해 너무나 부서지기 쉽습니다.
HTML을 만들고 CSS를 만들어 두면 이미 만들어진 CSS가 새로운 컴포넌트를 만들기 위한 제약사항이 되어버립니다. 새로운 HTML과 CSS를 만들기 위해서는 기존에 만든 CSS를 피해서 작성이 되어야 했습니다. 때로는 반대로 기존에 만들어진 CSS를 새롭게 덮어써야만 했습니다.
CSS의 Specificity관리와 모듈화가 중요해졌지만 CSS의 스펙은 변경할수가 없었기에 이러한 상황을 이해하고 어떻게 하면 CSS를 잘 작성할 수 있을지 체계적으로 그리고 규칙을 가지고 작성을 해야겠다는 방법론이 논의되기 시작합니다.
그러면서 여러 가지 방법론들이 등장을 하게 됩니다. 방법론의 본질은 다음과 같습니다.
- 여러명에서 함께 작업을 할때 공통적으로 사용할 수 있는 아키텍쳐
- Cascade의 Specificity 관리
- 그러기 위한 이름짓기 컨벤션!
지금 방법론의 최종승자는 BEM이지만 ITCSS를 소개하는 이 동영상은 왜 방법론이 필요한가에 대한 좋은 설명을 해주는 자료라고 생각해서 가져와봤습니다.
OOCSS, ITCSS, SMACSS 여러가지 방법론이 존재했지만 현재 방법론의 승자는 BEM이 되었습니다.
그래서 selector는 class방식으로만 작성하고 네이밍 규칙은 BEM 방식으로 하는 것이 대세룰이 되었습니다.
간단한 이름짓기 컨벤션을 통해서 협업할 때 같은 방식으로 이름을 작성할 수 있게 하면서 구조를 표현하고 Specificity를 하나로만 관리할 수 있게 해서 기존의 문제점을 해결하고자 하는 방식입니다.
처음에는 HTML이 복잡해지고 class이름이 너무 길다는 이유로 사람들에게 받아들여지지 않았지만 CSS의 구조적인 문제를 다 경험(?)하고서는 간결하고 직관적이며 배우기 쉬운 BEM이 대세가 되었습니다.
<div class="header">
<div class="nav"></div>
</div>
<div class="nav"></div>
<style>
.header .nav { (X) }
/* 이렇게 하면
1. nav가 header 구조에 종속이 되어 nav위치에 따라 디자인이 제대로 나타나지 않을 수 있다.
2. Specificity가 올라가게된다.
*/
</style>
<div class="header">
<div class="header__nav"></div>
</div>
<div class="header__nav"></div>
<style>
.header__nav { (O) } /*
1. 구조도 표현하면서 종속 관계가 없다.
2. Specificity가 하나로 관리된다.
*/
</style>
BEM이 최종 방법론의 승리자가 된 이유!
1. 구조도 표현하면서도 종속 관계가 없다.
2. Specificity가 하나로 관리된다.
3. 그러면서 컨벤션이 단순해서 쉽게 기억할 수 있다.
출처: 1분코딩 - 이번에야말로 CSS Flex를 익혀보자
https://studiomeal.com/archives/197
제일 비주얼적으로나 내용면으로 간결하고 좋은 설명을 하고 있다고 생각합니다.
기타 추천
https://d2.naver.com/helloworld/8540176
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
웹 문서가 아니라 웹 애플리케이션으로 발전을 하는 과정에서 레이아웃를 하기 위한 CSS 스펙에 대한 요구사항은 꾸준히 있어왔습니다. 2008년부터 만들기 시작했던 레이아웃을 하기 위한 스펙은 여러번의 시행착오 끝에 드디어 2013년 정식 스펙으로 등장하게 됩니다.
Flexbox가 나오기 전까지 🔥 float나 table, absolute와 margin등을 이용해서 억지로 레이아웃을 만들던 방법들이 존재했고 이러한 방법들은 대체가능한 방법이 없었으므로 여러가지 Tip과 같은 방법들로 방법이 공유되고 문서가 만들어지게 됩니다.
출시 당시에는 IE10이하 브라우저나 크롬, 사파리의 경우에도 이전버전에서는 바로 호환되지 않았기에 당장에는 쓸 수가 없다보니 IE가 없는 모바일에서만 사용하고 크로스브라우징을 하는 등의 과도기가 있었지만 이제는 웹 레이아웃을 하기 위해서는 제일 먼저 알아야 하는 가장 중요한 스펙이 되었습니다.
flexbox의 의미는 문서를 위한 CSS와 어플리케이션 레이아웃을 하기 위한 방식이 분리되어 CSS 스펙으로 웹 애플리케이션 레이아웃을 할 수 있는 토대를 만들어 준 것입니다.
🎯 2022년 flexbox는 이제 웹의 모든 레이아웃의 표준입니다. float, margin, table, inline-block 등 옛날 방식으로 뭔가 정렬을 하는 방식들은 이제 배우지 않으셔도 되고 헷갈려 하지도 마시기 바라며 CSS를 한다면 flexbox만큼은 꼭 master가 되시길 바랍니다!
기존에는 디자이너가 퍼블리싱까지 포함을 해서 웹 디자이너라는 직군으로 일을 했다면 본격적으로 제플린이라는 핸드오프툴이 등장하면서 이쪽 씬의 판도가 변하게 됩니다.
제플린은 기존에 디자이너가 사용하던 도구의 내용들을 통해 그동안 웹 디자인을 하기 필요한 스타일가이드나 요소 간의 간격, 배치에 대해서 기존에는 이걸 다 문서로 만들어서 전달을 하거나 (배보다 배꼽이 더 크던 시절) 그게 아니면 직접 퍼블리싱까지 해서 전달을 했다면 이제는 툴에서 알아서 문서화와 소통 그리고 아카이브까지 해주니 본격적으로 디자이너와 프론트엔드 개발자의 영역이 분리가 되어 더 각자의 영역에서 전문가가 될 수 있게 되었습니다.
이러한 핸드오프가 등장을 하고 나서부터는 CSS로 디자인을 잘하는 능력보다는 디자이너가 만들어 준 디자인을 flexbox등으로 적절한 구조를 만들어 나아가 컴포넌트의 구조를 잘 만들어내는 능력이 더 중요해지게 되었습니다.
제플린과 같은 Handoff툴의 등장의미는 기존의 디자이너가 퍼블리싱을 함께 하던 구조에서 보다 디자인에 집중을 하고 기존 퍼블리셔의 역할을 개발자가 대부분 가지고 와야 한다는 것을 의미합니다.
#CSS/1장_역사
IE는 2015년을 기점으로 현재 더이상의 업데이트가 없었습니다. IE11은 윈도우에서 여전히 점유율이 높은 브라우저였기에 이 이후 새로운 CSS의 스펙이 나오더라도 개발자들은 사용을 하기 꺼려졌습니다. 이때부터 프론트엔드 개발자들이 CSS에 대한 관심이 예전보다 더 떨어지게 되는 원인이기도 했습니다.
무엇보다 이 이후 새로운 스펙이 발표가 되더라도 IE11에서는 지원을 할 수 없기 때문에 해당 스펙을 적극적으로 사용할 수가 없게 되었습니다.
예전부터도 그랬지만 이때부터는 IE11이 CSS의 신문물을 막아주는 방파제이자 척화비가 되어 CSS의 발전역사가 여기서 멈추게 됩니다.
이러한 이유로 이후부터는 CSS의 스펙이나 CSS에서 문제를 해결하기 보다는 CSS를 문제점을 JS로 해결하려는 시도들이 생겨나기 시작합니다.
CSS의 고도화 시대 - CSS와 JS의 결합
CSS의 Global Scope로 인해서 컴포넌트와 CSS간의 구조와 범위가 일치하지 않는 문제를 JS를 통해서 해결하고자 하는 움직임이 생겼습니다.
그중 첫번째 도구인 CSS Modules는 컴포넌트에서 CSS를 불러와서 컴포넌트에서만 적용이 될 수 있도록 컴파일을 해주는 도구였습니다.
이를 통해서 CSS는 태생적인 문제를 JS를 통해서 극복을 할 수 있게 되었고 본격적으로 JS와 CSS가 결합되어가는 시도가 이어졌습니다.
CSS Modules를 통해서 CSS의 가장 고질적인 문제인 Global Scope에 대한 해결이 이루어졌습니다. 사실상 CSS Modules등을 쓴다면 기존의 BEM과 같은 방법론이 그렇게 필요하게 없게 되기도 하였습니다.
그래도 2019년 까지만 하더라도 방법론들을 학습하는 게 또 CSS의 학습의 중요한 역할이었어요. 하지만 또 지금은 그렇지 않습니다. 결국 CSS가 가지고 있는 문제점은 CSS만으로 극복을 하는데에는 한계가 있었기 때문입니다.
CSS는 다음과 같은 구조적인 문제를 지니고 있습니다.
CSS의 Global Scope와 Specificity문제는 CSS의 구조상 해결을 할 수 없는 문제였습니다. 그렇다면 CSS를 JS를 통해서 만들게 되면 이러한 문제를 해결한 새로운 CSS를 만들어낼수 있지 않을까? 하는 방법으로 CSS in JS가 탄생하였습니다.
이러한 방식을 통해서 Specificity문제의 원흉인 Selector는 사라지게 되고 Property와 Value를 컴포넌트 구조에 맞게 작성을 하면 되게 되었습니다.
🎯 현재에 와서 Selector의 의미가 많이 퇴색이 된 이유입니다. Selector를 복잡하게 쓰게 되면 Specificity관리가 힘들어지게 되고 BEM도 마찬가지 이지만 결국 하나의 Specificity를 갖는 방식으로 진화를 하고 있습니다.
JS가 아닌 CSS 생태계에서 이를 해결하고자 하는 새로운 패러다임을 얘기하는 CSS프레임워크가 나타났습니다. 그것은 Utiliy-First라고 불리는 방식의 TailwindCSS였습니다.
사실 TailwindCSS는 새로운 개념은 아니었습니다. HTML과 CSS가 만들어졌을 초창기 부터 class에 유틸리한 이름을 붙여 개발하는 방식은 개발자들 사이에서 암암리에 행해지는 방식이었습니다.
하지만 시멘틱한 방식이 중요한 패러다임이 되면서 이러한 방식은 일종의 꼼수, 옳치않은 방식으로 여겨졌기에 가급적 이렇게 쓰지 말라고 하는 안티패턴이었습니다.
.mt10 { margin-top: 10px} 은 좋은 클래스인가?
https://mulder21c.github.io/2014/12/03/considerations-for-class-name/
https://cafe.naver.com/hacosa/184954
https://hyeonseok.com/blog/604
하지만 TailwindCSS는 이러한 방식을 오히려 일부차용이 아니라 전면적으로 이러한 방식을 사용을 하는 것을 권장하며 패러다임 쉬프트에 성공하였습니다.
당연히 이러한 방식은 예시를 든 블로그의 내용을 보더라도 당시에는 받아들이기 아주 힘든 패러다임이었습니다. 그래서 tailwind의 경우에는 초반에 반대로 굉장히 많았습니다.
tailwindCSS가 받아들여지는데에는 예전과는 달리 다음과 같은 변화가 있었기 때문에 통용이 됩니다.
Atomic한 CSS는 모두 같은 Specificity한 class로 구성이 되었으며 개발을 할때에도 새롭게 CSS를 작성하지 않아도 되었기에 더 이상 추가적인 CSS의 관리가 필요하지 않다는 큰 장점이 있습니다.
무엇보다 이름을 짓기 위한 고민을 하지 않아도 되며(<- 엄청 큰 장점입니다!!) 또한 이미 만들어진 CSS는 서비스가 커지더라도 CSS의 양이 변화가 없기 때문에 대형 서비스 일 수록 CSS의 크기를 줄이는 이점이 존재합니다.
워드프레스와 같이 HTML이 미리 고정이 되어있고 테마를 제공해야하는 솔루션에서는 절대로 쓸 수 없는 기술이다보니 초창기 많은 사람들에게 좋지 않은 방식이라고 부정당했으나 지금은 당당히 CSS의 구조적인 문제를 다룰수 있는 방법으로 인정을 받고 가장 인기 있는 프레임워크가 되었습니다.
Sass나 Less와 같은 PreProcessor의 등장이유기도 했던 CSS에 변수를 쓸 수 있는 기능이 IE11를 제외하고는 모든 브라우저에서 사용을 할 수 있게 되었습니다.
IE11지원을 포기하고 새로운 CSS의 세상을 살기로 마음먹은 서비스들은 이제 더이상 Sass를 써야할 이유가 사라졌습니다.
복잡한 Selector는 CSS 구조상 이제 필요가 없어졌고, CSS Variable은 이제 CSS의 기본 기능이 되었습니다. autoPrefixer의 경우는 PostCSS가 대신할 수 있게 되었고 mixin과 같은 기능들은 CSS in JS에서 더욱 잘 지원을 할 수 있게 되었습니다.
IE11을 쓰지 않을거라면 CSS in JS를 할꺼라면, Atomic CSS를 쓴다면 점점 Sass를 써야 하는 이유가 줄어들고 있습니다. 여전히 Sass는 CSS를 하나면 점유율이 높지만 서서히 대체 도구들이 등장하고 있는 중입니다.
구상은 flexbox보다도 훨씬 전에 논의가 되었지만 여러가지 버전을 거쳐서 2017년 드디어 Grid Layout이 등장하게 됩니다.
하지만 IE의 시간은 2015년도에 머물러 있었기에 새롭게 만들어진 Grid Layout스펙과 IE에서 사용가능한 Grid Layout의 경우 미묘하게 스펙이 다르게 됩니다.
그래서 GridLayout은 흥행을 실패합니다. 사람들은 IE11에서 골치아프게 크로스브라우징을 해야하는 GridLayout에 비해 flexbox로 충분히 대부분의 레이아웃을 작업할 수 있었기에 Grid Layout은 실험적인 기능에 그치게 되었습니다.
MS에서 공식적으로 IE11의 지원종료를 발표하였습니다. 사람들은 이제 확실하게 IE11을 지원하지 않아도 된다는 사실을 통해서 그동안 2015년에 묶여있었던 5년치의 CSS를 한꺼번에 배워야했습니다.
이제는 새로운 CSS의 스펙을 곧 마음대로 쓸 수 있게 되었습니다. 흥행에 실패했던 GridLayout의 사용점유율도 10%에서 50%로 올라왔습니다.
아직 사용할 수 없는 수많은 스펙들이 새로 만들어지고 있습니다. 이제는 새롭게 지원해줄 스펙을 통해서 CSS를 더 좋게 만들 수 있는 방법들을 고민해볼 차례입니다. 물론 아직 그런 시대는 오지 않았습니다.
디자인 툴에 대한 지각변동이 발생하게 됩니다. figma가 1위가 된것은 아주 중요한 사건입니다. figma는 디자이너뿐만 아니라 개발자와의 협업을 하기 위한 실시간 클라우드와 Zeplin과 같은 Handoff 기능을 함께 겸하고 있습니다.
figma는 AutoLayout과 같은 개발자적인 관점에서의 도구를 가지고 있습니다. 점유율 1위가 되면서 디자이너들이 대부분 선택하는 도구가 되고 Zeplin대신 figma를 통해서 HandOff 및 디자인 리소스를 작업해야 하게 되었습니다.
figma의 CSS Inspect는 아주 훌륭하며 디자이너와 함께 협업을 하기 위해서는 개발자들도 알아야 하는 도구입니다.
Styled-Component의 흥행과 React의 압도적인 점유율로 인해 CSS in JS는 새로운 강자를 찾는 중입니다. 런타임에 CSS를 생성한다는 문제점을 극복하기 위해서 Zero-Time CSS, Near Zero CSS와 같은 컨셉을 들고 나오는 중입니다.
stateof2021 - 2021 새로운 기술들은 대부분 CSS in JS에 몰려있다.
오래된 기술의 사용율이 높긴 하지만
만족도의 순위는 엎치락 뒤치락 중이다!
아직까지 절대적인 강자는 Styled-Component가 자리를 지키고 있으며 어떠한 라이브러리가 최종승자가 될지는 좀 지켜보면서 천천히 갈아 타고 될 것 같다고 생각합니다.
TailwindCSS는 미리 만들어둔 CSS만으로는 수치나 색상 입력에 한계가 있고 이러한 부분들을 미리 설정을 해두는 방식으로는 한계가 있다는 지적을 받아왔습니다.
그래서 CSS를 미리 만들어 두는 방식이 아니라 AtomicCSS에 필요한 수치를 입력을 해두면 필요한 CSS를 자동으로 생성을 해두는 주문형(on-demand) Atomic CSS 패러다임으로 발전하고 있습니다.
그중에서도 unocss가 단연 성장세가 무섭습니다. atomic-css 토픽에서 벌써 3위가 되었네요. 나머지 1위 2위는 모르셔도 됩니다. 정말 5~6년도 더된 아주 아주 오래된 것들이 떄문에 얻은 Star이구요
제가 만들고자 했던 것과 컨셉이 상당히 유사합니다. antfu는 개발을 참 잘하는 것 같습니다. vite를 함께 개발하는 코어 개발자인데 evan you와 함께 요새 안만드는게 없는거 같아요. 제가 보고 베낀것은 절대 아닌데 컨셉이 유사한데 더 인기가 많네요 ㅋㅋ
star수를 보면 아직까지 atomic-css, functional-css, utility-first 라는 컨셉 그리고 on-demand라고 하는 컨셉자체가 아직은 희귀해서 인기자체가 좀 없는 느낌이기는 합니다.
https://github.com/topics/atomic-css
(마지막은 조금 더 정리가 필요하다.)
#CSS/1장_역사
(역사편을 정리하는 다른 내용을 작성하려고 합니다. 해당 내용은 머리말 쪽으로 보냈습니다.)
1장<역사편>을 통해서 지금까지 CSS의 지난 역사를 돌아보면서 CSS가 어떻게 태어났고, 어떤 문제를 해결하고자 했으며, 그 뒤로 어떤 발전의 방향성을 가졌는지 알아보면서 우리가 무엇을 어떻게 배워야할지 생각해볼 수 있는 배경지식을 알게 되었습니다.
이러한 내용을 바탕으로 이 책의 세부내용에서는 어떤 것을 다루고자 하는지 한번 정리해보았습니다. CSS는 HTML에서 스타일을 분리하여 디자인과 레이아웃을 쉽게 다룰 수 있도록 만들어진 스타일 시트 언어로, 웹 페이지의 구조와 스타일을 분리하여 코드를 간결하게 하고 유지보수를 용이하게 하기 위해 개발되었습니다.
2장<입문편>에서는 이러한 CSS의 기본적인 구문과 특징을 소개합니다. CSS는 UI 디자인을 구현하는 데 있어 다른 언어에 비해 간결하고 직관적인 문법과 유연한 방식을 제공하는 매우 유용한 언어로 설계되었습니다. 그래서 CSS를 사용하면 웹 페이지의 레이아웃, 색상, 글꼴 등 다양한 디자인 요소를 쉽게 구현할 수 있습니다.
하지만 다른 언어도 그렇듯 CSS 역시 시간이 지나고보니 최초의 설계에서 몇 가지 결점이 드러났습니다. 대표적인 예로 Global Scope와 Specificity 기반의 스타일 우선순위 규칙은 지금까지도 CSS 작성을 어렵고 복잡하게 만들고 있습니다. 이미 만들어진 스펙은 되돌리기가 힘들기 때문에 이러한 CSS의 특징을 이해하고 문제점을 극복하기 위해 적절한 방법을 찾는 것이 중요합니다.
웹은 문서를 공유하기 위해 시작되었으며, CSS는 이러한 문서를 꾸미기 위해 만들어졌습니다. 하지만 웹이 성장하면서, 문서뿐만 아니라 서비스와 어플리케이션을 위한 웹의 역할이 확장되면서 CSS 역시 이러한 고도화를 요구받았습니다. 지속적인 업데이트를 하지 못하는 인터넷 익스플로러의 구조적인 문제와 더불어 CSS의 발전 속도가 변화를 따라잡지 못했기에 그 당시 따라서 개발자들은 원하는 레이아웃을 만들기 위해 문서를 꾸미기위한 다양한 속성들을 조합하는 트릭을 사용하게 되었습니다. 이 과정에서 동일한 화면을 만들기 위한 다양한 방법과 트릭이 생겨나면서, 어떤 방법이 더 적절한지 판단하기 어렵게 되었습니다.
3장 <핵심편>에서는 이러한 과도기적으로 만들어졌던 속성들을 추려내고 핵심 속성을 통해 디자인을 만드는 Best Practice를 설명하려고 합니다. 이를 통해 여러분들은 더욱 효과적이고 핵심적인 CSS 작성 방법을 습득할 수 있게 될 것입니다. 이제 인터넷 익스플로러는 퇴출이 되었고 flexbox를 비롯한 레이아웃을 다루기 위한 좋은 모듈들이 정립되었지만, "여전히 CSS로 같은 화면을 만들기 위해서 여러가지 방법이 존재한다. "라고 하는 것은 저마다 다른 방식으로 CSS를 작성하게 되면서 CSS를 어렵게 만드는 이유가 되고 있습니다. CSS에서 가장 많이 쓰고 필수적인 스펙을 골라 Figma라고 하는 디자인툴의 개념을 기반으로 특정 화면을 만들기 위한 최적의 방법을 설명합니다.
4장 <심화편>에서는 CSS의 문제와 그 해결책, 다양한 도구들이 생겨나는 맥락과 방향성, 그리고 발전 방향에 대해 자세하게 설명하고 있습니다. 현대 웹 생태계는 계속해서 성장하고 있으며, 이에 따라 CSS도 더욱 복잡해지고 있습니다. 이러한 상황에서 단순한 CSS만으로는 충분하지 않기 때문에, CSS 방법론, CSS 전처리기, CSS Module, CSS in JS, Atomic CSS 등과 같은 현재 다양한 CSS 도구들이 개발되고 있습니다. 이제 CSS로 개발하기 위해서는 이러한 도구들을 알고 사용하는 것이 중요한 선택이 되었습니다. 이 책에서 특정한 라이브러리를 선택해 주지는 않지만 이러한 맥락을 이해함으로써 향후 새로운 기술이나 도구가 출시되더라도 선택 기준을 명확히 하고 더 나은 방향성을 이해할 수 있도록 하고자 하였습니다.
CSS는 오랜 역사와 급격한 변화를 거쳐왔습니다. 이에 따라 많은 트릭과 이야기들이 생겨나게 되었습니다. 그렇기에 이 책은 CSS 전체를 완벽하게 다루는 가이드보다는 실무에서 꼭 알아야 할 핵심적인 내용을 선별하여 설명하고자 하였고 중요하지 않은 부분은 의도적으로 작성하지 않으려 하였습니다.
5장<확장편>에서는 부록의 형태로 다뤄볼 예정입니다. 핵심적인 기술은 아니지만 알고 있으면 좋거나 흥미로울만한 내용을 준비해보았습니다. 이 책을 통해 여러분은 CSS의 핵심 내용뿐만 아니라 더 깊이 있는 이해와 흥미로운 이야기들까지 함께 배울 수 있을 것입니다.
#CSS/1장_역사
여기는 진짜 입문입니다. 이 책은 입문자 부터 고급자까지 다 알려드리고자 했기에 해본 경험이 있다면 가볍게 읽거나 그냥 3장으로 바로 넘어가셔도 좋습니다. 2장에서는 정말 기본 중의 기본만 설명하고 있습니다
CSS의 특징인 Cacading와 우선순위 정책, 상속과 같은 이론적인 입문자에게는 혼란만 가중시킨다고 판단하여 그러한 내용들은 여기에 없습니다.
챕터 2의 구성
내가 육성으로 설명을 할 수 있어야 참지식이 됩니다. 그냥 읽어보는 것만으로는 이해했다는 착각만 남게 됩니다. 마지막에 대답을 할 수 있는 질문들을 모아 실제 내것이 되었는지 확인하는 용도로 사용할 수 있습니다.
(글 다시 쓰자)
목표
CSS 시작하기
CSS의 기본 구조와 문법
CSS로 글자 꾸미기
CSS로 박스 꾸미기
CSS Document Layout
CSS Reset
CSS Visibility
CSS Application Layout - Flexbox
CSS Application Layout - Overlay와 Position
Overflow
#CSS/2장입문
#CSS/2장입문/2.1.Syntax
inline-style은 HTML 요소에 직접 스타일을 적용하는 방식입니다. 이 방식은 간단하고 빠르게 스타일을 적용할 수 있습니다. 이번 장에서는 다음과 같은 목표를 가지고 있습니다.
목표
1. inline-style이 무엇인지 이해하고 사용법을 익힙니다.
2. CSS의 속성과 값을 이해하고 간단한 구문과 문법을 익힙니다.
3. inline-style의 특징을 이해하고 어떤 단점이 있는지 이해합니다.
먼저, 연습용으로 HTML 파일을 하나 생성해보세요. 아래와 같은 코드를 작성해보시면 됩니다.
<p>안녕하세요!</p>
1. 글자 크기 조절
다음으로,
요소에 inline-style을 적용하여 글자 크기를 조절해 봅시다. 아래와 같은 코드를 작성해보세요.
<p style="font-size: 20px;">안녕하세요!</p>
위 코드에서, style 속성을 추가하고 font-size 속성을 이용하여 글자 크기를 지정했습니다. 이와 같이 스타일은 속성과 값을 가지며, 각 속성과 값 사이에는 콜론(:)을 사용한다는 것을 기억해주세요
2. 색상 변경
이번에는
요소의 색상을 변경해 봅시다. 아래와 같은 코드를 작성합니다.
<p style="font-size: 20px; color: red;">안녕하세요!</p>
위 코드에서, color 속성과 red 값을 사용하여 글자 색상을 빨간색으로 변경했습니다. 이러한 방식으로, 다양한 스타일 속성을 조합하여 스타일을 적용할 수 있습니다.
각 속성과 속성 사이에는 세미콜론(;)을 사용하여 구분합니다.
3. 다양한 스타일 조합해보기
요소에는 다양한 스타일 속성을 조합하여 적용할 수 있습니다. 아래와 같은 코드를 작성하여 여러 스타일 속성을 적용해 봅시다.
<p style="font-size: 20px; font-weight: bold; color: red; text-align: right;">안녕하세요!</p>
위 코드에서 추가로 font-weight 속성을 이용하여 굵은 글씨로 표시하였습니다. 마지막으로 text-align 속성을 이용하여 글자를 오른쪽에 정렬하였습니다.
"계속해서 속성과 값이라는 용어를 쓰고 있는데 속성과 값은 무엇을 의미하나요?"
속성과 값은 CSS를 구성하는 가장 기본적인 요소입니다.
<tag style="property: value; property: value;">content</tag>
속성 (Properties):
속성은 변경할 스타일 기능(예: font-size, color) 을 나타내는 식별자를 의미합니다.
값 (Values):
지정된 각 속성에는 값이 지정되어 있으며, 이는 해당 스타일 기능을 변경하는 방법 (예: 20px, red)을 나타냅니다.
속성과 값은 콜론(:)으로 구분하고 각 속성과 속성간은 세미콜론으로(;) 구분합니다.
<p>안녕하세요!</p>
<p>반갑습니다.</p>
<p>어서오세요.</p>
<p>이 문장을 다 스타일을 바꾸고 싶은데,</p>
<p>동일한 inline-style을 다 써야 할까?</p>
위 코드의 모든 문단에 20px의 글자 크기와 빨간색 그리고 굵은 폰트를 한번 적용해보세요.
<p style="font-size: 20px; font-weight: bold; color: red;">안녕하세요!</p>
<p style="font-size: 20px; font-weight: bold; color: red;">반갑습니다.</p>
<p style="font-size: 20px; font-weight: bold; color: red;">어서오세요.</p>
<p style="font-size: 20px; font-weight: bold; color: red;">이 문장을 다 스타일을 바꾸고 싶은데,</p>
<p style="font-size: 20px; font-weight: bold; color: red;">동일한 inline-style을 다 써야 할까?</p>
inline-style을 사용하면 위와 같은 결과를 얻게 됩니다. 이를 통해 알게 된 inline-style의 단점은 다음과 같습니다.
1. 유지보수가 어려움:
스타일이 여러 곳에서 중복 적용될 경우, 스타일을 변경하려면 각 요소의 style 속성을 일일이 수정해야 합니다. 이는 유지보수에 어려움을 초래할 수 있습니다.
2. 가독성이 떨어짐:
HTML 코드가 길어지고 복잡해지면 가독성이 떨어집니다.
3. 코드 재사용이 어려움:
inline-style은 한 번 적용되면 다른 요소에서 재사용하기가 어렵습니다. 스타일을 적용할 요소마다 모든 스타일 속성을 일일이 작성해야 합니다.
inline-style을 사용하여 여러 요소에서 스타일이 중복 적용될 경우 유지보수와 코드 재사용성이 어려워지기 때문에 실무에서는 권장되지 않습니다.
대신, CSS 파일을 별도로 작성하여 스타일을 적용하는 방식을 사용하는 것이 좋습니다. 이러한 방식은 유지보수와 코드 재사용성을 높일 수 있습니다.
다음 장에서는 inline-style의 단점을 보완하기 위해 CSS를 이용한 스타일 시트를 통해 서식을 적용하는 방법을 배워보겠습니다.
inline-style
속성(Properties)
값(Value)
font-size:20px;
font-weight:bold;
color:red;
inline-style로 스타일을 하는게 나쁜 것이지 inline-style이 나쁜 것은 아닙니다.
inline-style이 나쁘다는 표현을 통해 inline-style 사용자체를 꺼리게 되어 자칫 Javascript나 프레임워크에서 inline-style을 이용한 동적 스타일 변경적용도 좋지 않다고 생각하는 경우를 더러 접하게됩니다. inline-style의 역할을 이해하고 제 역할에 맞게 사용하는 것은 문제가 되지 않습니다. 좋지 않은 것은 inline-style을 이용하여 스타일링을 하는 것에 한정해서 생각해주세요.
#CSS/2장입문
#CSS/2장입문/2.1.Syntax
앞장에서 inline-style은 간단하고 빠르게 스타일을 적용할 수 있는 반면, 반복적으로 스타일을 장황하게 작성을 하도록 하여 코드의 가독성을 해치고 중복코드가 많아져서 유지보수를 어렵게 만드는 단점이 있다고 배웠습니다.
<h1 style="font-size:20px; font-weight:bold; color:blue">안녕하세요!</h1>
<p style="font-size:14px; color:black">이것은 CSS 내부 스타일 시트를 사용한 예제입니다.</p>
<h1 style="font-size:20px; font-weight:bold; color:blue">Inline-Style의 단점</h1>
<p style="font-size:14px; color:black">컨텐츠의 가독성이 떨어지고 중복이 발생하여 이후 유지보수가 어렵게 됩니다.</p>
<p style="font-size:14px; color:black">중복되어 있는 스타일을 한번만 작성하는 방법은 없을까요?</p>
"Inline-style의 코드는 가독성이 떨어지고, 중복이 발생해서 유지보수가 어렵네요. 그렇다면 중복된 스타일을 한번만 작성하는 방법은 없을까요?"
이러한 inline-style의 단점을 보안하기 위해서 중복된 스타일의 속성(Property)과 값(Value)을 미리 한번만 선언(Declaration) 하고, 이 스타일이 필요한 컨텐츠를 선택(Selector) 하여 중복을 제거하도록 미리 작성해둔 스타일 정보(Style Sheet) 를 만들어서 이를 해결하고자 하였습니다.
(ㄴ 용어의 이해를 돕고자 썼는데 복잡해보이네 목록으로 좀 나눠줘야겠다)
내부 스타일 시트는 HTML 문서의 태그 안에 와 중괄호로 이루어진 선언블록으로 구성되며, 중괄호 안에는 스타일의 속성과 값이 정의됩니다.
<style>
선택자 {
속성: 값;
속성: 값;
}
</style>
앞서 예시로 들었던 inline-style로 작성된 코드에 스타일 시트 방식을 적용하면 아래와 같이 중복을 제거하여 조금 더 간결한 형식으로 작성을 할 수 있게 됩니다.
<h1>안녕하세요!</h1>
<p>이것은 CSS 내부 스타일 시트를 사용한 예제입니다.</p>
<h1>내부 스타일 시트의 장점!</h1>
<p>이제 같은 스타일을 중복해서 작성하지 않아도 됩니다.</p>
<style>
h1 {
font-size: 20px;
font-weight: bold;
color: blue;
}
p {
font-size: 14px;
color: black;
}
</style>
스타일을 별도의 스타일 시트를 통해 작성함으로써 중복되는 코드를 제거하고 HTML 코드와 CSS 코드를 분리하여 가독성을 높이고, 유지보수를 용이하게 할 수 있습니다. 이렇게 스타일을 분리하면 동일한 스타일을 여러 웹 페이지에서 사용할 수 있으며, 변경 사항도 한 번에 적용할 수 있습니다.
다음 장에서는 이러한 스타일 시트 문법에 대해서 자세히 살펴보고, 어떻게 원하는 곳에 스타일을 적용을 하는지 선택자에 대해서 조금 더 자세히 알아보도록 하겠습니다.
inline-style
속성(Properties)
값(Value)
font-size:20px;
font-weight:bold;
color:red;
선택자(Selector)
선언 블록(Declaration Block)
#CSS/2장입문
#CSS/2장입문/2.1.Syntax
#CSS/2장입문
#CSS/2장입문/2.1.Syntax
CSS 구문은 다음과 같이 구성됩니다.
선택자 {
속성: 값;
속성: 값;
}
선택자 {
속성: 값;
속성: 값;
}
h1 {
font-size: 24px;
color: #333;
margin-bottom: 20px;
}
.title {
font-size: 30px;
color: #888;
text-align: center;
}
".title은 뭔가요?"
지금까지 우리는 태그를 통해 원하는 스타일을 지정해왔습니다. 하지만
CSS는 세 가지 주요 문법을 사용합니다.
CSS에서 선택자는 HTML 요소를 선택하기 위해 사용됩니다. 선택자는 다음과 같이 사용됩니다.
.클래스이름
으로 선택합니다.#아이디이름
으로 선택합니다.다음은 선택자를 사용한 예시입니다.
/* 태그 선택자 */
p { color: blue; }
/* 클래스 선택자 */
.text { font-size: 16px; }
/* ID 선택자 */
#main-title { font-weight: bold; }
/* 하위 선택자 */
nav ul { list-style: none; }
/* 자식 선택자 */
nav > ul { margin: 0; }
/* 인접 형제 선택자 */
h2 + p { margin-top: 10px; }
/* 일반 형제 선택자 */
p ~ ul { margin-top: 20px; }
초창기 CSS 학습은 Selector가 중요하지만 현대에 와서는 CSS의 Selector의 중요도가 상대적으로 떨어집니다. 현재 입문에서는 클래스 선택자정도만 알고 있어도 무방하며 Selector에 대한 자세한 설명은 이후 4장<심화편>에서 다루도록 하겠습니다.
CSS에서 속성은 스타일을 적용할 HTML 요소의 특성을 나타냅니다. 속성은 다음과 같이 사용됩니다.
속성(property): 스타일을 지정할 HTML 요소의 속성을 선택합니다. - 값(value): 선택한 속성에 지정할 값을 입력합니다. 다음은 속성을 사용한 예시입니다.
h1 { font-size: 24px; color: #333; margin-bottom: 20px; }
CSS에서 값은 속성에 지정하는 스타일의 종류를 나타냅니다. 값은 다음과 같이 사용됩니다.
#RRGGBB
, rgb(R,G,B) 등의 형식으로 색상을 지정합니다.h1 { font-size: 24px; /* 숫자 값 */ color: #333; /* 색상 값 */ font-family: 'Noto Sans', sans-serif; /* 문자열 값 */ }
이상으로 CSS의 구문과 문법에 대해서 알아보았습니다. CSS를 사용하여 웹 페이지의 스타일링을 할 때 구문과 문법을 올바르게 사용하면 보다 효율적이고 편리한 작업이 가능합니다.
#CSS/2장입문
#CSS/2장입문/2.1.Syntax
목표: 글자색을 변경한다.
Property
color
색상값은 글자 뿐만이 아니라 배경색, 외각선의 색상, 그라데이션에서도 쓰입니다. 또한 색상 키워드와 #rgb
외에도 색상값을 만들수가 있습니다. 색상의 경우 #rgb
방식을 거의 대부분 사용하기 때문에 지금은 이 방식만 알고 있어도 무방합니다. 나머지 색상에 대해서는 색상 고급편에서 더 자세히 다루도록 하겠습니다.
background
border
를 하면서 자연스럽게 Box로 넘어가자!
#CSS
#CSS/2장입문
#CSS/2장입문/2.2.Text
CSS의 텍스트 간격을 사용하면 문자, 줄 및 단락 사이의 간격을 포함하여 텍스트의 시각적 모양을 제어할 수 있습니다.
CSS는 line-height, letter-spacing, word-spacing, text-indent, white-space 및 margin을 포함하여 텍스트 간격을 제어하는 여러 속성을 제공합니다.
line-height를 통해서 줄간격을 조절할 수 있습니다.
Line-height는 텍스트의 연속된 두 줄 사이의 공간입니다. CSS에서는 절대값(예: 10px), 백분율 값(예: 120%) 또는 비율 값(예: 1.5)을 사용하여 선 높이를 지정할 수 있습니다.
1.5와 같은 비율 값을 사용하는 것이 좋습니다. 글꼴 크기와 관련하여 줄 높이를 정의하는 보다 유연하고 일관된 방법을 제공하기 때문입니다.
이것은 다른 화면 크기와 글꼴 크기로 작업할 때 라인 높이가 적절하게 조정되어 텍스트를 읽기 쉽고 시각적으로 균형을 유지하도록 하기 때문에 특히 중요합니다.
p { font-size: 16px; line-height: 1.5; }
부록1: line-height는 150%와 1.5의 차이는 무엇일까?
부록2: line-height 문제 때문에 한글과 영어 가운데 정렬이 잘 안된다?
부록3: line-height에 대한 재미난 이야기(?)
https://wit.nts-corp.com/2017/09/25/4903
letter-spacing을 통해서 글자간의 간격을 조절합니다.
문자 간격은 텍스트 블록에서 개별 문자 사이의 간격을 나타냅니다. CSS에서는 픽셀(예: 2px) 또는 em 단위(예: 0.1em)를 사용하여 글자 간격을 설정할 수 있습니다. Em 단위는 문자 간격을 설정하는 확장 가능한 방법을 제공하기 때문에 일반적으로 사용됩니다.
em 단위는 요소의 font-size와 동일하므로 letter-spacing을 0.01em으로 지정하면 글자 사이의 간격은 font-size의 1%가 됩니다.
p {
font-size: 16px;
letter-spacing: 0.1em;
}
문자 간격을 사용할 때 텍스트의 가독성을 고려하는 것이 중요합니다. 너무 많은 글자 간격은 텍스트를 읽기 어렵게 만들고 너무 작은 글자 간격은 텍스트를 비좁게 보이게 할 수 있습니다. 또한 다른 글꼴은 기본적으로 다른 커닝 값을 가지므로 글꼴 모음 및 글꼴 크기에 주의를 기울이는 것이 중요합니다.
일반적으로 Typography를 다룰 때 font-family, font-weight, font-size, line-height, letter-spacing을 묶어서 다루는 경우가 많습니다. 이러한 속성을 이해하고 제어함으로써 브랜드와 메시지를 정확하게 나타내는 아름답고 읽기 쉬운 텍스트를 만들 수 있습니다.
줄 높이와 문자 간격은 모두 타이포그래피 디자인에서 중요한 역할을 하며 텍스트에 시각적 관심과 강조를 만드는 데 사용할 수 있습니다. 그러나 간격이 너무 많으면 텍스트를 읽기 어렵게 만들 수 있으므로 이러한 속성을 신중하게 사용하는 것이 중요합니다.
일반적으로 좋은 경험 법칙은 line-height를 font-size의 최소 1.5배로 유지하고 letter-spacing을 -0.2em에서 0.2em 범위 내로 유지하는 것입니다.
Text-indent는 텍스트 블록의 시작 부분에서 들여쓰기 양을 지정하는 CSS 속성입니다. 이 속성은 읽고 이해하기 쉬운 구조화된 텍스트를 만드는 데 유용합니다. 단락의 첫 번째 줄을 들여쓰기하여 텍스트의 나머지 부분에서 눈에 띄게 하고 내용을 쉽게 훑어볼 수 있도록 하는 데 특히 유용합니다.
예를 들어 텍스트 들여쓰기가 20픽셀인 텍스트 블록을 고려하십시오. 이렇게 하면 텍스트 블록의 각 단락 첫 줄에 20픽셀 들여쓰기가 생성되어 새 단락이 시작되고 있음을 분명히 알 수 있습니다. 또한 text-indent를 사용하여 중첩된 목록을 만들거나 텍스트 블록 내에서 따옴표를 들여쓸 수 있습니다. 이렇게 하면 읽고 이해하기 쉬운 구조화되고 조직화된 레이아웃을 만드는 데 도움이 됩니다.
부록1. text-indent: -9999px 활용법
단어 간격은 텍스트 블록에서 단어 사이의 간격을 조정하는 CSS 속성입니다. 픽셀, em 단위 또는 백분율을 사용하여 지정할 수 있습니다. 웹 사이트의 전체 디자인과 일치하도록 단어 사이의 간격을 조정하거나 특정 글꼴로 인해 발생하는 간격 문제를 해결하는 데 유용합니다.
예를 들어 글꼴 크기가 16픽셀이고 단어 간격이 4픽셀인 텍스트 블록을 생각해 보십시오. 이렇게 하면 텍스트 블록의 각 단어 사이에 4픽셀의 공간이 추가되어 텍스트가 덜 비좁고 읽기 쉬워집니다. 또한 단어 간격은 특정 단어나 구 사이에 추가 공간을 추가하여 디자인에 시각적인 흥미를 유발하는 데 사용할 수 있습니다. 이는 제목을 강조하거나 긴 텍스트 블록을 나눌 때 유용하지만 잘 쓰이지는 않습니다.
#CSS/2장입문
#CSS/2장입문/2.2.Text
글과 글이 만나서 간격을 만들어야 할 떄!
CSS의 Margin은 텍스트 단락 사이의 공간을 의미하며 시각적 분리 및 계층 구조를 만드는 데 사용됩니다. 특정 내용을 강조하고 가독성을 높이는 데 도움이 되므로 문서 디자인에서 중요한 역할을 합니다.
p {
font-size: 16px;
line-height: 1.5;
margin: 20px 0;
}
line-height는 요소 내 각 텍스트 줄의 높이에 영향을 주고 여백은 요소 사이의 공간에 영향을 미친다는 점에 유의해야 합니다. 즉, line-height는 각 텍스트 줄 위와 아래의 공간을 결정하고 margin은 요소 사이의 공간을 결정합니다.
(이미지 필요)
결론적으로 line-height와 margin은 모두 텍스트 간격에 대한 중요한 속성이지만 서로 다른 용도로 사용되며 문서 레이아웃에 서로 다른 영향을 미칩니다. line-height는 각 텍스트 줄의 높이를 설정하고 margin은 요소 사이의 간격을 설정합니다. 이 두 속성의 차이점을 이해하는 것은 CSS를 사용하여 효과적이고 읽기 쉬운 문서를 디자인하는 데 필수적입니다.
둘 이상의 요소가 차례로 배치되면 해당 여백이 요소 사이에 하나의 큰 여백으로 결합됩니다. 이 마진을 결합하는 프로세스를 마진 축소라고 합니다.
이 동작의 이유는 요소가 서로 겹치는 것을 방지하고 시각적으로 더 매력적인 레이아웃을 만들기 위함입니다. 요소 사이에 생성된 공간을 사용하여 요소 사이에 계층 구조를 만들 수도 있습니다. 예를 들어 제목과 단락이 있는 경우 단락보다 제목이 더 중요함을 나타내기 위해 둘 사이에 공백을 만들 수 있습니다.
(제목과 문단이 섞여 있는 예시 그림을 보여주면 좋을듯)
여백 축소는 세로로 인접한 요소 사이에서만 발생하며 가장 큰 여백만 남습니다. 예를 들어 한 요소의 여백이 20px이고 다른 요소의 여백이 30px인 경우 요소 사이의 최종 여백은 30px가 됩니다.
마진 축소는 특히 float 및 clear로 작업할 때 예기치 않은 결과로 이어질 수 있다는 점에 유의하는 것이 중요합니다. 이러한 경우 여백 축소 동작을 억제할 수 있으며 여백이 축소되지 않습니다.
결론적으로 Margin Collapsing은 요소 사이의 공간을 보다 쉽게 관리하고 시각적으로 매력적인 레이아웃을 만들 수 있도록 설계된 CSS의 기능입니다. 유용한 도구가 될 수 있지만 제한 사항을 인식하고 예기치 않은 결과가 발생할 수 있는 경우를 이해하는 것이 중요합니다.
#CSS/2장입문
#CSS/2장입문/2.2.Text
목표: CSS의 가장 기본이 되는 글자를 다루는 법에 대해서 배워봅니다.
HTML은 문서를 만들고 공유하기 위해서 시작했습니다. 이후 최초의 CSS는 이러한 문서의 서식을 커스텀하기 위해서 태어났기 때문에 글자에 대한 스타일링은 CSS의 가장 기본 기능입니다.
글자와 관련된 속성들을 외부요소에 영향을 주는 부분이 거의 없고 조합해서 알아야 할 속성들이 적은데다가 워드프로세서나 프레젠테이션 어플리케이션을 통해서 컴퓨터 문서를 다뤄본 경험들이 한번쯤은 있을 것이기에 쉽게 이해할 수 있습니다.
"워드 프로세서의 툴바를 한번 떠올려보세요! 어떤 속성들이 있는지 기억하기 쉬울거에요"
먼저 글꼴의 종류를 선택할 수 있습니다. 그리고 글자의 크기를 변경할 수도 있네요. 그리고 글자의 굵기, 기울임, 밑줄, 취소선의 옵션이 있네요. 또한 글자의 색상을 변경할 수 가 있고 왼쪽, 가운데, 오른쪽, 균등등의 정렬이 가능합니다. 문단의 간격과 들여쓰기의 간격 또한 지정할 수 있습니다.
주요 Property
font-size, font-weight, font-family, text-style, text-decoration, color, text-align
/* <absolute-size> 값 */
font-size: xx-small;
font-size: x-small;
font-size: small;
font-size: medium;
font-size: large;
font-size: x-large;
font-size: xx-large;
/* <relative-size> 값 */
font-size: larger;
font-size: smaller;
/* <length> 값 */
font-size: 12px;
font-size: 0.8em;
/* <percentage> 값 */
font-size: 80%;
/* 전역 값 */
font-size: inherit;
font-size: initial;
font-size: unset;
예전에는 pt라는 단위를 썼지만 지금은 px단위로 사용합니다. 단위에 대해서는 중급편에서 더 자세하게 다루고 초급에서는 px만 우선 사용하도록 합시다!
정말 다양한 크기의 단위! px, pt, em, rem, vh, mm, cm, vmin!
실제로 웹 사이트의 가장 많이 사용되는 단위는 px와 rem입니다. 특히 절대적으로 px의 사용빈도가 높은 만큼 우선 적용하는 단위는 px로도 충분합니다. 다양한 단위에 대한 설명을 XXX에서 한번 설명합니다. 글자크기를 기준으로 하는 반응형 단위인 em과 rem에 대해서는 이 책의 후반부인 "CSS Unit Deep Dive" 에서 다시 한번 다루고 있습니다. 궁금하면 미리 가서 읽어봐도 좋아요!!
폰트 크기는 어떤 단위로 하는 것이 좋은 가요?
폰트 크기를 픽셀로 정하는 것은 사용자가 폰트 크기를 브라우저를 이용해 바꿀 수 없기 때문에 접근성이 떨어집니다. (예를 들어 시각에 제약이 있는 사용자가 폰트 크기를 웹 디자이너가 설정한 크기보다 더 크게 설정하려고 할 수 있습니다.) 그러므로, 접근성 높은 페이지를 만들고자 한다면, 폰트 크기를 픽셀 단위로 설정하는 것을 지양해야 합니다.
반대로 디자인이 중요한 웹 어플리케이션에서는 px를 이용해서 디자인이 틀어지지 않도록 작업을 하는 것이 필요합니다. 문서나 컨텐츠가 중심이 되는 사이트의 경우에는 px보다는 다른 단위를 디자인이 중심이 되는 웹서비스나 어플리케이션의 경우에는 px를 다루는 것을 추천합니다.
굵게, 기울임, 밑줄, 취소선
각자 속성 이름이 다 다른 이유는 함께 굵고 기울임 과 같이 함께 사용 할 수 있도록 하게 하기 위함입니다. 반대 이유로 밑줄과 취소선은 같은 속성이기 때문에 함께 사용할 수 없었답니다. (지금은 가능해요.)
핵심
bold
키워드를 사용합니다.font-weight: normal;
font-weight: bold;
/* Relative to the parent */
font-weight: lighter;
font-weight: bolder;
font-weight: 100;
font-weight: 200;
font-weight: 300;
font-weight: 400;
font-weight: 500;
font-weight: 600;
font-weight: 700;
font-weight: 800;
font-weight: 900;
/* Global values */
font-weight: inherit;
font-weight: initial;
font-weight: unset;
핵심
font-style: normal;
font-style: italic;
font-style: oblique;
font-style: oblique 10deg;
/* Global values */
font-style: inherit;
font-style: initial;
font-style: revert;
font-style: revert-layer;
font-style: unset;
font-style: italic과 oblique의 차이는 무엇인가요?
Font에서 기울임 속성이 있는 경우 italic을 지정하면 기울임 폰트를 사용할 수 있습니다. 기울임 속성이 없는 폰트라면 인위적으로 기본 글꼴을 기울여서 기울임 스타일을 적용할 수도 있는데 그것이 oblique입니다.
그래서 oblique속성에 추가로 각도로 적어줄 수 있는데 현재 대부분의 브라우저에서 아직 지원하고 있지 않습니다.
italic이라는 속성을 지정해준다면 italic이 있는 폰트로 출력하고 기울김체가 없다면 자동으로 oblique로 넘어가도록 되어 있기 때문에 일반적으로 italic을 사용합니다.
Tip: 현대 웹 개발은 디자이너와 개발자의 전문성이 분리가 되어 있으므로 디자이너가 잘 사용하지 않는 속성들은 우리도 잘 사용할 필요는 없습니다.
핵심
- font-family를 통해 글꼴을 변경할 수 있습니다.
- ,를 통해서 여러개의 글꼴을 등록할 수 있는데 첫번째 글꼴이 없다면 차선을 택하는 방식입니다.
- 글꼴은 상속이 되는 속성입니다.
/* A font family name and a generic family name */
font-family: Gill Sans Extrabold, sans-serif;
font-family: "Goudy Bookletter 1911", sans-serif;
/* A generic family name only */
font-family: serif;
font-family: sans-serif;
font-family: monospace;
font-family: cursive;
font-family: fantasy;
font-family: system-ui;
/* Global values */
font-family: inherit;
font-family: initial;
font-family: unset;
일반적으로 현대 웹서비스에서는 글꼴은 잘 수정하지 않습니다. 글꼴 속성은 상속이 되는 속성이기에 보통은 :root나 body와 같이 최상위에 설정을 만들어두고 사용합니다.
시스템 폰트나 일반적으로 잘 사용하는 폰트들이 있어요.
.serif {
font-family: Times, Times New Roman, Georgia, serif;
}
.sansserif {
font-family: Verdana, Arial, Helvetica, sans-serif;
}
.monospace {
font-family: Lucida Console, Courier, monospace;
}
.cursive {
font-family: cursive;
}
.fantasy {
font-family: fantasy;
}
부록1: 굴림, 돋움, Roboto, Noto Sans, 산돌 고딕 이야기
(내용 채워넣기)
부록2: 웹폰트, 구글 폰트 이야기
(내용 채워넣기)
부록3: 모든 시스템 폰트의 결합! Pretendard 폰트 이야기
(내용 채워넣기)
부록4: 웹 안전 글꼴이란?
(내용 채워넣기)
핵심
- text-decoration은 상속이 되는 속성입니다.
text-decoration: underline;
text-decoration: line-thro red;
text-decoration: overline red;
text-decoration: green wavy underline;
text-decoration: none;
/* 전역 값 */
text-decoration: inherit;
text-decoration: initial;
text-decoration: revert;
text-decoration: unset;
.under {
text-decoration: underline red;
}
.over {
text-decoration: wavy overline lime;
}
.line {
text-decoration: line-through;
}
.plain {
text-decoration: none;
}
.underover {
text-decoration: dashed underline overline;
}
.thick {
text-decoration: solid underline purple 4px;
}
.blink {
text-decoration: blink;
}
Tip: Can I Use ~_~ ?
모든 브라우저가 최신의 기능을 제공하는 것은 아닙니다. 스펙이 먼저 확정되어 공개가 되고 브라우저에는 구현이 나중에 되기 때문에 아직 몇몇의 속성들은 아직 동작하지 않는 브라우저들이 있습니다. 이럴때에는 can i use 사이트에서 확인할 수 있습니다.
글자도 왼쪽, 오른쪽, 가운데, 양쪽 정렬을 사용할 수 있습니다.
text-align: justify?
왼쪽, 가운데, 오른쪽,
이런 것들은 그냥 알고 있으면 그냥 외우면 됩니다.
내가 원하는 서식들을 이렇게 만들 수 있게 됩니다.
text-align-last?
justify는 양측으로 균등배분을 하기 때문에 디자인상 안정감이 있으나 영어의 경우 띄어쓰기가 들쭉날쭉해지는 문제가 있습니다. 특히 단어가 얼마 쓰이지 않은 마지막 문장의 경우 균등정렬을 해버리면 다음과 같이 보이는 불상사도 발생하게 됩니다. 그래서 마지막 문장의 경우 왼쪽 정렬로 지정함에 따라 이러한 문제를 막을 수 있습니다. 그렇지만 실제로는 거의 쓰이지 않은 속성입니다.
말씀드리지만 이론을 이해하시는 것이 아니라 css는 숙달을 해야 느는 거기 때문에 최대한 많이 바꿔보시면 좋을 것 같습니다.
그냥 많이 해봐서 이런 디자인을 만들기 위해서는 이러한 속성을 써야 되는구나라고 화면을 디자인을 보면 이제 해당하는 스펙들이나 속성들이 이제 머릿속에 떠올릴 수 있는 어떤 이런 데 숙사됨이 필요하다라는 얘기였습니다.
#CSS
#CSS/2장입문
#CSS/2장입문/2.2.Text
CSS Box Model은 모든 HTML 요소가 콘텐츠, 패딩, 테두리 및 여백으로 구성된 직사각형 상자라는 개념입니다. 이러한 상자는 서로 중첩되어 웹 페이지를 구성하는 상자의 계층 구조를 만듭니다.
다음은 CSS Box Model의 시각적 표현입니다.
![](A031F62E-1A6C-4662-8955-A9C763D1A9AD-44702-00000C8637811A0E/Screen Shot 2019-04-14 at 23.59.07.png)
콘텐츠: 실제 콘텐츠(텍스트, 이미지 등)가 배치되는 상자의 가장 안쪽 부분입니다. width 및 height 속성은 콘텐츠 영역의 크기를 나타냅니다.
패딩: 패딩은 콘텐츠를 둘러싸고 콘텐츠와 테두리 사이에 간격을 제공합니다. padding속성은 요소의 전체 너비와 높이의 일부입니다 .
테두리: 테두리는 패딩과 콘텐츠를 둘러싸며 요소를 다른 요소와 구분하는 스타일 가능한 선을 제공합니다. 이 border속성은 요소의 전체 너비와 높이의 일부이기도 합니다.
여백: 여백은 경계 외부에 약간의 숨쉴 공간을 제공하여 요소를 다른 요소와 분리합니다. 속성 은 margin요소의 전체 너비와 높이에 영향을 주지 않습니다.
요소의 총 너비와 높이는 콘텐츠 영역, 패딩, 테두리 및 여백의 합계라는 점을 명심하는 것이 중요합니다.
(관련 CSS 속성과 예시 코드들 그리고 시각적인 이미지들이 필요하다)
(width: auto, width: % 등에 대한 정보도 필요하다)
(box-sizing: content-box 모드에서 width를 계산하는 공식 content + padding + border-width에 대해서 설명하면서 문제점을 언급하면서 다음 장으로 자연스럽게 넘어가도록 하자)
#CSS/2장입문
#CSS/2장입문/2.3.Box
box-sizing의 진화: content-box에서 border-box로
CSS는 끊임없이 진화하는 기술이며 box-sizing 속성은 웹 디자이너의 요구 사항을 더 잘 수용하기 위해 CSS가 어떻게 변경되었는지를 보여주는 완벽한 예입니다.
이 장에서는 box-sizing의 역사와 함께 border-box가 왜 더 권장되는 방법인지 이유를 자세히 살펴보겠습니다.
CSS 초창기에 box-sizing 속성의 기본값은 content-box 였습니다. 이는 요소의 전체 너비와 높이가 패딩이나 테두리를 고려하지 않고 콘텐츠 영역만을 기준으로 계산되었음을 의미합니다.
이 모델은 웹 페이지가 주로 텍스트 및 간단한 이미지와 같은 문서 스타일 콘텐츠에 사용되던 초기 웹 시대에 적합했습니다. 그러나 웹 디자인이 진화하고 정교해짐에 따라 content-box 모델의 한계가 분명해졌습니다.
content-box 모델의 문제는 특히 패딩과 테두리를 고려할 때 요소의 전체 너비와 높이를 예측하기 어려울 수 있다는 것입니다. 예를 들어 다음 HTML 및 CSS를 고려하십시오.
<div class="box">
<p>Some content</p>
</div>
<style>
.box {
width: 200px;
height: 100px;
padding: 20px;
border: 5px solid blue;
margin: 10px;
}
</style>
content-box 모델을 사용하면 요소의 총 너비와 높이가 200px + 20px + 20px + 5px 이 되므로 예상치 못한 레이아웃 문제가 발생할 수 있습니다.
(예시 그림이 필요하다)
content-box 모델의 한계를 해결하기 위해 border-box값이 도입되었습니다. 이 border-box값을 사용하면 콘텐츠 영역, 패딩 및 테두리를 기준으로 요소의 총 너비와 높이가 계산되며 테두리는 패딩 안에 배치됩니다.
상자 크기 조정 모델에 대한 이러한 변경으로 특히 패딩과 테두리가 있는 요소로 작업할 때 요소의 전체 너비와 높이를 훨씬 쉽게 예측할 수 있습니다.
border-box값을 사용할 수 있는 방법의 예는 다음과 같습니다 .
.box {
box-sizing: border-box;
width: 200px;
height: 100px;
padding: 20px;
border: 5px solid blue;
margin: 10px;
}
이 예에서 요소의 전체 너비와 높이는 .box예상대로 200x100px입니다.
(예시 그림이 필요하다)
box-sizing의 진화는 웹 디자이너의 변화하는 요구 content-box를 반영합니다.
border-box웹 디자인이 더욱 정교해지고 복잡한 대화형 애플리케이션을 만드는 데 집중함에 따라 border-box모델은 요소의 전체 너비와 높이를 처리하는 보다 예측 가능하고 유연한 방법을 제공합니다.
이 border-box모델은 가까운 장래에 box-sizing을 처리하는 권장 방법이 될 것이며 웹 디자이너와 개발자에게 필수적인 도구가 될 것이라고 해도 무방합니다.
"그렇다면 모든 속성들을 content-box를 쓰지 않고 border-box로 바꾸면 안되나요?"
브라우저는 웹 표준에 의해서 새로운 기능이 추가되며, 기존에 동작하고 있던 사이트들의 호환성을 유지하기 위해서 한번 만들어진 속성과 표준은 되돌릴 수가 없습니다.
따라서 당시에는 존재하지 않았던 box-sizing의 방식을 border-box로 바꾸기 위해서는 다음과 같은 CSS를 늘 추가로 작성을 해야합니다.
* { box-sizing: border-box }
위와 같이 이미 더 나은 속성으로 초기화 하기 위해서 CSS Reset이라는 기법을 쓰게 됩니다. 자세한 내용은 다음장 CSS Reset편에서 더 자세히 다루도록 하겠습니다.
CSS box-sizing 속성은 초기 웹의 content-box 모델에서 오늘날의 border-box 모델에 이르기까지 상당한 발전을 거쳤습니다. border-box 모델의 변경으로 요소의 전체 너비와 높이를 훨씬 쉽게 예측할 수 있습니다.
결론적으로 CSS의 box-sizing 속성은 웹 초창기의 content-box 모델에서 시작하여 오늘날 널리 권장되는 border-box 모델로 전환하는 등 큰 변화를 겪었습니다.
이 변경으로 인해 특히 패딩 및 테두리가 있는 요소를 처리할 때 요소의 총 너비와 높이를 훨씬 쉽게 계산할 수 있습니다. border-box 모델은 이제 웹 디자이너와 개발자에게 필수적인 도구로 간주되며 앞으로도 표준으로 남을 것으로 예상됩니다.
하지만 실제 표준이 될 수는 없기 때문에 Reset은 수동으로 해야합니다.
#CSS/2장입문
#CSS/2장입문/2.3.Box
Normal Flow에 대해서 이해하자.
1. block 요소
2. inline 요소
3. Float & Clear
(float은 할까 말까? 안해도 될듯...)
(아직 내용을 정리하지 못했습니다.)
CSS의 Layout은 기본적으로 겹치지 않게 배치하려고 한다.
Normal Flow는 일반적으로 워드프로세스등의 글쓰기 도구의 레이아웃이다. 글자는 오른쪽으로 문단(요소)는 세로로
배치가 되는 순서와 display 속성 그리고 block요소와 inline 요소의 차이점에 대해서 설명한다.
inline요소는 width, height를 가지지 않는다는 것을 알려준다.
inline-block은 3장에서 알려주도록 하자.
같은 엘리먼트로 표현이 되지만
글자와 박스를 분리해서 생각하면 좋다
#CSS/2장입문
#CSS/2장입문/2.4.Layout
문서에서 앱으로 진화하는 과정에서 생긴 레이아웃 스펙의 과도기 시절
Web은 최초 문서를 만들기 위해서 만들어졌지만 웹 산업이 점점 발전하면서 사용자와 인터렉션이 강화되면서 점점 단순한 문서가 아니라 홈페이지의 형태로 그리고 점점 더 어플리케이션과 같은 역할을 하게 되면서 웹 디자인의 요구사항이 변화하게 되었습니다.
CSS는 처음에는 이러한 어플리케이션 UI를 만드는 의도를 가진게 아니었기 때문에 이러한 어플리케이션 UI와 레이아웃을 만드는 방법이 없었습니다.
그래서 원래 이미지와 문서를 어울리게 배치를 하기 위한 float라든가 표를 만들기 위한 table, 기타 inline block과 같은 문서를 만들기 위한 스펙들을 조립해서 복잡하게 레이아웃을 해야하는 과도기 시절이 있었습니다.
flexbox는 Application 레이아웃을 하기 위해 태어났다.
그래서 사람들은 CSS로 복잡한 UI를 만드는 것에 불만이 있었고 이러한 레이아웃을 하기 위한 새로운 스펙을 만들어야 했습니다. 이후 2009된 출시된 box라고 붙여진 레이아웃방식이 태어났지만 다양한 레이아웃을 다 담아내지 못했기에 한번 deprecated 되었고 이후 flexbox라는 스펙이 2012년 정식으로 태어났습니다.
하지만 당시 Major 브라우저인 IE의 지원부족으로 인해 여전히 복잡한 CSS를 통해서 레이아웃을 해야만했고 사람들이 습관처럼 당연히 IE를 지원을 해야하다 보니 해당 스펙이 보편화가 되기까지는 오랜시간이 필요했습니다.
그러면서 이때 만들어진 자료들이 제일 많았기 때문에 flexbox의 사용법이나 응용법에 대해서는 저마다의 방법들이 달랐으며 덕분에 CSS의 레이아웃은 여전히 어려운 스킬이었습니다.
앱 레이아웃의 시작은 가로로 배치한다는 것
(여기는 다다시 쓸 것)
(요점 - 가로로 배치하는 것이 달랐다! 중요하다!)
flebox는 문서가 아니라 어플리케이션의 UI를 만들기 위해서 탄생을 했다고 하였습니다. 그렇다면 문서와 어플리케이션 UI의 가장 큰 차이점이 뭘까요? 아니 기존 CSS에서 가장 하기 힘들었던 UI는 어떤 것이었을까요?
기존 문서기반의 CSS에서 가장 어려웠던 것이 바로 콘텐츠를 가로와 중앙에 배치한다는 거였습니다. 그래서 flex라고 만들어졌던 것들 처음에 기본 개념이 아무것도 속성하지 않았을 때는 가루로 배치된다는 걸 알 수가 있죠.
여하튼 콘텐츠에서 가로로 배치한다는 거는 굉장히 중요합니다. 그래서 플렉스 박스는 내가 어느 방향으로 콘텐츠를 배치할지를 결정할 수 있고 이 콘텐츠를 어떤 식으로 놓을지 어떤 식으로 간격을 벌려놓을지 그리고 남는 크기에 따라서 어떻게 크기를 지정을 할 수 있을지 이러한 단계로 레이아웃을 결정할 수 있게 됩니다.
이때부터 컨테이너라는 개념이 생겼다.
이때부터 컨테이너라는 개념이 생겨납니다. 그전까지 CSS 레이아웃의 기준이 항상 본인을 중심으로 하는 개념이었다면 처음으로 레이아웃을 중심으로 하는 자식의 레이아웃을 구조를 반영하는 부모가 레이아웃을 컨트롤하는 어떤 형태의 구조가 나왔다라고 보시면 될 것 같습니다.
그래서 앞에서 배웠던 css와는 다르게 외부에서 레이아웃을 잡아주는 형태로 생각을 하셔야 돼요 그래서 나의 레이아웃이 아니라 이 자식들의 콘텐츠 간의 배치를 돕는 속성이다라고 생각을 해 주시면 좋을 것 같아요.
그래서 가로로 배치를 하게 되면 지금 보시는 것처럼 내가 어떤 콘텐츠가 있을 때 내가 콘텐츠를 가로로 배치할 것인가 세로로 배치할 것인가 결정을 할 수가 있습니다.
자식 컨텐츠(=컴포넌트)의 레이아웃 요소를 배제하고 레이아웃만 담당하는 컨테이너로 배치를 하는 방식이 보편화 됨.
과도기는 끝났다! 이제는 flexbox만 써도 되는 상황이 왔습니다.
2022년 현재 flexbox는 사용하지 못하는 브라우저가 없으며 인지도 및 사용율의 거의 100%에 가까운 스펙이기에 레이아웃을 한다면 flexbox를 사용하는 것이 너무 당연한 정석이 되었습니다.
그러나 아직도 오래전에 만들어진 사이트들이 float등으로 레이아웃이 되어 있기도 하고 이미 만들어진 커리큘럼이나 웹 문서등으로 인해 flexbox의 최신 방법들이 아닌 레이아웃 방식이 아직 남아있기도 합니다. 지금은 flexbox나 grid가 아닌 다른 방식이 아닌 방식으로 레이아웃을 설명하고 있다면 문서의 연도를 꼭 확인해보시기 바랍니다.
flexbox가 모든 브라우저에 동작을 하고 사용자들의 경험치가 쌓이면서 이제는 각자만의 Best Practice들이 정립이 되고 있는 중입니다.
flexbox의 스펙 역시 모든 스펙을 사용할 필요가 없습니다. 이번 장에서는 제가 정립한 flexbox의 핵심 내용을 함께 배워 보려고 합니다.
이제 옛날 스펙 레이아웃은 사실상 쓸모가 없다. 원래 의도로만 써야한다.
float, inline-block, table 로 레이아웃을 해야할 필요가 없다. XX장에서는 기타 레이아웃 속성을 모아서 이해할 수 있도록 모아두었습니다. 해당 레이아웃의 취지를 이해하고 그 스펙으로만 할 수 있는 레이아웃을 작업 하도록 합시다.
flexbox는 현재 CSS의 보편적인 레이아웃을 쉽게 만들어 낼 수 있는 스펙이기에 꼭 알아야할 CSS의 꽃과 같은 존재입니다.
이번 장에서는 웹의 레이아웃의 가장 기본이 되는 개념 flexbox에 대한 이야기를 해보려고 합니다!
Let's go!
필독! CSS는 많이 아는 것보다 Best를 찾는게 중요하다.
(다시 써야됨. 아래 내용은 글이 아니라 메모 입니다. )
CSS는 여러가지 방법으로 같은 모양을 만들어 낼 수 있다. 방법을 많이 아는게 중요하지 않다. 간단하고 최소한의 노력으로 원하는 모양을 만들어 내는 방법을 알고 있는 것이 중요하다. 여기에서도 깊게 얘기하지 않고 꼭 필요한 핵심만 먼저 적을 것이다. 더 몰라도 되니 이것의 사용법에 먼저 익숙해져라. 이후 고급편에 다시 추가적으로 더 알면 좋을 만한 스펙을 알려줄 것이다.
절대로 하나씩 하나씩 다 깊게 팔 배우고 하는 게 아니라 자기 손에 꼭 맞는 베스트한 방법들을 찾는 게 중요하고요 여기서 설명드릴 것은 저도 가장 간소한 방법에 대해서 간단하게 플렉스 박스를 할 수 있는 방법에 대해서 알려드리려고 합니다.
CSS는 숙달이 더 중요하기 때문에 핵심만 먼저하고 추가적인 이론을 뒤에 다루는 방식으로 진행하겠습니다!
Best Practice의 소스: figma의 AutoLayout!
figma AutoLayout은 flexbox의 subset으로 일부 개념만 축소해서 가져왔다.
그럼에도 거의 대부분의 디자인이 가능! 디자이너가 모든 스펙을 쓰지 않아도 디자인이 되는데 개발자가 굳이 복잡하게 바꿔줘야할 이유가 없다.
제가 써왔던 경험과 AutoLayout을 근거로 Flexbox의 핵심과 Best Practice를 알려드립니다.
figma AutoLayout의 핵심 구성
(figma AutoLayout의 UI 설명 - 책에서 사용해도 되나? 아니면 언급 정도만 하면서 넘어가자.)
1 방향 - 가로, 세로
2 배치 + (space-between)
3 패딩
4 간격
5 크기 - hug content, fixed width, fill-container
⠀이것만으로 충분하니 이 정도의 범위만 핵심으로 익히고 실습을 해서 익히고 나면 고급을 배우도록 하자!
flexbox도 이 부분만 가지고 얘기를 하겠습니다.
일단 플렉스 박스 이해를 합시다 문서처럼 보이지 않는 레이아웃이라는 것들은 어떤 걸 과연 이런 거죠.
출바라든지 대표적인 케이스가 이 바로
툴과 아니면 내비 모양입니다 가로로 배치하는 부분이거든요.
우선은 기본적으로 콘텐츠는 저렇게 가로로 배치하는 게 없어요.
콘텐츠를 가로로 배치할 것인가 세로로 배치할 것인가: flex-direction(= flex-flow)
그래서 이 방향을 결정해 주는 걸로 flex-direction라는 걸 쓰고 있고요
row한 방향이냐 column만 방향이냐 두 가지를 정할 수 있습니다.
구 버전에서는 horizontal, vertical이어서 조금 더 직관적이었다고 생각합니다. row=가로, column=세로로 기억해두자. 기존 스펙을 덮어 쓸 수 없다는 점이 있고 타이핑 측면에서는 지금이 나은 것 같다.
그리고 이렇게 방향이 결정이 되었다면 이제 콘텐츠들이 박스에서 어디에 놓일지를 한번 생각을 해봅시다 콘텐츠가 존재한다면 이 박스는 레이아웃의 가운데에 배치될지 상단에 배치될지 혹은 하단에 배치될지 왼쪽에 배치될지 오른쪽에 배치될지
혹은 가운데 배치될지 이런 9가지의 배치 방법이 존재합니다.
flow-direction은 방향을 설정한다. flex-flow는 방향과 flex-wrap을 함께 적을 수 있는 속성이다. 결국 짧은 CSS를 작성하는게 좋으니 이후 flex-direction대신 flex-flow로 작성을 하겠습니다.
메인 축과 교차 축
(컨텐츠를 배치하는 9군데 영역, 다 그려서 펼쳐주는 방식으로 그려두자!)
박스형 컨테이너 내부에 컨텐츠를 배치하게 된다면 우리는 위와 같은 다양한 방법으로 컨텐츠를 배치할 수 있게 됩니다. flexbox는 이렇게 다양한 배치를 하기 위해 크게 2가지의 방향으로 나눠서 어떤식의 배치를 할지 조립하도록 설계가 되었습니다.
(이건 좀 좋게 다시 그리자!, 가로 세로 둘다..)
flexbox라는 거는 메인 축이 존재하고 그다음에 교사 축이 존재해서
온라인 바이패지는 교차 축에 대한 어떤 위치를 잡는 것이다라고 되어 있는데요.
조금 더 쉽게 이야기하려고 하면 바라보는 방향에서 좌우를 컨트롤 한다는 개념으로 생각하시면 될 것 같습니다.
내가 가로를 배치하고 있을 때 나는 가로를 이 방향으로 바라보고 있으니까 anline iite들은 왼쪽과 오른쪽
건들게 되는 부분인 거고요 제대로 바라보는 방향에서는 위아래겠네요.
좌.우.가운데, 늘리기! : align-items
그래서 이 배치를 바꿀 수 있는 방법 그걸 알아야 되는데 첫 번째로 알아야 될 내용이 온라인 아이템즈입니다.
온라인 아이템즈는 보통 설명을 배우면 보통 이렇게 되어 있습니다.
메모:
(사람이 바라보고 양팔을 벌리고 있는 그림)
(좌, 우, 가운데, 늘리기를 팔로 보여주고 있는 그림)
align-items는 크로스, 좌우, a키를 누르고 있는 것을 상상해보자. (왼쪽 오른쪽)
가로에서 보았을때는 start가 위, 아래
세로에서 보았을때에는 start가 좌, 우
이것은 글자를 쓰는 순서와 연관이 되어 있다.
이제 해로를 알아봤을 때는 이렇게 이렇게 좌우라고 생각하시면 좋겠습니다.
이렇게 머릿속에 한번 기억만 해주시면 다음부터 어렵지 않으실 거고 머릿속에 그림이 그려지실 거고요 외우는 방법은 왼손의 키보드에 a를 누른다는 생각으로 왼쪽 오른쪽 이 그림 그리고 잡아서 늘린다 이렇게 이름만 생각을 하시면 이거 설명을 해주고 이 얘기를 해줘야겠다.
바이러스 콘텐츠를 가운데 배치하기 위해서는 이 a라인 아이템들을 센터로 두시면 센터 라인에 정렬을 해서 맞출 수가 있게 됩니다.
그리고 네 밑에 만들고 싶으면은 플렉스 랜드를 쓰시면 되고 상단으로 대체하고 싶으면 플렉스 스타트를 쓰시면 됩니다.
콘텐츠가 이렇게 있으면은 나라는 방향으로
어떻게 모아둘까? 벌려둘까? : justify-content
align이 늘리기라고 외웠으면 justify-content는 space-between 과 짝꿍. 꼭 함께 외워야 한다.
(그림으로 보여주기, 왼쪽, 오른쪽, 가운데, space-between)
메인 축으로의 어떤 배치도 봐야겠죠.
이럴 때는 콘텐츠 저스티파이라는 걸 씁니다.
스트레스도 얘기해야 되고 늘린다도 얘기해 줘야 되고
콘텐츠 간의 간격이랑 어떻게 놓을지가 중요하기 때문에 네 앞쪽으로 모아놓을지 뒤쪽으로 모아놓을지
그리고 저스티파이는 스트레이스 비투윈과 함께 연결해서 외우시면 되겠습니다.
그래서 내가 왼쪽으로 모으겠다라고 스타트고요 오른쪽으로 모으겠다라고 마인드입니다.
그리고 언제나 스타트는 위 아래 혹은 자 이렇게 되어 있고 언제든 늘릴 수가 있다.
그리고 콘텐츠가 여러 개 들어가는 공간이면은 콘텐츠를 벌릴 수 있다.
벌리는 거는
스페이스 비투비 비스트 비스 비투비는 저 스티파일이랑 콘텐츠와 함께 묶어주시고 라인 아이템들은 라인 아이템들을 늘려준다 이렇게 개념을 머릿속에 들고 가시면 배치하는 데는 그렇게 어려움이 없습니다.
그래서 우리는 콘텐츠를 어떻게 배치하고 종료해 둘 수 있는지를 알게 되었습니다.
조합 연습해보기
그래서 다음과 같은 순서대로 작성을 해봅시다.
1) flex-flow: 컨텐츠의 방향
2) align-items: 방향과 교차방향의 위치
3) justity-content: 나머지 위치
계속 크로스로 확인하는 것이 포힌트
(말로 설명하니까 이상하다 이 과정을 그림으로 보여주자.)
이러한 방향들은 글을 쓰는 방향을 기준으로 만들어졌다.
헷갈린다면 계단을 그려보자! 방향, flex-end, flex-end
➡️⬇️➡️
.hbox--bottom-right {
display: flex;
flex-flow: row;
align-items: flex-end;
justify-content: flex-end;
}
⬇️➡️⬇️
.vbox--right-bottom {
display: flex;
flex-flow: row;
align-items: flex-end;
justify-content: flex-end;
}
연습해보기
다음 예시들을 보고, 방향, align-items, justift-content 알아맞혀 보기
예시 1) 1 2 3
예시 2) 123
예시 3) 123
(예시 배치 그림 그리기)
이런 것들을 게임으로 해볼 수 있는 연습 방법이 존재한다. flexbox froggy, flexbox 좀비. 추천!
이제 세부적인 디자인은 바로 간격!! 간격은 크게 2가지
1) 컨테이너와 컨텐츠의 간격
2) 컨텐츠 간의 간격
(이것도 좀 그림으로 그리자)
이제는 margin으로 간격을 조절하는 것은 좀 old한 방법...
기존에는 이러한 간격을 조절하는 방식을 Element를
기존에는 이런 것들을 좀 마진으로 해결을 하려고 했어요.
하지만 시간이 지나고 확인을 해보니까 마진으로 작업을 하는 거는 별로다라는 것을 깨닫게 됩니다.
왜냐하면 컴포넌트의 마진을 보통 이런 것들을 프레임워크로 만들다 보면 보통 이 버튼들이 컴포넌트 형태로 정리가 되는데 컴포넌트의 마진이 들어가게 될 경우엔
컴포넌트를 배치하거나 컨트롤하는 데 굉장히 어렵다는 것을 알게 돼요.
(마진을 쓰면 누구에게 마진을 줘야할지 고민하는 내용의 그림)
예전에는 이 세부적인 사이의 간격을 margin을 통해서 작업을 했었어요.
하지만 컴포넌트의 방식으로 변하게 되면서 컴포넌트의 마진을 가지고 있다는 것은 굉장히 안 좋다라는 걸 깨닫게 됩니다.
왜냐하면 마진이라고 하는 거는 아이템의 어떠한 주위에 서로의 영향으로 콘텐츠가 만들어지는 건데 보통은 대부분 어떤 콘텐츠와 어떤 콘텐츠 사이의 간격이라고 표시가 되고 있거든요.
그러면 이 마진에 대한 소유권에 대한 문제가 발생을 하게 됩니다.
과연 이 사이의 간격은 이 친구의 것일까요.
이 친구의 것일까요. 이런 부분이 헷갈리기 때문에 현대에 들어가서는 이렇게 margin을 개념을 쓰기보다는 이 사이의 간격을 표시하는 gap이라는 개념을 가지고 프로그래밍을 하도록 스펙이 나왔습니다.
이게 더 좋다는 것을 알게 되었거든요.
(일반적인 디자인 명세서와 함께 gap의 의미를 설명하는 그림)
이 것이 컨테이너 개념으로 생각하는 연장선상!
margin이 나쁘거나 쓰면 안된다는 얘기가 아니다~ margin을 안씀으로써 우리가 더 편하고 일관되게 CSS를 쓸 수 있다는 의미! 필요하면 써야지. 융통성을 가지자!
그래서 지금은 gap과 padding을 쓰자!
그래서 가급적 컨포넌트에서 마제를 주도하거나 아이템의 margin으로 간격을 맞추는 게 아니라 부모에서 컨트롤 하는 게 좋다는 식으로 만들어지고 그래서 그냥 따끈한 스펙인 갭이라는 게 등장을 합니다.
그래서 이 갭을 통해서 맞추는 걸 확인할 거고요
단순합니다. 그래서 갭을 얼마를 적으시면 이 사이 간격이 얼마씩 늘어나고 있다는 것을 확인할 수 있습니다.
그러면은 이 바깥의 간격은 어떻게 할 거예요.
우리가 알고 있는 패딩을 쓰면 되겠습니다.
그래서 바깥에 있는 여백의 패딩 그리고 콘텐츠 간 간격의 갭을 이용해서 우리가 원하는 레이아웃을 적절히 만들 수 있게 됩니다.
그래서 메모를 그려보시고 내가 콘텐츠를 배치한 다음 이렇게 이렇게 있는 화면에서 각각의 아이템을 통해서 콘텐츠를 배치해보는 해보신다면 디자인을 원하는 대로 만들 수 있게 됩니다.
이렇게 하면 콘텐츠를 그래서 출발을 한번 만들어 봅시다 기본적으로 나중에 해야겠구나 이런 식으로 콘텐츠를 배치하
gap이 없던 시절에는 >+ 올빼미를 썼다.
그래서 이 갭이 없던 시절에는 다음과 같은 부엉이 표기법으로
이 갭이라는 걸 쓸 수가 있게 되었고요 지금은 정식 표준 스펙이 되었기 때문에 갭이라는 것을 쓰면 됩니다.
gap 스펙은 아직 IE 11과 사파리 14 이하 버전에서 동작하지 않는다.
지금 현재 쓰고 있는 주류 브라우저가 브라우저에 아직까지 사파리 14 이하나 이 11이 존재하고 있다라고 하면 예전에 쓰고 있던 갭을 사용할 수 있기 때문에 그대로 사용하셔도 괜찮습니다.
(올빼미 표기법에 대한 간단한 설명..)
이게 길어지겠다 싶으면 부록으로 옮긴다.
다른 크기의 gap이 필요할 때 1? space
그게 아니라면 가운데에 스페이스를 넣어두는 방식도 추천을 합니다.
하나는 빈 엘리먼트를 집어넣어서 백을 여백처럼 동작하는 어떤 콘텐츠를 집어넣는 방식인 거고요
HTML에 빈 엘리먼트를 만들어서 간격을 채워두는 방법도 있다.
(코드 보다는 이미지가 낫겠다.)
다른 크기의 gap이 필요할 때 2? sub-flexbox
나머지 하는 방법은 이제 여기만 다시 다시 그룹으로 묶어서 거기 콘텐츠의 갭을 따로 별도로 지정하는 방식입니다.
이런 방식으로 이런 이렇게 박스를 다시 그룹이 하기 위해서는 부모의 어떤 속성과 똑같으면 되기 때문에 이럴 때는 이런 서브 박스 혹은 서브 클래스라는 어떤 클래스를 만들어서 사용하면 굉장히 편리합니다.
응 그 밖에 그리고 나머지 공간에 대해서 내가 콘텐츠를 늘려서 공간을 채우는 방식 이 필요하게 되고 이게 플렉스 박스에 꽂힌 플렉스라는 속성입니다.
.sub-flexbox {
display: inherit;
flex-flow: inherit;
align-items: inherit;
justify-content: inherit;
}
서브박스는 앞에서 설명을 했지만 한 번 더 설명을 드리자면 서플렉스 같은 느낌을 만들 수가 있습니다.
그는 디스플레이 inn리트를 이용하고 라인 itt나 stfi 콘텐츠를 이내리 해서 내가 그룹을 만들고 거기에 적당한 갭을 주게 되면 이 앱을 통해가지고 내가 원하는 어떤 특정 영역만 조금씩 떨어뜨릴 수 있는 방법으로 만들 수 있습니다.
이렇게 하지 않더라도 가운데
가운데에 어떤 스페이스를 줄 수가 있게 되는데 내가 전체적으로 김을 건 다음에 여기 스페이스를 주게 되면 이 스페이스를 따로 계산해야 되는 어떤 문제가 발생하기 때문에 그걸 생각을 하셔서 이걸 대체하셔도 내가 이게 굳이 감싸는 거에 대해서 귀찮음이 있을 경우에 이런 걸 만들지 않아도 좋고 필요하다면 이런 부분들은 비트리스를 만들어줘서 작업을
figma에서는 3가지 타입으로 나눈다. hug-contents, fixed-size, fill-container
우리도 이렇게 3가지로 나눠서 생각하자.
컨텐츠에 따라서 vs 고정된 크기로
width, height가 auto인 경우에는 내부 컨텐츠의 크기를 따라간다. 크기를 지정하면 컨텐츠와 관계없이 크기가 고정이 된다.
flexbox에는 추가로 가변 크기가 존재한다. flex: 1
가변의 어떤 영역이 필요한데 이 가변의 영역을 정해주는 게 플렉스 플렉스를 알고 있어야
플렉스 박스를 다 아는게 되는 거죠.
플렉스는 복잡하게 생각하지 말고 이 중에 크기 하나를 가변으로 만든다라고 생각하시면 되겠습니다 가변이기 때문에 나머지 공간을 그냥 꽉 채워준다라고 생각하시면 될 것 같아요.
그래서 패치가 필요한 부분에 언제든지 클래스를 통해서
얘를 가변으로 만들어주기 면 나머지 공간을 알아서 채우고 혹은 선택에 따라서 줄어든다 그래서 보편적으로 디자인은 어떻게 하느냐 자식의 콘텐츠는 기본적으로 세 가지 속성을 가집니다.
콘텐츠를 따라 가든가 아니면 고정된 크기가 있거나 혹은 플렉스하게 나쁘거나 이 세 가지 속성을 지정해 주는 방법을 알고 계시면
flex-grow?, flex-shrink?, flex-basis?
이 플렉스라는 속성은 플렉스 글로우 블렉스 슈링크 플렉스 베이시스라는 세 가지 속성으로 만들어지고 있는데
각각에 대해서 설명을 하자면 는 만큼 남는 공간이 있을 때 얼마만큼 정도를 분배를 해서 넣을 것이고 줄일 것이고 크게 할 것이고에 대한 얘기지만 사실 이거를 이론적으로 이해하기에는 되게 복잡하기 때문에 그냥 내가 이 중에서 적어도 하나의 플렉스는 가지고 있다라고 생각을 하시면 굉장히 단순하게 생각을 할 수 있습니다.
그래서 지금까지 알려줬던 plex 박스의 이 개념들 방향을 정하고
어디에 배치하고 좌우로 배치하고 앞뒤로 배치하고 간격을 정해주고 패딩을 정하고 간격을 정해주고 하는 이 방식만 가지고 그리고 나머지 특정 공간에서 반응형 가변으로 작동을 해야 되는 공간 옆 가면으로 작동해야 되는 공간을 지정해 주는 이 단계만 가지고도
플렉스 박스의 90% 이상의 실전에서 나오는 모든 데이터를 할 수가 있습니다.
일단 * { flex-shrink: 0} 으로 설정하고 flex: 1만으로 충분히 다 커버가 가능하다.
자세한 개념은 고급 편에서 다시 설명을 합니다.
일단 flex:1 의 활용법을 익혀봅시다.
(flex:1을 이용하고 있는 예시 이미지들)
특별히 하나의 컨텐츠만 크기가 다르면 콕 집어서 align-self 혹은 justify-self를 사용해 줄 수 있습니다.
컨텐츠마다 정렬의 기준이 다를 때 사용합니다.
(예시 카톡의 채팅방 디자인의 시간대 표기)
tip2: fill-container를 만드는 방법 align-self: stretch
@TODO: 내용 좀 더 추가할 것
#CSS/2장입문
#CSS/2장입문/2.4.Layout
오버레이의 핵심은 그러니까 포지션을 알고 있다는 기본인 거고 이거 스태틱 이어가 기본인 거고 결국 디자인 툴에서부터 우리가 힌트를 얻어야 된다고 했죠.
디자인 툴에서는 포스트 레인츠 발음이 맞나 라고 하는 것들을 만들고 있어요.
피글만에서도 이제 그런 걸 사용하고 있는데 이건 뭐 하는 거냐면
어디를 기준으로 얼마만큼 띄울 것인가라고 하는 부분입니다.
우리가 절대적으로 어떤 위치를 만드는 것 릴레이티브나 앱솔루트를 이용하는 것은 사실 어렵지 않아요.
어렵지 않은데 어떤 크기가 변했을 거나 만들었을 경우에 이거를 조립을 해서 우리가 원하는 형태의 것들을 만들 수 있는 것들이
이 포지션이 모지션을 기본적으로 잘 다루는
상식입니다. 그래서
실습 과제는 다음과 같습니다.
일단 이론 공부부터 해야겠네요.
기본적으로 문서를 만들려고 했기 때문에
css에서는 콘텐츠들을 겹치지 않게 배치를 하려고 자동적인 레이아웃을 만들어내는 기능들을 굉장히 많이 넣었습니다.
아시겠지만 기본적으로 글자와 내용을 편집하는 로멀 플로우도 그렇고 플렉스 박스 레이아웃들도 가급적 이제 콘텐츠가 자동 겹치지 않고 배치될 수 있도록 만들어 놨던 것들인 거죠.
하지만 일반적으로 디자인 툴이라고 하는 것들은 이제 레이어라는 어떤 개념으로
이제 드로잉을 쌓아 올라가면서 만들었기 때문에 기본적으로 이제 콘텐츠가 겹칠 거라는 것을 전제로 만들고 있습니다.
그래서 이 레이어라고 하는 개념 그리고 절대적인 좌표로 콘텐츠를 이동한다는 개념들이 이제 포함이 되고 있죠 그래서 일반적인 어떤 문서나 콘텐츠가 아니라 이러한 요소들이 필요할 때 무언가 이제 콘텐츠를 위로 올려야 할 때 겹치게 만들어야 할 때
사용하는 개념이 바로 이 포지션입니다.
그래서 제가 이걸 설명드릴 때 키워드를 오버레이라고 적었던 거예요.
요는 이제 우리가 콘텐츠를 겹치게 배치하기 위해서는 이제 어떤 것들을 알아야 되는가라는 겁니다.
.overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: 0;
transform: translate(0,0,0);
z-index: 0;
}
그래서 다음과 같은 속성들을 내가 이 기준으로 봤을 때 이제 다음과 같은 속성들을 함께 세트로 기억을 하시면 좋을 것 같아요.
기본적으로 이제 포지션 그리고 3 라이트 바텀 레프트 그리고 마진 그리고 트랜스폼
네 이것들을 조합을 해서 이제 우리가 원하는 어떤 형태를 만들어낼 수 있는 것이 우리 이 스터디의 특별 과제입니다.
이동 해보자!
아무런 변화가 없다!. position의 속성을 바꿔줘야만 한다.
기본값은 position: static이므로 위치와 관련된 속성이 아무것도 적용이 되지 않는다.
하나씩 이제 어떤 것들을 할 수 있는지 이제 짚어보시죠 우리가 어떤 콘텐츠를 기준으로 이제 좌우를 움직이고 싶을 때 한 5픽셀만큼 픽셀만큼 이동하고 싶을 때
우리는 relative라는 것들을 쓸 수 있습니다.
그래서 포지션에 relative를 주고 top을 right로 opx를 만들어 주시면 우리가 원하는 형태의 다음과 같은 샘플 형태를 볼 수 있습니다.
수치를 조정해 보세요. 탑 라이트 바텀 레프트 4방향으로 우리는 현재 기준으로 콘텐츠가 움직일 수 있게 됩니다.
포지션에 다른 속성을 만들어볼까요. 포지션에 다른 속성을 만들게 되면 이렇게 앱솔루트라고 하는 것들이 만들어지게 됩니다.
앱솔루트는 릴리트 해브 하고 조금 다릅니다.
릴레이티버는 내가 원래 있어야 할 자리에서 이제 얼마만큼 이동을 하는 거라면 그래서 릴레이티브죠 상대적인 앱솔루트는 절대적인 어떤 기준으로 위치가 변한다는 것을 알 수 있게 됩니다.
그래서 좌상단을 기준으로 해서 css는 오른쪽으로 갈수록 숫자가 커지고 밑으로 갈수록 숫자가 커지는 이러한 좌표계를 사용하고 있습니다.
좋습니다. 그리고 fid라고 하는 부분들은 우리가 최초에는 이 앱솔루트랑 릴레이티브라고 하는 것들만 만들어졌었죠.
근데 이제 fixt가 나오게 된 배경은 어느 순간 우리가 모달창 같은 것들을 많이 만들어낸다고 모달창과 같은 어떤 ui들이 굉장히 많이 쓰이게 됐어요.
그런 경우에는 내가 스크롤을 하더라도 특정 화면을 기준으로 해서 뭔가 팝업을 띄워야 되는데 앱솔루트로 하게 되면 항상 이 스크롤을 다 기억을 해서 이제 띄워야 되는 어떤 불편함이 생겼던 겁니다.
그래서 sixt라고 불리는 것들은 내가 스크롤과 커서와 상관없이 현재 화면을 기준으로 내가 어디에 있던 어떤 화면을 기준으로 띄우게 만들었던 거고 이런 부분들은 토스트 팝업이라든지
모달 팝업이라든지 현대 ui에 해서 굉장히 많이 유용하게 쓰이는 부분이기 때문에 이 포지션 fixt라고 하는 개념이 나왔고요 그런 맥락에서 작업을 할 수 있게 됩니다.
그리고 마지막으로 스티키라고 하는 부분들은 이거는 이제 ios 모바일 앱이 나오고 ios에서
이러한 레이아웃을 처음. 선보였는데요.
주소록에 들어가면서 책 카피로 기억이나 니은 등의 어떤 책 카피를 만들려고 했을 때 현재의 위치를 기준으로 해서 넘어가는 어떤 기능들이 만들어졌었고 이것들 ui를 이 ui에서 영감을 받아서 웹에서도 이런 걸 할 수 있도록 그래서 현재 위치에 고정을 하고 있으나 내가 지나가게 되면 그 위치를 대신해서 콘텐츠가 바뀌는 형태 그래서 이 콘텐츠가 어디에 붙어 있다라는 느낌을 만들어서 이제 스트리키라고 하는 것들이 가장 최근에 생긴 기능입니다.
그래서 여러분들이 오버레이를 다 이러한 특성들을 잘 조립을 해서 내가 원하는 것들을 만들려고 하는 거라고 생각을 하시면 될 것 같고요 일단 앞서 얘기하려고 했었던 이제 콘스트렌트에 대해서 얘기를 할 건데 포지션의 어떤 특히 앱솔루에 대한 개념에 대해서 좌표계에 대한 어떤 이야기를 조금 더 드릴까 합니다.
나머지는 잡히기가 쉽습니다. 릴레이티브는 내가 원래 있어야 할 자리에서 상대적으로 얼마큼 이동한다라고 했죠.
그래서 원점이 항상 내가 그려지고자 하는 그 박스를 기준으로 원점이 잡히게 됩니다.
그리고 이 원점의 박스 중에서도 이제 좌 상단의 어떤 기준을 통해서 탑 라이트를 계산을 하게 되죠.
앱솔루트의 경우는 fixt 같은 경우에는 화면을 기준으로 한다고 했습니다.
그래서 화면을 기준으로 절대적인 어떤 값의 자표로서 값이 만들어지게 되는 거고요 스티키의 경우는 릴레이트와 동일합니다.
내가 원래 있어야 할 자리를 기준으로 해서 만들어지는 거고 내가 고정해야 되는 그 위치를 잡아주는 개념이기 때문에
스티키를 잡는다고 해서 해당하는 엘리먼트의 크기가 변하거나 하진 않습니다.
이건 스크롤과 연관이 되어 있는 부분이 거고요 문제는 솔트 있는데요.
앱솔루트가 항상 절대적인 어떤 위치로 만들게 된다면 콘텐츠를 그룹화시켰을 때 내가 얼마만큼 얼마만큼 이동을 한다고 했을 때 이 콘텐츠에 따라서 위치가 다 달라진다면 굉장히 불편할 수 있습니다.
그렇죠 나는 이거를 하나의 어떤 그룹으로 생각을 하고 있는데
솔루트한 위치의 어떤 크기를 만들려고 하면 원점의 좌표 기준이 해당하는 특정 엘리먼트의 기준으로 되는 게 나을 겁니다.
이걸 통해서 우리는 이제 어떤 앱솔루트의 원점 좌표계를 잡아줄 수 있는 방법을 제공하려고 하는데요.
그래서 css에서는 어떠한 포지션이든 간에 static이 아닌 가장 가까운 엘리먼트를 원점 자표로 한다라고 하고 있습니다.
그래서 우리는 일반적으로 어떤 엘리먼트를 만들거나 만들었을 때 이게 하나의 컴포넌트가 돼야 된다 그리고 수트를 사용해야 된다라고 하면 우리가 특정한 콘텐츠의 releative라고 하는 속성을 부여해줌으로써 위치는 변화시키지 않고 현재 위치를 그대로 가져갈 수 있도록 만들어주는 어떤 기능을 제공을 하고 있어요.
이 방식을 통해서 asolt의 어떤 특정 위치와 좌표를 잡아줄 수 있는 방법까지 우리가 공부를 했습니다.
조금만 더 나아가서 이제 퍼센테이지 잡혀에 대한 어떤 부분에 대해서 설명을 좀 할게요 퍼센테이지에 대한 나중에 귀찮아 100%라고 했을 경우에 이 100 프로
나중에 인터넷 뒤져가지고 연결하자 아무튼 100%를 이용해가지고 우리는 끝에도 붙일 수 있고 저 일지에도 붙일 수 있고 가운데도 붙일 수 있게 됩니다.
그리고 트랜스폼이라고 하는 것들을 만들 건데요.
그래서 실습 과제 실습 과제는 뭐냐면 이렇게 네모난 박스가 있습니다.
그리고 네모난 박스 안에 꽃에 또 다른 네모난 어떤 박스가 존재하고 있어요.
이 박스의 위치를 다음과 같은 샘플 위치에 한 번씩 만들어보는 것들이 이번 실습 과제입니다.
첫 번째는 쉽죠. 첫 번째는 이제 이 박스와 박스 사이에서 이 정도의 어떤 크기를 띄워놓는 방법입니다.
오른쪽에도 띄워야 되고 왼쪽이나 하단에도 한 번 다 위치 해 보십시오
그런 다음에 이제 내가 어떤 콘텐츠와 상관없이 내가 이제 윗면에 붙여보는 방식이나 혹은 윗면에 붙여보는 방식 위편에서 이만큼만 떨어져 있는 코드 혹은 전체적에서 전체 윗변에서 가운데로 비친다든가 하는 코드 오른쪽에 나타나는 코드 이 모든 거에 대해서 내가 어
떤 식으로 코딩을 작성하면 이렇게 만들 수 있다.
라고 것을 연습하는 것이 연습하고 나시면 오버레이를 다루는 데 굉장히 쉬워지게 됩니다.
Overview
이번에 학습할 내용만 바로 Position입니다.
우리가 지난 시간에 엘리먼트 박스들을 배치를 하면서 표면적으로 우리가 자동으로 원하는 곳을 대체하는 것들을 배워봤어요.
하지만 콘텐츠가 이렇게 겹쳐 있는 것들을 구현을 하기 위해서는 우리가 지정되어 있는
위치에 자동으로 놓는 것이 아니라 콘텐츠들을 겹쳐서 놓을 수 있게 겹쳐서 놓아야 되는 어떠한 상황들이 생깁니다.
현재 주어진 어떤 위치에서 내가 특정한 곳으로 위치를 이동하려고 자주 쓰는데요.
이러한 어떤 상황에서 우리가 사용하는 것이 바로 position입니다.
Values
staic, relative, absolute, fixed, sticky
/* Keyword values */
position: static;
position: relative;
position: absolute;
position: fixed;
position: sticky;
포지션에는 staic, relative, absolute, fixed, sticky 5가지의 종류들이 있습니다.
이 5가지의 포지션 속성을 통해서 우리가 어떤 특정한 콘텐츠의 위치를 변경해야 될 때 어떻게 할 수 있는지 한번 생각을 해보겠습니다.
우선 간단하게 첫 번째로
스테틱은 사실 아무런 의미가 없습니다.
스테틱은 그 이름 그대로 그냥 고정한다는 뜻이겠죠.
포지션 스테틱은 기본적인 속성이며 원래 있어야 할 자리에 있는 속성입니다.
그래서 position 위치에 아무런 변화를 주지 않아요.
정확히는 static은 position의 값이 없는 것입니다.
position relative를 하게 되면 이제 이 eliment는 상대적인 위치를 가지게 됩니다.
내가 원래 있어야 할 자리에서 osition top left 혹은 right bottom을 이용해서
현재 있어야 할 자리에서 그만만큼의 이동을 할 수 있다는 의미가 됩니다.
top, right, bottom, left
어떤 방향에서 얼마만큼 위치를 이동해야하는지 알려주는 속성입니다.
그래서 한번 예시를 보시죠 지금처럼 만들어져 있는 어떤 형태의 코디션을 이용해서 탑 값이나 레프트 혹은 라이트 바탕 값을 수정 한번 해보세요.
4방향으로 내가 원하는 형태의
데이터를 변경할 수 있게 됩니다. 위치의 값은 음수도 가능합니다.
그래서 지금처럼 보여질 수도 있습니다.
top, right, bottom, left 값들의 우선순위
auto의 값이 있다면 우선순위가 더 낮다. top과 bottom 중에서는 top이 우선순위가 더 높습니다. left, right 중에서는 direction (en-US)이 ltr(영어, 한국어 등)이면 left를 우선 적용하고, direction (en-US)이 rtl(페르시아어, 아랍어, 히브리어 등)이면 right를 우선 적용합니다. 이걸 잘 모르면 왜 값을 적용했는데 반영이 안되지 하는 경우가 발생한다.
margin vs relative
마진을 이용해서 값을 이동하는 거와 릴레이티브의 값을 이동하는 거에 대해서는 좀 차이가 있습니다.
마진은 내가 현재적인 어떤 nommol flowr 안에서 콘텐츠를 이동했기 때문에 그 이동한 위치를 그대로 대변해서 그다음에 어떤 위치가 결정이 되지만
position relative는 이미 만들어진 내 위치에서 상대적으로 얼마만큼 뛰어 있다라고 하시기 때문에 내가 만들어놨던 지금 현재가 위치하고 있는 위치가 다른 어떤 노문 플러우구나 로 flow에 영향을 주지 않는다는 것을 주의해 주시면 좋을 것 같습니다.
position을 써야하는 상황이라면 일반적으로 가장 더 많이 쓰이는 속성은 assolute죠 aslt는
절대적인 위치에 놓고 싶은 거예요. 그래서 한번 앱솔루트를 이용해서 콘텐츠를 이동을 한다면 화면을 기준으로 특정 위치에서 이동을 한다는 것을 확인할 수 있습니다.
그래서 값이나 라이트 혹은 바텀 값을 이동을 하게 되면 그의 적절한 형태의 엘리먼트 위치로 이동한다는 것을 알 수가 있겠습니다.
스크롤과 함께 한다면 어떻게 될까?
다음과 같은 예시를 한번 볼게요 내가 콘텐츠가 굉장히 많은 상태에서 솔로 한 값을 줬다면 내가 스크을 했을 때 이 스크롤에 콘텐츠에 반응하지
콘텐츠에 따라 같이 스크롤 된다는 것을 확인할 수 있습니다.
예약 솔루트라고 하는 것은 콘텐츠가 특정한 좌표를 중심으로 절대적인 위치로 이동을 했기 때문에 내가 스크롤을 하게 되더라도 해당하는 엘리먼트가 전체적으로 스크롤이 되었기 때문에 그 위치에 존재하게 되는 것이죠.
모달 팝업과 같은 UI의 경우 스크롤과 관계없이 항상 특정 위치에 배치를 하고 싶을 수도 있습니다. 이런 경우에는 이제 scrol을 하더라도 항상
화면 전체 화면을 기준으로 특정 위치에 위치한다는 것을 알 수 있습니다.
이런 것들을 하기 위해서는 모o덜 평을 띄운다던가 어떤 특정 위치에 고정이 돼야 되는 경우에는 픽스드를 사용할 수가 있겠죠.
스크롤과 관련해서 하나 하나가 한 가지 더 값이 있습니다.
아무튼 스티키라는 것을 넣어주고 톱에다 값을 넣어주는 거죠.
그러면 처음에는 아무런 위치가 변하지 않지만 스크롤이 되어서 그 콘텐츠가 화면에 넘어가려고 할 때 해당하는 위치에 걸린다는 걸 알게 됩니다.
stack라는 옵션은 모바일 브라우저가 생기면서 이런 식으로 애플에서의 디자인에서
이런 식으로 특정한 영역이 지나갔을 경우에 걸리는 어떤 디자인들이 유행을 하게 됨에 따라 css의 표준으로 보게 되었습니다.
그래서 내가 콘텐츠가 스크롤에 따라서 특정한 위치에 고정을 해야 할 때 스틱이라는 어떤 옵션을 사용하면 굉장히 유용하게 사용할 수가 있게 됩니다.
참고예시
https://css-tricks.com/position-sticky-2/
조금 더 고급으로 들어가 보겠습니다 가장 많이 사용하는 거는 position asolot입니다.
이렇게 slot를 만들었을 경우에는 특정 위치를 기준으로 절대적인 어떤 값에 이동을 한다고 했습니다.
그렇다면 이 기준은 어떻게 측정이 될까요.
퀵스는 항상 전체 화면의 화면을 기준으로 특정 위치에 잡아놨어요.
하지만 엑소루트는 내가 원하는 형태의 기준점을 잡아줄 수 있게 됩니다.
그 기준점이라고 하는 것들은 포지션이
스테틱이 스테틱이 아닌 어떤 형태의 프리션을 잡아준다면 그 콘텐츠는 cntainning block이 되어 절대적인 원점의 사표가 되어 줍니다.
그래서 afsoult의 어떤 이벤트가 있을 경우에 내가 특정 위치에 사표를 만들어주고 싶다.
라고 하면 가장 가까운 규모의 position 속성을 찾아서 그 position이 더 이상 static이 아닐 때 그 엘리먼트를 기준으로
절대 위치를 만들게 됩니다. 왜 이렇게 만들었을까요.
우리가 절대 위치로 만들어졌을 경우에 특정한 어떤 영역을 우리가 반복해서 사용할 수 있다거나 해야 되는 경우가 생깁니다.
이렇게 독립적인 어떤 콘텐츠를 만들기 위해서는 항상 화면의 기준으로 만들게 된다면 내가 두 개나 세 번째 만들었을 경우에
x 탑과 레프트의 값을 계산해서 만들어내야 되겠죠.
하지만 이렇게 적당히 하나 하나의 그룹으로 만들 수 있도록 세팅을 해주면 어쨌든 부모의 가장 가까운 부모의 어떤 사용이 되는 어떤 기준점 그룹의 기준점으로부터 절대적인 좌표를 만들 수 있기 때문에 이렇게 만들어낸 것입니다.
그래서 일반적으로는 콘텐츠를 대부분
릴레이티브라고 하는 어떤 속성들을 가둬서 릴레이티브를 속성을 하게 되면 컨테이너 블로그는 만들어졌지만 현재 위치를 그대로 가지 고수하기 때문에 relative라는 것을 감싸줌으로써 하나의 어떤 컴포넌트 가장 외부에는 이렇게 relati aslot와 같은 그러한 position을 지정을 해주고 내부적으로 콘텐츠를 배치할 수 있다라는 것을 잘 알고 계시면 좋을 것 같습니다.
.layer {
position:absolute;
top:0;
right:0;
bottom:0;
left:0;
}
.layer {position:absolute;inset:0}
조금 더 디파이브를 해보겠습니다. 세 번째 시간 이 앱솔루트와 릴렉티브를 잘 이용하면 이제 콘텐츠를 우리 마음대로 대체할 수 있게 됩니다.
asolut를 하게 되면 콘텐츠의 크기는 wide와 hight는 ot 속성이 되고 asolut일 경우에는 콘텐츠의 콘텐츠의 크기를 따라가게 됩니다.
그래서
우리가 잘 만들어놨던 콘텐츠들이 엑솔로터가 되는 순간 위치가 깨지는 경우가 생기곤 합니다.
그렇다고 wid를 100%를 주게 되면 여기에 마진in이나 오더 패딩을 줬을 경우에 좀 문제가 생기는 경우가 있었어요.
물론 지금은 이 앞에서 배웠던
보더 박스나 콘텐트 박스를 이용 박스 사이즈 보더 박스를 이용하게 되면 이러한 문제는 발생하지 않으나 일반적으로 위드와 하이트를 100%를 주는 것은 여러 가지 오류를 발생할 수 있기 때문에
position과 lefte와 lighte를 0으로 top과 battom을 0으로 주는 형태의 방식을 많이 사용하곤 합니다.
그래서 우리가 어떠한 콘텐츠가 상단에 쭉 덮여 있는 형태를 만들고 싶을 때는 탑 라이트 닥터 레프트를 전부 0으로 세팅을 하게 되면 우리는 이 덮는 형태의 디자인을 만들 수가 있고 이러한 방식은 굉장히 자주 사용하게 됩니다.
그래서 최근에는 인셋이라고 불리는 프로포티가 생겨났고요 이 프로포티는 사용할 수도 있는 프로저가 있지만 아직까지 모든 브라우저를 사용할 수 있지 않기 때문에 알고만 계시다가 나중에 inset 0으로 굉장히 심플하게 적을 수 있겠으나 어쨌든 top light boto bto left가 0이라는 사실이 0을 지워준다면 전체를 덮을 수 있는 형태를 쉽게 만들어낼 수 있다.
그래서 화이트와 위드에 대해서 헷갈리지 않으셨으면 좋겠습니다.
그래서
부모가 릴레이티브 형태이고 aslt가 aslt의 모든 포지ition이 빵인 0인 이 경우는 굉장히 빈번하게 사용함으로 머릿속에 기억해 주시면 좋을 것 같아요.
조금만 더 응용을 해보겠습니다. 여기에서 이러한 과정에서 어떠한 특정의 값을 ot로 준다면 어떻게 될까요.
btom을 ot를 주게 되면 콘텐츠 크기에 따라가면서 위에 붙어 있는 어떤 액제의 형태를 만들 수 있습니다.
반대로 left가 left가 ot라면
오른쪽으로 붙어 있는 형태를 만들 수가 있게 되고요 라이트가 오토라면 왼쪽에 붙어 있는 이런 식으로 콘텐츠를 만들어낼 수 있습니다.
코너에도 모일 수가 있고요 이러한 방식들을 조합을 하면 내가 원하는 콘텐츠를 만들어 낼 수가 있습니다.
그래서 absolo dro content를 배치할 때는 이러한 방식으로
윗변이나 혹은 코너 혹은 가운데 여러 가지로 배치할 수 있는 것들을 익혀두시고 적절하게 margin을 이용해서 간격을 정도 띄우는 이런 식으로 디자인을 하시게 되면 조금 더 쉽게 원하는 어떤 형태의 레이아웃을 할 수 있게 됩니다.
다섯 번째
tresform translate 그리고 퍼센트 값에 대한 이야기입니다.
값을 이동할 수 있는 것들은 릴레이티브 포지션과 탑을 이용하는 방식 그리고 mg를 이용하는 방식 그리고 트랜스 라이트를 이용하는 방식이 있습니다.
세 가지는 우리가 어떠한 콘텐츠를 우리가 원하는 어떤 위치에다가 놓을 수 있는 방법을 제시를 합니다.
하지만 각각의 성질이 다 다르기 때문에 각각의 차이를 일단 기억해 주시는 게
좋습니다. 우리가 일반적으로 magin을 이용한다라고 하면 magin은 콘텐츠가 당연히 응당 그만큼 떨어져 있어야 된다는 것이고 이 margin은 이 콘텐츠의 주위에 영향을 미치는 a입니다.
그렇기 때문에 일반적으로 마진을 자동적으로 콘텐츠를 간격을 만들어주기 위해서 배치를 하는 것이 아니라면 내가 보기 좋게 띄우기 위해서 만든 것이 아니라면 마진을 사용하지 않는 게 좋습니다.
아까 만들었던 포지션이나 일반적으로 탑 라이트를 사용하는 것이 일반적인
상식입니다.
또한 하지만 이런 방식은 가운데로 정렬하기가 굉장히 힘이 들어요.
내가 탑을 50%로 만들었다면 50%부터 왼쪽으로부터 시작하기 때문에 혹은 라이트를 50% 만들었다면 50%만큼의 콘텐츠를 만들었기 때문에 내가 가운데를 유치하기 위해서는 이 콘텐츠의 절반만큼을 다시 옮겨야만 실제로 우리가 원하는 가운데 정렬이라는 것이 가능해집니다.
이걸 하기 위해서는 마진을 이용해서 콘텐츠의 50%를 정확하게 계산을 해서 만들어야 되죠 하지만 이 콘텐츠가 가변의 크기라면 어떻게 될까요.
마진은 마진 50%로 한다면 괜찮을까요.
그렇지 않죠. 마진의 퍼센테이지는 규모의 크기의 부모의 위드에 비례를 합니다.
이거는 마진 탑 레프트 라이트 모드가 동일해요.
사실 이거는 상당히 헷갈리게 만들어내는 개념 중의 하나입니다.
어찌 됐든 이러한 방식으로 만들게 되면 절대적인 크기는 가능하겠지만 상대적인 어떤 크기를 가지고 있거나 가변적인 크기에는 대응을 할 수가 없습니다.
그래서 만들어진 것이 트랜슬레이트를 이용하는 방식입니다.
트랜스폼의 트랜슬레이트는 실제로 그려진 결과물에 매트릭스를 적용을 하여
데이터를 조금 더 다르게 그려내는 방식입니다.
자세한 내용은 트랜스폼에 관련된 이 후반부 내용을 참고해 주시고 지금은 단순히 이 보여주는 화면의 크기를 변환하는 거라고 생각하시면 될 것 같아요.
그래서 우리는 x나 y 혹은 x y로 전단을 하게 될 수가 있고요 동일하게
현재 위치를 기준으로 이동하게 만들어내는 릴레이트와 굉장히 유사하다고 보시면 될 것 같습니다.
다만 릴레이티브하고 다르게 여기서 적용하는 퍼센테이지는 현재 나의 콘텐츠의 크기에 비례하게 됩니다.
이래서 이를 통해서 우리는 apsolot와 left 50%와 frenslatex 50%를 결합해서 우리는 가운데 종료를 할 수 있게 됩니다.
이런 것들을 이용해서 다음에 레이아웃을 연습을 한번 해보세요.
전체를 전체를 채우는 것 양 사이드를 채우는 것 혹은 양 사이드를 반대편으로 채우는 방법 가운데로 정렬하는 방법 이런 부분들이 익숙해지고 나면 이제 콘텐츠와 콘텐츠를 겹쳐서 대체하는 것에 대한 이해도가 굉장히 높아질 겁니다.
오디션 마지막 이야기 지금까지 x와 y 2 그리고 엘리벤트는 서로 겹쳐서 돕는 법에 대해서 이해를 했다면 마지막으로 이렇게 겹쳐서 콘텐츠를 만들어냈을 때 어떤 것이 위로 올라올 것이고 어떤 것이 아래로 오는지에 대한 규칙입니다.
이 스텝 규칙은 제트 인덱스라고 불리는 방식과 방식을 사용하게 됩니다.
그래서 제트 인덱스라는 어떤 값을 추가하면
숫자가 높을수록 나중에 쌓여지기 때문에 더 높이 올라가게 되고 콘텐츠는 더 상단에 보여지게 됩니다.
다만 제트 인덱스는 절대적으로 수치상으로 콘텐츠를 교체하는 것이 아니라 부모의 콘텐츠가 부모의 제트 윈덱스가 훨씬 더 높은 우선순위를 지닙니다.
부모의 zet index가 3이라면 내가 아무리 높은 zet index index를 가지고 있다.
하더라도 이미 그것보다 낮은 상태에서 만들어지는 것이죠.
무슨 말이냐면
내가 경쟁하는 상대에는 이 틀 안에서만 경쟁을 한다라고 보시면 될 것 같습니다.
앞에서 만들었던 우리가 컨테이닝 블록이라고 불리는 그 안에서 ztindex를 통해서 상대 경쟁을 하는 것이기 때문에 어떤 수치에 따라서 절대적으로 만들어내는 것이 아니라 콘텐츠에 따라서 상대 경쟁을 하는 것이다.
그래서 제트 index가 올라오지 못할 경우에는 콘텐츠를 구조적으로 밖으로 뺀다든가 조정을 하는 부분이 필요하다는 것을 기억하시면 될 것 같습니다.
일반적으로는 zet index를 단순히 숫자로 집어넣는 것은 나중에 이 오더링을 방해하기 때문에 css balave를 통해서 zet inde스들은 스펙을 쌓아두고 적정히 100이나 100 단위 혹은 500 천 단위 정도로 만들어 두고 작업을 하는 것이 일반적이며
일반적이며 이렇게 했을 경우에 훨씬 더 jpt index가 관리하기 수월해집니다.
여기까지 콘텐츠를 겹쳐서 배치하는 방법 xxxy 평면 그리고 제2 축에 z 2 그리고 컨테이닝 블록까지 이러한 개념들을 이해를 하시고 필요할 때 적절히 사용한다면
정말 훨씬 더 각별하게 만들 수 있을 것 같습니다.
overflow:scroll이나 overflow:hidden이 있다면 dropdown과 같은 overlay를 구현할 수가 없다. 현재는 css만으로는 해당 구현을 할 수가 없으므로 자바스크립트의 도움이 필요하다.
오늘 해야 기억해야 할 문구 콘텐츠를 겹쳐서 배치하고 싶다면 포지션을 고려하십시오
홈페이지를 만들다보면 컨텐츠가 없을때는 하단에 푸터를 유지하고
A Clever Sticky Footer Technique
https://css-tricks.com/a-clever-sticky-footer-technique/
html, body { height: 100%;}
body > footer {
position: sticky;
top: 100vh;
}
#CSS/2장입문
#CSS/2장입문/2.4.Layout
컨텐츠를 숨기는 방법
display: none;
opacity: 0;
visiblity: hidden;
#CSS/2장입문
#CSS/2장입문/2.5.Visibility
호랑이 담배피던 시절의 웹 개발 퍼플리싱은 그냥 이미지만 전달을 받거나 일부 가이드를 정도 그려준 이미지를 통해서 CSS를 한땀한땀 다 만들어야 했습니다. 반면 디자이너가 힘이 없는 회사는 가이드 수준을 엄청 요구해서 디자이너들이 죽어나던 시절도 있었죠.
퍼블리싱이 쉬운 일이 아닌데 시간은 상당히 많이 들어가는 일인데 반해 진입장벽은 낮아서 대체가능한 인력이 많다보니 비싼 일도 아니었습니다. 그렇지만 디자이너는 가이드를 만드느라 수정된 부분을 찾아내느라 전체가 다 바뀌면 일일히 이미지 다 교체하느라 잔일에 시간을 정말 많이 잡아먹던 일이었습니다.
이러한 요구사항에 힘입어 스케치, 제플린, figma와 같은 UI 디자인 전용툴과 디자인 HandOff 툴이 발전하면서 이러한 불편함을 해소하면서 퍼블리싱의 생산성은 더 높아졌습니다.
그리고 이러한 도구들의 발전으로 인해서 더 쉬워지는 것을 넘어, '디자인을 자동으로 HTML+CSS코드로 뽑아줄 수 없나?' 하는 생각으로 Figma to Code와 같은 자동 코드 생성도구
들이 만들어지고 연구되기 시작했습니다.
Figma가 UI 디자인 프로그램의 1등이 된 이유는 웹기반의 동시 편집가능이라는 협업을 중시하는 말도 안되는 차별화 기능도 있지만 본질적으로 UI 디자인 툴이 갖춰야할 잘 만들어진 디자인 개념에 입각한 속성과 기능이라는 측면에서도 figma는 너무나 월등합니다.
figma는 협업을 강조하기에 디자인을 개발로 옮기는 과정 또한 협업의 workflow로 인식하고 있으며, 단순히 절대적인 디자인을 그리는 것이 아니라 반응형으로 디자인을 할 수 있도록 AutoLayout
, Fixed/Hug/Fill Size
, Min-Max Size
, Constranints
, Layout Grid
등 상당히 "Design in dev-friendly systems" 한 디자인 개념을 제공합니다.
무엇보다 이러한 Figma의 디자인 개념과 제공하는 인터페이스들은 CSS의 속성보다 훨씬 더 직관적이며 적은 속성으로도 실무에 필요한 대부분의 디자인을 만들어내는데 손색이 없을 정도입니다.
학습곡선을 늘리고 싶지는 않았지만 더 편리한 기능을 제공하기 위해서는 새로운 기능을 만들어야하고 이러한 기능의 제공은 다시 학습곡선을 높이는 딜레마를 가져오게 만듭니다.
맨땅에서 CSS를 해야하는 경우도 있겠지만, 우리는 대부분 디자이너가 만들어주는 결과물을 HTML과 CSS로 마크업을 하는 작업을 하게 됩니다. 그리고 대부분의 경우 그 결과물은 이제 figma일거라고 생각합니다.
figma가 가지고 있는 디자인의 개념은 훨씬 더 간단하지만 더 직관적기이에 figma가 제공해주는 기능을 그대로 제공을 한다면 훨씬 1)더 적은양의 코드와 2)직관적인 표기 그리고 3)강력한 기능을 제공해 줄거라고 생각했습니다.
Figma의 디자인 개념들을 CSS로 만들어보고 다시 TailwindCSS와 AdorableCSS로 만들어가는 모습을 보면서 어떤식으로 더 간결하고 직관적으로 작성할 수 있는지 알아보고자 합니다.
CSS와 관련된 Figma의 주요 디자인 개념들
- AutoLayout
- Fixed/Fill/Hug Size, Min-Max Size
- Position & Constraints
- Text Align
- Text Truncate
전통적인 디자인 이미지와 마크업 개발을 통해서 만들어진 결과물의 결정적인 차이는 반응형 디자인에 있습니다. 인쇄로부터 출발한 디자인은 절대크기와 절대좌표를 기반으로 디자인을 만들면 되지만 웹이나 앱에서 사용되는 디자인은 디스플레이의 크기가 포함하는 컨텐츠가 변화할 수 있기 때문에 같은 디자인을 표시하더라도 디스플레이의 크기나 컨텐츠의 양에 맞게 적절히 위치와 크기가 가변적으로 조정 되어야 합니다. 가령 크기가 고정된 상태로 글의 내용이 많아진다면 그 글이 프레임밖으로 삐져나와 잘려보이거나 다른 영역을 침범할테니까요.
이렇게 겹치지 않게 적절히 자동으로 컨텐츠를 배치할 수 있는 Layout을 만들기 위해서 여러가지 디자인 개념들이 고안되었는데 CSS에서서는 Flexbox가 가장 대표적인 이러한 Layout의 개념이라고 할 수 있습니다. 이러한 개념은 ios의 Stack이나 andorid의 LinearLayout, Compose의 Row와 Column등으로도 많이 제공이 되고 있습니다.
Figma 역시 이러한 컨텐츠를 가변적으로 배치를 도와줄 수 있는 디자인 개념을 Auto Layout 이라는 이름으로 제공을 하고 있습니다. 우리는 Figma의 Auto Layout 개념을 이해하고 CSS의 Flexbox로 변환을 해보려고 합니다.
Figma의 디자인 개념을 알고 있으면 좋은 이유!
Figma를 기반으로 디자인을 이해하면 좋은 것은 Figma가 웹뿐만 아니라 앱과 다른 디자인도 고려하면서도 정말 최소한의 UI와 개념으로 반응형 디자인을 할 수 있도록 정말 많은 생각을 해서 만들어놓은 결과물이라는 점입니다.
때문에 CSS의 어려운 점 중에 하나인 '같은 화면을 만들기 위해서 너무 많은 방법이 존재한다.'라는 점에서 Figma가 제시하는 개념으로만 CSS를 사용해도 대부분의 디자인 결과물을 만들 수 있기에 Best Practice로 삼을 수 있다는 점에서 매우 유용합니다. 또한 이러한 개념이 웹에만 한정되는 것이 아니라 앱이나 다른 디자인에 대한 개념까지 확장할 수 있다는 점에서도 좋습니다.
우선 AutoLayout을 구성하는 UI Panel을 살펴보면서 어떤 개념으로 구성이 되어있는지 알아봅시다.
Figma Auto Layout 공식문서
https://help.figma.com/hc/en-us/articles/360040451373-Explore-auto-layout-properties#Layout_flow
Figma의 AutoLayout은 Flow
, Alginment
, Spacing
, Resize
라고 하는 큰 줄기의 개념으로 기본은 다음과 같은 4가지로 구성이 되었습니다.
Vertical Layout
Horizontal Layout
Wrap
Algin(Top/Middle/Bottom + Left/Center/Right)
gap: 8px
gap: Auto
padding-left
padding-top
padding-right
padding-bottom
이미지를 통해서 각 역할에 따라 어떻게 컨텐츠가 배치가 되는지 한번 이해해보세요. 실제로 Figma를 이용해서 수치를 건들여보면서 해보는 걸 추천드립니다. 눈으로 어떤 속성으로 인해 어떻게 컨텐츠가 배치가 되는지 이해한다면 훨씬 더 큰 도움이 됩니다.
Figma의 AutoLayout은 CSS의 Flexbox로 구현할 수가 있습니다. Figma의 AutoLayout은 CSS와 다음과 같이 매칭하여 적용할 수 있습니다.
.AutoLayout {
/* 1. Use AutoLayout */
display:flex;
/* 2. Flow */
flex-flow:row; /* or column, wrap */
/* 3. Alginment */
align-items: flex-start; /* or center, baseline, flex-end */
justify-content: flex-start; /* or center, flex-end */
/* 4. Gap */
gap:8px;
/* or */ justify-content: space-between; /* gap: Auto */
/* 5. Padding */
padding: 10px 20px 30px 40px; /* top right bottom left */
}
1) flex-row|flex-col|flex-wrap
-> hbox|vbox|wrap
저는 행
과 열
이라는 row
와 column
보다는 가로
와 세로
라는 horinontal
과 vertical
이라는 용어가 훨씬 더 시각적이고 직관적이라고 생각했습니다. 따라서 방향성의 앞글자인 h
와 v
와 함께 flexbox
의 명칭을 합해서 hbox
, vbox
라고 명명을 하였습니다.
<div class="hbox"></div>
<div class="vbox"></div>
<div class="wrap"></div>
2) align-*|justify-*
-> top|middle|bottom
+ left|center|right
Figma에 있는 9개의 방향성 개념을 그대로 제공하고 싶었습니다. 그래서 다음과 같이 방향성을 표기하면 각 레이아웃 방식에 맞게 적절히 align과 justify를 만들어주고자 하였습니다.
<div class="hbox(top+left)"></div>
<div class="vbox(bottom+center)"></div>
<div class="wrap(middle+right)"></div>
3) justify-between
-> gap(auto)
또한 Figma에서 표현하는 gap(auto)
를 space-between
이 될 수 있도록 하여 gap을 통해서만 표현을 할 수 있도록 하였습니다.
또한 figma의 gap:Auto
의 경우 컨텐츠가 하나밖에 없다면 가운데 정렬을 하도록 되어 있습니다. 이러한 부분 역시 스펙으로 반영하여 gap(auto)를 justify-between보다 더 적은 코드더 더 직관적으로 사용할 수 있도록 하였습니다.
.gap\(auto\) { justify-content:space-between; align-content:space-between; }
.gap\(auto\)>:only-child { margin:auto; }
4) AutoLayout와 AdorableCSS
그리하여 AutoLayout을 사용하는 Frame의 경우, 다음과 같이 TaliwindCSS에 비해 간결하고 더 직관적인 형태의 코드를 제공할 수 있게 되었습니다.
<!-- TailwindCSS -->
<div class="flex flex-row align-start justify-center gap-[10px] pt-[10px] pr-[20px] pb-[20px] pl-[20px]"></div>
<!-- AdoarbleCSS -->
<div class="hbox(top+center) gap(10) p(10/20/30/40)"></div>
반응형 디자인에서는 절대좌표과 절대크기 대신 컨텐츠나 컨테이너에 맞게 자동으로 크기와 위치가 조절이 되는 것이 핵심이라고 했습니다. 그렇기에 크기를 지정하는 width와 height의 값이 특정한 값 뿐만 아니라 적절한 값이 될 수 있도록 하는 것이 필요합니다.
width와 height의 경우 figma는 다음과 같이 3가지로 구분합니다.
Fixed width
: 수치를 입력하면 입력한 크기를 가집니다.
Hug contents
: 글자나 이미지등 내부에 속한 컨텐츠의 크기를 따라갑니다.
Fill container
: 부모의 크기를 따라갑니다.
Fixed width는 간단합니다. width: 320px
와 같이 그냥 width에 값을 넣어주면 됩니다.
한 가지 특수한 상황이 있다면 display: flex; flex-flow: row;
인 컨테이너의 컨텐츠들은 width: 320px
과 같이 특정한 값을 지정하더라고 flexbox의 기본특성인 컨테이너가 스스로 크기를 조절한다는 성격과 flex-shirink
의 기본값이 1
로 설정되어 자리가 부족하면 스스로 크기를 줄이도록 되어 있습니다.
따라서 간혹 내가 특정한 지정한 크기를 지정했음에도 해당 크기보다 작게 출력이 되는 경우가 있습니다. flexbox에서는 정확한 크기를 지정하기 위해서 flex-basis
라고 하는 속성을 고려해볼 수 있습니다. 그렇지만 이 속성은 width
가 아니라 flexbox의 메인축
이기에 flex-basis가 경우에따라 width에도 height에도 적용이 될 수 있습니다. 따라서 이 경우에는 flex-basis를 쓰기보다는 flex-shirink:0
을 이용해서 지정된 width의 크기가 가변이 되지 않도록 해야 Figma 디자인 개념과 동일하게 설정을 할 수 있습니다.
.fixed-width-320px {
flex-shirink:0;
width:320px;
}
CSS에서 width의 기본값은 width: auto
입니다. CSS에서 width: auto
는 상황에 따라서 각기 다른 성격을 가집니다.
width:auto의 상황별 변화
1. Normal Flow에서의block
엘리먼트의width: auto
는 부모 블록의 크기를 따라가며 패딩과 보더를 제외한 나머지 영역을 가득 채우는 것으로 합니다.
2. Flexbox 내에서width: auto
의 경우에는 기본적으로 컨텐츠를 크기를 따라가도록 되어 있습니다.
3. 단, Flexbox의 컨테이너의 속성이flex-flow:column; align-items: stretch
등으로stretch
라면 컨테이너 크기를 따라갑니다.
4.position:absolute
혹은inline
이라면 컨텐츠를 따라가도록 되어 있습니다.
Figma의 경우 Hug는 AutoLayout에서만 발생하고 Figma의 AutoLayout은 stretch 라고 하는 개념이 없으므로 width: auto
속성만으로도 충분히 Hug
를 표현할 수 있기 때문에 특별히 다른 조치를 하지 않아도 됩니다.
다만 강제로 width: hug
속성을 지정해야한다면 CSS의 width:max-content
속성을 통해 지정할 수가 있습니다. width:max-content
속성은 상황과 관계없이 항상 컨텐츠의 크기를 따라가도록 할 수 있습니다.
.width-hug {
width: max-content;
}
CSS로 figma의 fill-container을 표현하기 위해서는 다음과 같은 상황들을 고려해야합니다.
- 부모가 block element라면
width: auto
로 가능합니다.- 부모가 row flexbox라면
flex:1
이 필요합니다.- 부모가 column flexbox라면
align-self:stretch
가 필요합니다.
각 경우에 맞는 적절한 CSS를 작성하면 width: fill-container에 대응할 수 있습니다.
그리고 최소, 최대 너비와 높이를 조절하여 원하는 적절한 크기의 범위를 지정할 수 있습니다.
CSS에서는 1:1로 대응하는 min-width
max-width
개념이 존재하므로 해당 코드로 간단히 입력을 할 수 있습니다.
Height는 반대의 개념이니 따로 적지는 않겠습니다.
종합해보자면 CSS의 width(or height)를 Figma의 개념으로 다루기 위해서는 다음과 같은 템플릿 내에서 적절한 값을 조립하여 사용할 수 있습니다.
.width-something {
/* 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;
}
TailwindCSS의 경우, 이러한 개념들을 조립해서 적절히 대응되는 TailwindCSS의 속성을 입력하여 작성을 할 수 있습니다.
<div class="flex flex-row align-center gap-[20px]">
<div class="shrink-0 w-[32px] h-[32px]">⬅</div>
<div class="flex-1">Title</div>
<div class="w-max min-w-[100px] max-w-[300px]">Button1</div>
<div class="flex-1 self-stretch">Button2</div>
</div>
AdorableCSS의 경우는 Figma을 기반으로 조금 더 시각적이고 직관적인 형태의 코드를 작성할 수 있도록 하여 코드만 보고도 어떤 모습일지 상상하기가 쉽도록 만들어보았습니다.
w(hug)
, w(fill)
속성을 추가해서 hug contents와 fill container를 지원할 수 있도록 하여 내가 조건에 맞는 CSS 속성을 고민하기 보다는 직관적이고 시각적인 표현을 사용할 수 있도록 하였습니다.
min-width, max-width의 경우 min-x(30)
, min-w(50%)
도 지원하지만 조금 더 시각적으로 표기할 수 있도록 w(30~)
, w(~50%)
, w(30~50%)
이런식의 표기도 지원을 하고 있습니다.
<!-- AdorableCSS는 코드만 보아도 어떤 모양인지 쉽게 상상할 수 있는 것이 목표! -->
<div class="hbox gap(20)">
<div class="w(32) h(32)">⬅</div>
<div class="w(fill)">Title</div>
<div class="w(hug) w(100~300)">Button1</div>
<div class="w(fill) h(fill)">Button2</div>
</div>
CSS에서는 음수 gap는 지원하진 않지만, 겹쳐서 표기하는 아바타 프로필 같은 디자인에 따라 필요할 수도 있다. Figma에서는 음수 gap을 공식적으로 지원을 하고 있다. 이건 CSS로 어떻게 구현을 하면 좋을까?
전통적인 CSS에서는 간격표기를 margin
을 통해서 해왔다. margin의 경우 컨테이너 내부의 갭이 아니라 컨텐츠를 중심으로 작성하는 간격이기 때문에 자식 컨텐츠에 전부 margin을 추가하면 gap처럼 만들기 위해서는 아래 그림처럼 첫번째 컨텐츠에도 margin이 적용이 되기 때문에 의도하지 않은 결과물이 나올 수 있습니다.
이때 > * + *
라는 CSS Selector를 사용한다면 margin을 통해서 gap과 동일한 디자인을 구현할수가 있습니다. margin은 음수도 지원을 하므로 음수 gap을 만들 수 있게 됩니다. flexbox의 gap은 방향과 관계없이 가능하나 margin-left와 margin-top은 flex-flow의 row와 column에 따라 적용을 해야합니다.
.hgap(-10) > * + * {
margin-left: -10px;
}
.vgap(-10) > * + * {
margin-top: -10px;
}
tailwind의 경우 .space-x-*
, .space-y-*
라는 형태로 유틸리티를 제공하고 있습니다.
.space-y-3 > * + * { margin-top: 0.75rem; /* 12px */ }
adorableCSS의 경우 gap이 음수라면 자동으로 동작할 수 있도록 만들고자 하고 있습니다만, CSS가 너무 복잡해지는 관계로 hgap()
, vgap()
처럼 명시적으로 가로와 세로 방향은 최소 사용자가 지정해야하는 방식으로 우선 고려되었습니다.
<div class="hbox gap(-10)"></div> <!-- 개발중 -->
<div class="hbox hgap(-10)"></div> <!-- 현재스펙 -->
CSS의 경우에는 같은 z-index가면 HTML에 나중에 그려진 순서대로 덮어쓰도록 되어 있습니다. 하지만 디자인에 따라서는 앞에 있는 컨텐츠가 더 앞으로 와야 하는 경우도 필요합니다.
Figma의 경우 이를 First on Top
이라고 부르고 있는데 이러한 기능을 CSS에는 딱 맞는 스펙이 존재하지 않습니다.
현재는 실험적으로 아래와 같이 .FirstOnTop
을 만들어보았으나 사이드 이펙트가 너무 염려되는 방식이다보니 고민중에 있습니다.
/* FIXME: */
* {z-index: 11;}
.FirstOnTop > *:nth-child(1) {z-index: 10;}
.FirstOnTop > *:nth-child(2) {z-index: 9;}
.FirstOnTop > *:nth-child(3) {z-index: 8;}
.FirstOnTop > *:nth-child(4) {z-index: 7;}
.FirstOnTop > *:nth-child(5) {z-index: 6;}
.FirstOnTop > *:nth-child(6) {z-index: 5;}
.FirstOnTop > *:nth-child(7) {z-index: 4;}
.FirstOnTop > *:nth-child(8) {z-index: 3;}
.FirstOnTop > *:nth-child(9) {z-index: 2;}
.FirstOnTop > *:nth-child(10) {z-index: 1;}
추후에는 이러한 기능들도 figma와 같은 형태로 제공을 하고자 간단히 사용할 수 있도록 하는 방법을 제공할 예정입니다,.
<div class="hgap gap(-20) firstOnTop">
<Avatar>
<Avatar>
<Avatar>
<Avatar>
</div>
수치를 이용한 좌표방식은 그 자체로 충분히 직관적으로 CSS로 표현할 수 있습니다.
이러한 Figma의 속성들을 CSS에서는 다음과 같이 표현할 수 있습니다.
.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;
}
TailwindCSS에서는 다음과 같이 표현할 수 있습니다.
<div class="absolute left-[-8901px] top-[2336px] w-[409px] h-[308px]
rotation-[90deg] rounded-[20px] overflow-hidden">
AdorableCSS에서는 직관적인 범위 안에서 가능한한 코드를 더 짧고 figma와 유사한 키워드를 쓰고 싶었기에 다음과 같은 x
, y
, r
, clip
, rotate
와 같은 속성을 추가하여 조금 더 간결하게 사용할 수 있도록 하였습니다.
x(-8901)
= left: -8901px;
y(2336)
= top: 2336px;
r(20)
= border-radius: 20px;
clip
= overflow:hidden;
rotate(90)
= transform: rotate(90deg);
<div class="absolute x(-8901) y(2336) w(409) h(308) rotate(90) r(20) clip">
Figma Text 공식문서
https://help.figma.com/hc/en-us/articles/360039956634
Figma는 다음과 같이 글자에 대한 속성들을 구성해두고 있습니다.
주요 속성과 키워드는 다음과 같습니다.
Font type
Font Weight
Font size
Line height
Letter spacing
Paragraph spacing
Auto width
Auto Height
Fixed size
Text Align left
Align top
Underline
Strike
Upper Case
lower case
small caps
Vertical trim
List style
Paragraph spacing
Truncate text
대부분은 CSS의 개념들과는 크게 상이 하지 않으며 특이할만한 것들만 몇가지만 짚고 가보려고 합니다.
기본적으로 CSS의 Text정렬은 text-align
을 이용하여 left
, center
, right
, justify
정도로만 표현되고, vertical-align
의 경우에는 inline간 정렬을 하기 때문에 실제로 자주 쓰이는 속성들이 아닙니다.
Figma의 경우에는 Text 정렬에 대해서 Text Resizing
와 Text Align Vertical
이라는 개념을 추가해서 텍스트를 정렬하도록 하고 있습니다.
Text Resizing은 Auto Width
, Auto Height
, Fixed size
라는 3가지의 옵션이 있으며, Text Align Vertical
은 Top
, Center
, Bottom
의 3가지 옵션이 있습니다.
Text Align Vertical은 Center나 Bottom일 경우에는 display:flex
를 이용하여 정렬을 해줄 수 있고 Auto Width
일 경우에는 사용 할 필요가 없습니다.
.AutoWidth {
white-space:nowrap;
}
.AutoHeight {
width: 200px; /* Fixed Width */
}
.FixedSize {
width: 200px; /* Fixed Width */
height: 200px; /* Fixed Height */
}
.Text-Vertical-Center {
display:flex;
flex-flow:column;
justify-content:center;
}
말줄임은 실전에서도 상당히 빈번하게 사용되면서 많은 CSS가 복합적으로 사용해야 하는 경우가 많아서 유틸리티 CSS에서 가장 많이 나오는 예시입니다. 1줄을 말줄임하는 경우와 여러줄을 말줄임하는 경우가 달라서 다음과 같이 CSS를 준비해보았습니다.
.truncate {
flex-shrink:1;
max-width:100%;
overflow:hidden;
white-space:nowrap;
text-overflow:ellipsis;
}
.max-lines\(3\) {
max-width:100%;
overflow:hidden;
display:-webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:3;
}
문장과 문장간의 간격을 별도로 설정하는 Paragraph Spacing이라고 하는 속성은 CSS에는 없는 속성입니다. 글자내 문장간 간격등을 만들어 내기 위해서는 다음과 같은 CSS를 이용해서 만들어 볼 수 있을 것 같습니다.
.Text > br {
display:block;
margin-top:20px;
content: "";
}
/* or */
.Text > p + p {
margin-top:20px;
}
종합해서 Figma의 속성들을 CSS로 만들기 위한 템플릿을 작성해보았습니다. CSS가 문서 서식을 기반으로 시작한만큼 거의 대부분의 속성들은 1:1로 매칭이 가능합니다. 아래는 Figma 속성이 어떤 CSS와 대응이 되는지 확인할 수 있습니다.
.Text {
/* 1. Font Type */
font-family:'Noto Sans KR';
/* 2. Font Weight */
font-weight:700;
/* 3. Font Size */
font-size:14px;
/* 4. Line Height */
line-height:22px;
/* 5. Letter Spacing */
letter-spacing:-0.01em;
/* 6. Text Decoration */
text-decoration:underline; /* or line-through */
/* 7. Text Transform */
text-transform:uppercase; /* or lowercase, capitalize */
/* or */ font-variant-caps:small-caps;
/* 8. Text Align */
text-align:left; /* or center, right, justify */
/* 9. Text Resizing & Text Align Vertical*/
white-space: nowrap;
/* or */ display:flex;
flex-flow:column;
justify-content:center; /* or flex-end */
/* 10. Vertical-trim */
leading-trim:both;
text-edge:cap;
/* 11. Truncate text */
max-width:100%;
display:-webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:1;
/* 12. Fill */
color:#fff;
}
/* 13. Paragraph spacing */
.Text > p + p {
margin-block-start: 30px;
}
.Text > br {
display:block;
margin-block-start: 30px;
content: "";
}
#CSS/3장_핵심/3.1.figmaToCSS
1장 CSS의 역사편을 통해 웹의 중심이 문서에서 동적 애플리케이션으로 이동함에 따라 Flexbox 스펙이 만들어졌다는 사실을 배웠습니다.
현대 CSS에서는 Flexbox layout을 이해하는 게 무엇보다 중요합니다. 문서가 아닌 어플리케이션을 디자인을 하기 위해서는 반드시 숙지해야만 하는 스펙입니다.
핵심 파트에서 가장 첫번째에 소개하는 것도 그 이유입니다.
현대 CSS의 핵슴은 Flexbox를 마스터를 하는 것이기에 Flexbox에 대한 필요한 기본 개념, 용어 및 구문을 배우고 작동 방식을 이해하는 데 도움이 되는 다양한 예제와 연습을 통해 작업합니다.
이 책에서는 figma의 AutoLayout의 개념을 바탕으로 flexbox 속성을 작성하고 각종 디자인을 만들어내는 방법을 배우게 됩니다.
(내용이 너무 별로다. 다시 잘 다듬자!!)
속성을 이해하기 전에 그림을 통해서 충분히 체계를 먼저 잡아보도로 합시다. CSS는 디자인을 코드로 옮기는 작업이기에 CSS의 속성을 배우기 전에 디자인에 대한 개념이 선행이 되어야 합니다. (오 멋진 말 잘 기억해놔야 겠다.)
일반적인 모바일 어플리케이션 구성입니다. 사진 앱을 떠올려주세요.
UI 구성요소들을 떠올려주세요.
(이것도 그림을 그려야 겠다.)
어플리케이션의 레이아웃은 글을 쓰는 Norml Flow랑 다릅니다.
어플리케이션 레이아웃을 구성하는 핵심요소는 다음과 같다.
위 핵심 요소들을 바탕으로 툴바를 한번 살펴보도록 하겠습니다.
.hbox {
display: flex;
flex-flow: row;
align-items: center;
}
align-items과 justify-content
처음에 flexbox를 이해하려고 하면 align-items와 justify-content의 개념과 용법이 상당히 헷갈립니다. 그리고 조금만 더 파고들면 grid 이후에 나오는 align-content와 justify-items, align-self, justify-self 등이 나오기 시작하면 더 헷갈리고 어렵게 만들곤 합니다.
많이 해봐서 익숙해지는게 최선이지만 ...
진행축, 크로스축으로 각각 start, center, end가 있다. justify-content에만 space-between이 있다는 사실을 기억하고 gap(auto)가 space-between이라는 것을 기억하면 align-items와 justify-content가 덜 헷갈릴 수 있다.
추가로 flex-flow에 따른 자주 쓰이는 align-items과 justify-content
대부분 UI에서 가로로 배치 하는 것은 툴바나 목록에서 자주 쓰이므로 세로는 가운데 정렬, 가로는 왼쪽부터 오른쪽이 제일 보편적으로 쓰이곤 한다.
또한 세로의 경우는 block과 유사하게 가로폭을 최대로 늘린 stretch를 가장 많이 쓰므로 다음과 같이 자주쓰는 세트를 외워두면 align-items과 justify-content가 어느 방향인지 떠올리기 쉽다.
그래서 적당히 세트로 외워두면 좋다.
hbox {
display:flex;
flew-flow:row;
align-items:center;
}
vbox {
display:flex;
flew-flow:row;
justify-content:stretch;
}
#CSS/3장핵심
#CSS/3장핵심/3.1.figmaToCSS
(블로그에서 작성한 내용을 바탕으로 톤앤 매너를 맞춰서 다시 작성할 예정입니다.)
CSS는 레이아웃에 대한 역사가 되게 오래되었습니다.
웹 초창기 출판의 레이아웃 개념에서 시작한 float부터 table을 거쳐 지금의 flexbox, grid에 오기까지 웹 서비스의 변화에 따른 레이아웃에 대한 방법은 다양하게 발전했습니다.
새로운 스펙이 등장할 때 마다 레이아웃을 이렇게 해야 된다 저렇게 해야 된다라는 어떤 여러 가지 해법들이 있었고, 또 브라우저마다 해법이 다르고 하나의 정답이 있지 않다보니 무엇이 맞는 방법인지 혼란스러움이 첫번째 이유입니다.
뿐만 아니라 사소하게는 내가 원하는 배치를 위해서 margin을 어디에 둘지, padding을 어디에 둘지도 같이 개발하는 사람끼리 천차만별입니다.
사실 여기에는 정답이 존재하는 것은 아니기 때문에 매번 작업을 할때마다 '이게 맞나?'라는 생각이 드는 점도 CSS를 어렵게 하는 이유 입니다.
그래서 Best Practice를 정해두고 그 철학에 맞게 개발을 하면 마음도 편하고 좋습니다.
그것이 바로 글 서두에서 밝힌 저의 Best Practice를 설명 하고자 함입니다.
CSS가 애매해지고 복잡해지는 첫 번째는 바로 margin입니다.
margin이 처음부터 어렵지는 않지요. 그러나...
아... 그래서 margin을 좀 적당히 쓰라고 하는거구나.. 를 깨닫게 됩니다.
margin은 상당히 특이한 개념입니다.
내 주위에 보이지 않는 밀어내는 힘을 만들어서 주위에 영향을 미치는 구조죠. 자석마냥 서로가 마진을 가지고 있다면 서로간의 상쇄를 통해 위치가 부여됩니다.
이게 스펙상으로는 상당히 직관적인것 같은데 반해 막상 코드로 구현된 결과물은 전혀 그렇지 않습니다.
그래서 레이아웃을 해결하는 방법에 있어서 margin보다 좋은 방법들이 많으니 꼭 margin을 써야 되는가를 생각해보세요.
실제로 figma는 margin이라는 개념이 없지만 충분히 Layout이 가능합니다.
CSS의 레이아웃의 과도기는 지나갔고 이제 거의 대부분의 레이아웃은 flexbox로 가능합니다. 그러니 일단 flexbox로만 레이아웃을 하도록 하세요.
다음 쳅터에서는 margin을 사용하지 않고 flexbox를 통해서 레이아웃을 만들어내는 방법을 알려드리도록 하겠습니다.
거의 모든 레이아웃이 가능한 CSS 스펙입니다. 그리고 더 최신 스펙인 grid로도 대체할 수 없는 레이아웃이기 때문에 꼭 알고 있어야 합니다.
IE11에서도 다행히(!) 사용가능한 아주 소중한 스펙입니다.
flexbox의 기능이 훌륭하고 구성이 어렵지 않음에도 배울때 헷갈리는 이유는 바로 스펙이 직관적이지 못하기 때문입니다.
가로 혹은 세로로 배치하기 위한 flex-direction: row | column
만 보더라도 개인적으로 조금 마음에 들지 않습니다.
그러니까 우리말로 행과 열은 항상 헷갈리지 않나요? 가로 세로가 조금더 명확 한것 같고... 사람마다 다르겠지만 저는 좀 그랬습니다.
그밖에 align-items: flex-start
, justify-content: flex-end
도 조금 헷갈리죠.
굉장히 naming 센스가 좋다고 생각하는 CSS인데 flexbox는 조금 아쉽게 스펙만 보고서 어떤 화면이 그려질리 바로 그려지지 않아요.
그래서 처음 익혀야 할 것은 flexbox를 시각적으로 이해하는게 필요합니다.
figma의 AutoLayout은 위와 같이 구성이 되어있습니다.
- 세로, 가로의 방향
실제 figma을 설치해서 한번 어떤식으로 배치가 되는지 시각적으로 이해해 보세요.
백번의 설명보다 한번의 그림으로 이해하는 것이 훨씬 더 이해하기 좋습니다.
저도 처음에는 계속 헷갈렸습니다. 연습을 계속 해도 헷갈리길래 이걸 연습으로 커버하기 보다는 좀더 직관적인 스펙으로 만드는게 낫겠다라는 생각이 들었습니다.
보통 API가 좀 마음에 안 드는 부분들을 좀 더 예쁘게 정리하는 과정을 Wrapping이라고 하는데요.
조금더 직관적인 형태로 스펙을 만들어서 사용해야겠다는 생각이 들었습니다.
row
|column
보다는horizontal
|vertical
로
align-items
|justify-content
보다는top+right
로
이렇게 한번 변경해서 만들어보니 쓰기도 편할 뿐더러 나중에 스펙을 더 이해하는데 도움이 되었습니다.
왜 CSS 스펙이 조금 더 직관적이고 시각적인 이름을 쓰지 않았을까요?
모든 언어권이 왼쪽에서 오른쪽으로 글자를 읽지는 앖습니다. css direaction: rtl(right to left)을 키워드로 한번 검색해보세요. 아랍권등에서는 문자를 오른쪽에서 왼쪽으로 읽게 됩니다. 그러니 같은 CSS를 가지고 다국어 대응등을 위해 방향만 뒤집기 위해서는 left나 right가 아니라 start, end 라고 표기를 해야 문제가 없거니와 반응형에서도 row와 column만 바꾸는 경우에 방향이 고정이 되어 있으면 이상하게 보일 수도 있기 때문입니다.
그럼에도 Wrapping을 하는 이유는 실전에서 저런 경우의 수를 고려해야 하지 않는 상황이 거의 대부분이기 때문입니다. 필요할때는 필요한 것을 찾아서 하면 되고 그때 배워도 됩니다.
AdorableCSS에서 사용하는 스펙을 css로 구현해봅시다.
한번 만들어두고 html에 적용을 해서 개발을 해보면 참 쉽구나 할 수 있습니다. Sass나 Styled Component를 사용하신다면 mixin이나 function으로 한번 만들어 보세요.
wraping를 하는 과정을 통해서 flexbox에 대해서도 한번 배워봅시다.
가로로 배치하는 flexbox를 만들어 봅시다.
row라는 이름보다는 horizontal로.. horizontal은 너무기니 horizontal flexbox를 따와서 hbox로 지었습니다.
.hbox {
display: flex;
flex-direction: row;
}
마찬가지 방법으로 세로도 만들어봅시다.
.vbox {
display: flex;
flex-direction: column;
}
@TODO: sass로 해보기
@TODO: styled-component로 해보기
두 번째는 어디에 배치하는 것인가 입니다.
배치하는 방향과 cross한 축의 위치를 결정하는 것이 align-items입니다.
hbox의 경우 대부분이 Toolbar와 같은 UI이므로 대부분 가운데 정렬이니 hbox를 아래와 같이 만들겠습니다.
.hbox {
display: flex;
flex-direction: row;
align-items: center; /* hbox는 가운데 정렬이 default이면 편하다! */
}
cross한 축의 위치라고 했으니 남은 곳은 위 아니면 아래 입니다.
align-items: flex-start
면 위,
align-items: flex-end
면 아래 입니다.
.hbox\(top\) {
display: flex;
flex-direction: row;
align-items: flex-start;
}
.hbox\(bottom\) {
display: flex;
flex-direction: row;
align-items: flex-end;
}
위, 아래가 아니라 꽉 채우는 방식도 있습니다.
.hbox\(fill\) {
display: flex;
flex-direction: row;
align-items: stretch;
}
stretch은 오타를 많이 내서 fill이라고 이름을 지어봤습니다.
배치하는 방향과 나란한 축의 배치를 결정하는 속성입니다.
기본은 왼쪽이니까 가운데와 오른쪽의 경우만 만들어보면 될 것 같습니다.
.hbox(center) {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.hbox(right) {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end
}
나란한 축의 특징은 space-between이라는 스펙이 존재한다는 것입니다. 이는 조립해서 쓰기 좋은 속성이므로 따로 만들어 주겠습니다.
justify-content
와 space-beetween
을 세트로 외워두시면 align-items와 헷갈리지 않습니다.
.space-beetween {
justify-content: space-beetween;
}
<div class="hbox(top) space-beetween">...</div>
컨텐츠를 가운데에 배치하는 것은 매우 빈번한 작업입니다. hbox(center)
와 같이 쓸 수도 있겠지만 빈도를 고려해서 더 짧은 이름의 유틸리티를 두고 사용하면 좋습니다.
.pack {
display: flex;
align-items: center;
justify-content: center;
}
margin:auto
를 이용해서 가운데 정렬을 하는 방법도 배울텐데요. 가급적 margin을 쓰지 않는다는 원칙에 따라 위 방식을 추천드립니다.
figma에는 없는 아래와 같은 스펙들을 그냥 이런게 있구나 정도만 알고 있으면 될것 같습니다.
flex-wrap
flex-direaction:row-reverse
order:0
justify-content: space-around
figma에서 지원하지 않는데에는 다 이유가 있습니다. 굉장히 특수한 목적에서만 사용이 되므로 그냥 기억만 하고 있다가 그런 상황이 닥쳤을때 생각에서 꺼내어 검색해서 활용하세요.
<div class="tool-bar hbox(top) space-beetwen">
<div class="tool-bar__item">h</div>
<div class="tool-bar__item">b</div>
<div class="tool-bar__item">o</div>
<div class="tool-bar__item">x</div>
</div>
저는 이와 같이 유틸리티 클래스를 만들어서 조립하는 방식을 추천합니다. flexbox 레이아웃은 HTML의 구조에 영향을 받도록 만들어져 있기 때문에 HTML에서 레이아웃을 잡는 편이 훨씬 더 관리하기가 쉽습니다.
하지만 그러기 싫다면 Sass나 Styled Component에서 mixin이나 함수를 한번 만들어서 사용해보는것도 그것도 싫다면 지금의 과정으로 인해 flexbox스펙이 익숙해 지길 바랍니다.
어렵지 않으실 거예요. vbox는 hbox와 방향만 다를 뿐 동일합니다.
hbox와 달리 vbox는 align-items: stretch
으로 만드는 것이 좋기 때문에 저는 아래와 같이 만들어서 사용하고 있습니다.
.vbox {
display: flex;
flex-direction: column;
align-items: stretch; /* vbox는 기본값이 stretch 가 편하다 */
}
하지만 vbox 기준으로도 상하좌우 배치를 만들어봐야 align-items나 justify-content에 대한 이해도가 완성되기 때문에 꼭 연습을 하시길 바랍니다.
패딩은 어렵지 않기 때문에 자세히 쓰지 않겠습니다. 컨테이너를 기준으로 내부로 여백을 두는 스펙이며 공통적으로 쓰이는 내부 여백이 존재한다면 패딩을 사용하시면 되겠습니다.
그다음에 이제 각각의 콘텐츠들이 있을 때 이 콘텐츠들의 간격을 만들어내는 방법인 건데
이 부분들은 이제 사실 굉장히 최근의 해법이 나왔습니다. (뭐 그렇게까지 최신은 아닙니다만...)
바로 margin을 쓰지 않고 간격을 만들 수 있는 gap이라는 속성이 생겼습니다.
그래서 갭을 입력하시면 그 사이의 간격을 일정하게 만들수가 있습니다.
대부분의 디자이너들은 일단 이 간격을 균등하게 만들고 싶어 하기 때문에 각각의 엘리먼트에 마진을 얼마씩 주면서 작업을 복잡하게 할 필요가 전혀 없어졌습니다.
.bar {
display: flex;
flex-direction: horizontal;
gap: 8px
}
특히 웹 프레임워크의 컴포넌트를 배치를 할 경우에는 margin을 전달하는 것이 굉장히 복잡하고 컴포넌트에 margin이 있을 경우 배치 위치에 따라 처리를 해줘야 하는 복잡함들을 사라지게 할 수 습니다.
그래서 컴포넌트가 아닌 배치를 하는 컨테이너에 수치나 스펙을 기술하게 해서 컴포넌트를 레이아웃에서 분리할 수 있습니다.
우연히 css-trick이나 외쿡 블로그에서 새로운 것을 접하고선 오오! 하는 마음으로 can I use에 가면... 아... 이놈의 IE11은 언제까지 해야하나... 애플은 돈 벌어서 뭐하나... 제발 사파리좀 어떻게 해줘라... 이런 마음 아시죠?
아쉽게도 이 gap는 한 가지 문제가 있습니다. 이게 최신 스펙이기 때문에 (이젠 그렇게 최신도 아닌데 ㅠㅠ) 에 가보시면 갭을 쓸 수 없는 브라우저들이 보입니다.
당연히(?) IE11에서 쓸 수가 없고요 그다음에 사파리 같은 경우에도 14이하 버전에서는 쓸 수가 없습니다. 문제는 아직은 둘다 현역이라는 거죠. ㅠㅠ
다행히 해법이 있습니다. 이거 같은 경우에는 이른바 올빼미 표기법이라고 불리는 이런 css 셀렉터 방식을 사용할 건데요. * + *
요 모양이 올빼미 같다고 해서 붙여진 이름입니다. 귀엽죠?
.bar > * + * { margin-left: 8px; }
https://alistapart.com/article/axiomatic-css-and-lobotomized-owls/
셀렉터는 필요없다고 했지만 요런거 하면서 겸사 겸사 익히는 거죠. 간격을 어떻게 만들 수 있는지 그냥 위 링크를 통해서 한번 이해하고 오세요.
이 방식을 통해서라도 각 엘리먼트에 margin을 붙이지 말고 gap 방식으로 레이아웃을 해보세요.
.bar {
display: flex;
flex-direction: horizontal;
gap: 8px /* 표준 스펙 */
}
.bar {
display: flex;
flex-direction: horizontal;
}
.bar > * + * { margin-left: 8px } /* IE나 safari 14를 지원하려면 이렇게 써야 한다. */
[정리] gap이라는 속성은 표준이나 나름 최신기능인 만큼 구 브라우저인 IE와 Safari 14.0.0 이하에서는 작동하지 않습니다.
그래서 혹시나 현업에서 IE와 Safari 14.0.0이하를 지원해야 한다면 gap 속성을 바로 쓰실 수가 없습니다.
그러면 gap을 쓰지 않고 gap과 같은 방법을 구 브라우저에서 쓸 수 없을까? 하는 것이 바로
> * + *
를 사용하는 방식입니다.
서비스가 IE를 지원을 하지 않을거라면 gap을 써도 무방할 것이며 IE를 지원해야 된다면 올빼미 표기법을 써야만 합니다.
margin을 안쓰고 우리에겐 gap이 있지만 그럼에도 디자인에 따라 다른 간격을 넣어야 하는 경우가 생깁니다.
그래서 이것 때문에 사실 또 마진을 써야 되는 경우가 생기거든요.
하지만 우리는 margin을 쓰지 않을 거기 때문에 2가지 해결법을 제시합니다.
조금 귀찮지만 figma에서는 이러한 방법 밖에 없기도 하고 좋은 방법입니다.
<style>
.gap\(4\) { gap: 4px; } /* 표준 스펙 */
.gap\(8\) { gap: 8px; } /* 표준 스펙 */
.hgap\(4\) > * + * { margin-left: 4px; } /* IE, Safari 14 지원용 polyfill */
.hgap\(8\) > * + * { margin-left: 8px; } /* IE, Safari 14 지원용 polyfill */
</style>
<div class="hbox gap(4)"> <!-- 최신 브라우저에는 gap을 쓰자. -->
<div>h</div>
<div>b</div>
<div class="hbox hgap(8)"> <!-- IE, Safari 14이하를 지원해야 한다면 hgap형태로 쓰자! -->
<div>o</div>
<div>x</div>
</div>
</div>
<div></div>
를 만들고 width나 height를 입력한다.이것도 전혀 나쁘지 않은 방법입니다. 간격을 위한 빈 엘리먼트를 만드는 것에 대해서 부정적일수 있지만 사실 전혀 문제되지 않습니다.
대부분 디자인 명세는 엘리먼트와 엘리먼트 사이의 간격을 표기해줍니다.
코드상으로도 그렇게 구현이 되어있다면 더 직관적으로 여기에 대한 간격이 얼마큼 떨어져 있구나라는 거를 좀 알 수 있기 때문에 좋습니다.
<style>
.hspace\(4\) { width:4px }
.hspace\(8\) { width:8px }
</style>
<div class="hbox">
<div>h</div>
<div class="hspace(4)"/>
<div>b</div>
<div class="hspace(4)"/>
<div>o</div>
<div class="hspace(8)"/>
<div>x</div>
</div>
반응형 작업의 마무리 격인 flex
프로퍼티 입니다. 저는 보통 이렇게 만들어두고 사용합니다.
.flex {
flex:1
}
컨텐츠는 보통 부모의 크기에 따라가며 자동으로 크기가 늘어나야 하는 영역이 존재합니다. 일반적으로 툴바에서 버튼이나 메뉴를 제외한 제목 영역등이 그러하죠.
그런 남는 영역에 flex를 지정하여 자동으로 늘어나야 할 크기를 확보해줍니다.
<div class="hbox">
<button>버튼</button>
<div class="flex">여기가 늘어나는 제목 영역</div>
<button>버튼</button>
</div>
또 양 옆으로 배치를 해야하는데 element개수가 여러개라서 space-beetween으로 좌우를 벌리기 힘들때에도 space의 공간으로 빈 엘리먼트에 flex를 사용하기도 합니다.
<div class="hbox">
<button>버튼</button>
<button>버튼</button>
<div class="flex"/>
<button>버튼</button>
</div>
레이아웃에서 엘리먼트의 크기는 아래와 같은 3가지 타입이 있다고 생각하면 될 것 같아요.
- 크기를 지정하면 해당 크기로 보여지고
근데 flexbox로 작업을 하다보면 갑자기 왜 이러지 하는 순간이 찾아옵니다.
분명히 컨텐츠가 다 보여져야 하는데 공간이 막 쪼그라드는 경우요.
*{margin:0;padding:0;box-sizing:border-box;font:inherit;color:inherit;flex-shrink:0;}
제가 쓰는 CSS Reset입니다.
flex-shrink:0
이 좀 특이하죠?
flexbox에서 컨텐츠를 배치를 하다보면 크기가 지정이 되지 않은 auto에 대한 해석을 하는 과정에서 공간 배치가 이상할때가 있습니다. flex-shrink
의 속성은 자동으로 flexbox의 공간을 어떻게 줄일지 하는 옵션을 초기값은 1입니다.
그러다 보니 특히 img태그나 scroll과 함께 쓰이다보면 모든 엘리먼트가 보이지 않고 크기를 강제로 줄여버리는 현상이 발생합니다. 그런 엘리먼트에는 flex-shrink:0을 설정해주면 원본크기가 제대로 나타납니다.
저 같은 경우에는 일반적으로 당연히 내가 뭘 조치하지 않으면 컨텐츠 사이즈 그대로 노출이 되는 것이 default라고 보고 reset에 flex-shrink:0
을 세팅을 하였습니다.
대신 기존의 말줄임과 같은 기능을 구현해야 할때에만 flex-shrink:1
을 입력하도록하였습니다.
.nowrap\.\.\. {
white-space:nowrap;
text-overflow:ellipsis;
overflow:hidden;
flex-shrink:1;
}
<div>
<div class="nowrap...">여기가 너무 작아지면 말줄임으로 보여주세요.</div>
</div>
쓰다보니 길게 설명을 드렸는데 입문자 입장에서는 여전히 헷갈리실 겁니다.
css 같은 경우에는 스펙들이 이제 워낙 많이 발전되어 있고 많이 만들어지고 있는데 어떤 것은 써라 어떤 것은 쓰지말라고 하니 뭐가 맞는건지 헷갈릴 거라고 생각합니다.
쓰지말라고 하는 것이 또 언젠가는 필요할 것 같고 실제로도 그런 순간이 오기는 하고 결국에는 내가 좋은 것과 나쁜 것을 알고 안 쓰는 순간이 와야겠죠
지금 알려 준 것만 쓰면 된다. 써야 한다. 그런 얘기는 아니구요. 일단은 헷갈리면 이 방식을 본인의 Best Practice로 하시라는 겁니다.
이 방법은 figma를 바탕으로 만들어졌기 때문에 절대로 나쁘지 않으실 겁니다.
이 Best Practice를 연습하는 방법에 대해서는 또 따로 다음 편인 실전편으로 적어 볼 예정입니다. 다음 글은 그냥 간단하게만 팁 정도로 끝날 것 같아요.
아직 다 설명하지 못한 Overlay나 Interaction, Animation에 대해서도 언젠가는 정리해볼까 하지만 CSS에서 레이아웃을 제외하면 나머지는 정석이란게 존재해서 다른 자료와는 크게 차별화가 될 것 같지는 않아요. 나머지들은 그냥 편안하게 하라는대로 공부하시면 됩니다.
혹시 css 레이아웃을 하면서 굉장히 헷갈리거나 잘 모르겠다하며 힘들었던 분들에게는 도움이 됐으면 좋겠습니다.
감사합니다 :)
#CSS/3장핵심
#CSS/3장핵심/3.1.figmaToCSS
사이트 전체 레이아웃을 잡는 방법에 대한 방법과 빨리빨리 연습할 수 있는 방법 그리고 전반적인 레이아웃에 대한 개념에 알아보도록 하겠습니다.
여러가지 레이아웃들을 어떻게 만들까?
그리고 다음과 같은 규칙을 머리속에 기억해두고 종이를 꺼내들고 네모를 그린뒤에 적당히 선을 한번 그어 보면서 이미지를 그려봅시다.
- 선은 처음부터 끝까지 그어야 합니다. 그래서 완전히 2개의 영역으로 구분이 되도록 하세요.
- 같은 방향의 선은 몇번이고 그을 수 있지만 다른 방향의 선은 안됩니다.
![](DD270545-C6D0-4731-A420-7F3B8CF466F6-44702-00000D15457336EE/스크린샷 2021-12-19 오후 7.59.03.png)
영역이 2개 이상으로 분리가 되면 진행방향 이라는 것이 생깁니다. 진행방향은 선의 방향과 반대의 방향입니다.
이렇게 분리된 영역을 컨텐트(Content) 그리고 이 컨텐츠를 묶어주는 것을 컨테이너(Container) 라고 부르며 진행방향은 컨테이너가 결정하게 됩니다.
처음으로 익혀야할 부분은 이 이 분할과 HTML코드를 이미지로 비슷하게 생각하는 일입니다.
<style>
.vbox {
display: flex;
flex-direction: column;
align-items: stretch;
}
.vbox > * { outline: 1px solid #4f80ff; } /* 이렇게 가이드 선을 그어둘 수 있게 하면 좋다. */
</style>
<div class="vbox"> <!-- Container -->
<div>1</div> <!-- Content -->
<div>2</div> <!-- Content -->
</div>
<section class="vbox"> <!-- 헷갈리면 Container Tag명을 div 대신 section을 써보세요. -->
<div>1</div>
<div>2</div>
<div>3</div>
</section>
HTML은 항상 세로로 작성되므로 가로형 컨텐츠에 대해서는 조금 더 생각이 필요합니다.
그리고 레이아웃에 원칙을 하나 더 추가를 하려고 합니다.
- 거의 대부분 컨텐츠 중 하나는 Flexible하다.
아닐경우도 있지만 레이아웃의 경우 반응형을 고려해야 하므로 거의 대부분 나머지 공간의 크기를 모두 받아줄 하나 이상의 메인컨텐츠가가 있기 때문에,
컨텐츠의 크기가
1) 고정 크기인지
2) 컨텐츠를 따라가는지 아니면
3) 남는 공간을 모두 채우는 flex인지를 생각해봅시다.
<style>
.hbox {
display: flex;
flex-direction: row;
align-items: stretch; /* 큰 레이아웃을 잡을 때에는 stretch가 더 편할 거에요. */
}
.flex { flex: 1 }
.guide > * { outline: 1px solid #4f80ff; } /* 아예 guide class를 만들어둬도 좋다! */
</style>
<div class="hbox guide"> <!-- Container -->
<div flex>1</div> <!-- Content -->
<div flex>2</div> <!-- Content -->
</div>
<section class="hbox guide">
<div style="width:100px">1</div>
<div flex>2</div>
</section>
<section class="hbox guide">
<div flex>1</div>
<div flex>2</div>
<div flex>3</div>
</section>
저도 그런것들은 기초시간에 이미 다 배웠어요. 그정도는 쉽죠! 저는 이런것들을 만들고 싶은거라구요.
두번째로 생각해야 할 것은 복합적인 컨텐츠가 만들어질때의 영역을 나누는 방법입니다. 방법은 간단합니다.
가위로 이 선을 자른다고 생각할때 둘로 반드시 나뉘는 것을 먼저 자르면 됩니다.
이 것들을 한데 모아 조립을 하기 위해서는 제일 큰데부터 안으로 들어가는 Top-Down 방식과 제일 잘게 잘린 조각들로 부터 올라오는 Bottom-up 방식이 있습니다. 물론 중간부터 하셔도 아무 상관없고 레이아웃과 HTML의 형태를 같이 그릴 수 있는 본인만의 편한 방법을 찾아보세요.
<div class="hbox">
<div>1</div>
<div>2</div>
<div class="vbox">
<div>3</div>
<div>4</div>
<div class="hbox">
<div>5</div>
<div>6</div>
</div>
</div>
</div>
어때요? 참 쉽죠?
개념 설명을 위해서 align-items, justify-content, flex, padding, gap등 핵심요소는 포함시키지 못했습니다. 자료를 만들기가 너무 어렵네요ㅠㅠ
(이거 해야지!!)
레이아웃 분할에 대한 이미지만 명확히 가져가 주신다면 감사하겠습니다!
(이거 할 수 있는 연습 과제로 변경할 것)
뭐 하지만 다들 이걸 모르시겠습니까? 정작 디자인으로 받고 나면 막막해지는 거죠. 특히 현대 웹 디자인의 정석인 Flat Design은 border등을 잘 안쓰는 편이라 어디를 잘라서 나눠야 가늠하기가 어렵습니다.
![](250017C3-5C7F-4756-A755-08C998DF08E1-44702-00000D157FA2DBCC/화면 기록 2021-12-19 오후 9.33.10.mov.gif)
이것도 자료 만들기 힘들어서 그냥 개발자 도구에서 + 기호 눌러서 전부 outline을 그리는 꼼수를 부렸습니다. 😢 하지만 이 방식을 쓰게 되면 어떤식으로 박스가 구성되어 있는지 시각적으로 참고하기 좋습니다. 👍
일부러 복잡한 예시를 좀 가져왔는데 처음에는 간단하게 늘려나가면 좋습니다. 레이아웃을 분할할 때에는 이러한 원칙이 있습니다.
- 선을 다른 영역을 침범하게 긋지 않는다!
- 의미론적으로 다른 성격의 것들이 섞이지 않게 잘라야 한다.
세로가 먼저일까? 가로가 먼저일까?
![](0EF7FFE2-AEA8-4C60-B716-46EF14A9AAD1-44702-00000D1594BAA18E/스크린샷 2021-12-19 오후 11.32.05.png)
컨텐츠의 구조가 어떻게 확장되고 어떻게 그룹이 되는냐에 따라 같은 분할이라도 순서가 다르다. 지금 예시에서는 세로 -> 가로의 형태가 더 적절하다.
연습할때는 유틸리티 클래스나 inline-style를 남발해도 좋으니 디자인을 보고 적절한 HTML의 구조를 바로 직관적으로 떠올릴수 있도록 연습해봅시다.
<style>
*{margin:0;padding:0;box-sizing:border-box}
.guide, .guide > * { outline:1px solid #4f80ff;}
.hbox{display:flex;flex-flow:row;align-items:center;}
.vbox{display:flex;flex-flow:column;align-items:stretch;}
.pack{display:flex;align-items:center;justify-content:center;}
.flex{flex:1}
.space-between{justify-content:space-between;}
*{outline: 1px solid #4f80ff;}
html,body{height:100%}
div{padding: 20px}
</style>
<div class="hbox">
<div>1</div>
<div>2</div>
<div class="flex vbox">
<div class="flex">3</div>
<div class="flex">4</div>
<div class="hbox">
<div class="flex">5</div>
<div class="flex">6</div>
</div>
</div>
</div>
유틸리티 클래스는 홍보겸 제가 사용하는 AdorableCSS의 문법에서 가져왔지만 본인이 직접 유틸리티 CSS를 만들어보시는 것이 더 좋아요!
.row { display:flex; flex-flow: row }
.column { display:flex; flex-flow: column }
(몇가지 샘플 레이아웃을 그려서 연습 할 수 있도록 하는 문제 제시)
#CSS/3장핵심
#CSS/3장핵심/3.1.figmaToCSS
border-radius: 10px;
border: 1px solid #4f80ff;
box-shadow: 0 0 10px rgba(0,0,0,.2);
#CSS/3장핵심
#CSS/3장핵심/3.1.figmaToCSS
말줄임
overflow-hidden;
text-overflow:eleisips;
여러줄 말줄임
-webkit-line-clamp: 3;
overflow:hidden;
팁
display:inline-flex;
flex-shrink:1
#CSS/3장핵심
#CSS/3장핵심/3.1.figmaToCSS
overflow:hidden
overflow:scroll
#CSS/3장핵심
#CSS/3장핵심/3.1.figmaToCSS
사용자의 행동에 반응하기
화면 크기에 반응하기
시간에 따라 반응하기
#CSS/3장_핵심/3.2.Responsive
cursor
:hover
:active
:focus
pointer-events
user-selection
버튼을 한번 떠올려볼까요? 버튼위로 마우스르 가져다 되었을 때 커서를 다르게 표기하면 누를 수 있는 곳이라고 알려주기 좋을 것 같네요. 모양과 색상이 바뀐다면 더 강조가 될 수도 있겠습니다. 버튼이니까 눌렀을때의 작용에 대한 디자인이 있다면 더 자연스러울거에요. 키보드를 사용할 경우에는 탭 키등으로 포커스가 되었을 경우에도 다른 표기가 되면 좋겠네요. 버튼은 마우스로 드래그를 했을때 글자처럼 선택영역이 생기는 것은 조금 좋지 못할 것 같아요. 사용하지 못하는 버튼은 클릭이 되지 않아야 겠죠?
이렇듯 여러가지 상황에서 CSS는 사용자와의 상호작용에 따라서 다른 디자인을 표기할 수 있습니다. 위에서 언급했던 순서와 맥락을 떠올리면서 사용자와의 상호작용에 관련된 속성들을 한번 익혀나가봅시다!
/* 키워드 값 */
cursor: pointer;
cursor: auto;
/* URL, 대체용 키워드 */
cursor: url(hand.cur), pointer;
/* URL과 좌표 및 대체 키워드
crsor: url(cursor1.png) 4 12, auto;
cursor: url(cursor2.png) 2 2, pointer;
/* 전역 값 */
cursor: inherit;
cursor: initial;
cursor: unset;
첫번째는 커서입니다. 커서는 이제 여러 가지 커서 포인트들을 변경할 수가 있습니다.
일반적으로 마우스가 호버했을 때 그의 적절한 커서의 어떤 크기가 모양이 바뀌게 되곤 합니다.
그래서 여러 가지 인터렉션을 표기할 때 적절한 커서를 사용한다면 훨씬 더 명확한 좋은
이벤트의 cs를 만들어 사이트를 만들어 낼 수가 있겠죠.
브라우저는 기본적으로 콘텐츠가 셀레 선택이 되게 됩니다.
이렇게 했을 경우에
내가 특정한 어떤 애플리케이션을 만들게 되면 이러한 선택이 되는 부분들이 사실은 되게 어색하게 보이는 영역들이 존재하기도 합니다.
특히 내가 드래그 앤으로 ui를 만들려고 할 때 글자가 선택이 돼버리면은 그것 또한 보기 좋지 않기 때문에 이러한 선택을 없앨 수 있는 방법도 존재하고 내가 클립 보드 복사를 하기 위해서 강제로 콘텐츠를 선택해줘야 되는 부분
이러한 ui들은 선택을 강조시킬 수 있는 방법이 존재합니다.
그래서 유저 셀렉트라고 하는 부분들은 드래그로 했을 때 선택된 영역에 대해서 어떻게 조치를 할 수 있는지에 대한 부분입니다.
/* Keyword values */
pointer-events: auto;
pointer-events: none;
pointer-events: visiblePainted; /* SVG only */
pointer-events: visibleFill; /* SVG only */
pointer-events: visibleStroke; /* SVG only */
pointer-events: visible; /* SVG only */
pointer-events: painted; /* SVG only */
pointer-events: fill; /* SVG only */
pointer-events: stroke; /* SVG only */
pointer-events: all; /* SVG only */
/* Global values */
pointer-events: inherit;
pointer-events: initial;
pointer-events: revert;
pointer-events: revert-layer;
pointer-events: unset;
포인트 이벤트는 종종 자주 쓰이는 부분입니다.
내가
브라우저에서는 항상 눈에 보이는 엘리먼트의 가장 최상단에 있는 엘리먼트가 마우스에 지정이 되게 됩니다.
그냥 우리가 때대로 어떤 이벤트가 전혀 이벤트가 동작하지 않기를 바라거나 이벤트를 이 이미지를 뚫고 내려가서 이벤트를 지나가야 되는 경우가 생기곤 합니다.
되지 않도록 만들기 위해서는 투명한 어떤 레이어를 위로 깔 수 있겠지만 이미 어떤 동작이 있는 상태에서 이 밑에 걸 누를 수 있도록 만들 수 있는 방법은 존재하지가 않죠.
그렇게 하기 위해서 이제 포인트 이벤트 on이라고 하는 속성이 존재합니다.
이러한 경우에는 이 엘리먼트에서는 더 이상 마우스 이벤트의 동작하지 않습니다.
그래서 이걸 실행하는 거는 두 가지가 있는데 처음부터 이 엘리베이터의 어떤 이벤트 자체나 기능들을 막고 싶어서 dsd의 과 같은 어떤 형태의 동작을 만들고 싶을 때 사용할 수가 있고요
우리가 오버레이를 깔아서 그 위에 덮어 쓰는 이미지를 만들었지만 실제로 그 아래에 있는 하단에 있는 어떤 콘텐츠가 클릭이 가능하게 만들고 싶을 때 오버레이에 깔려 있는 여기에다가 포인트 이벤트를 논이라고 설정할 세팅을 할 수 있는 여러 가지 방법들이 존재하게 됩니다.
이
또 뭐 했지 커서 3개는 꽃이 아닌 아닌가
후보와 액티브 나중에 셀렉터에 자세한 보겠지만 인터렉션을 생각할 때 여기까지를 세트로 생각하면은 좋아서 당겨왔습니다.
후버는 마우스 이벤트 마우스가 영역이 되었을 때 만들 수 있는 css입니다.
기존에 있던 css에 대대 css에 후버라는 어떤 이팩트를 붙이게 되면 마우스를 갖다 대었을 때 원하는 어떤 모양을 만들 수가 있게 됩니다.
이걸 통해서 마우스가 갖다 댔을 때의 어떤 색깔들을 만들 수 있게 되고요 네 액티브라고 불리는 것들은 마우스를 눌렀을 때 원하는 형태를 만들 수 있게 됩니다.
이 모든 내용들을 조합을 해서 다음과 같은 같은 컴퍼넌트를 만들어 볼 수 있을 것 같아요.
/* 키워드 값 */
user-select: none;
user-select: auto;
user-select: text;
user-select: contain;
user-select: all;
/* 전역 값 */
user-select: inherit;
user-select: initial;
user-select: unset;
기본적으로 버튼을 라운드를 주고 컨텐츠를 만들어서 만들어 보았습니다.
여기에 우리가 적절히 커서를 줘서
손가락의 어떤 포인터를 줄 수 있도록 만들어봤고요 이곳에 인터랙션을 줘서 포인트 이벤트 이 버튼이 이제 dsave 됐다라고 하면은 여기에 포인트 이벤트를 줘서 더 이상 클릭이 안 되도록 만들어줄 수가 있을 것 같고요 호버를 했을 경우에는
버튼이 그림자가 생길 수 있거나 이런 식으로 받을 수가 있게 되고 액티브를 했었을 때는 이제 눌러지는 형태의 그런 모양을 만들어 줄 수가 있겠습니다.
그래서 여기에 사용되고 있는 여러 가지 어떤 인터렉션과 관련된 프로포트를 이제 한 번에 외워두고 버튼이라든지 다른 여기서 셀렉트가 되면 별로 보기 안 좋겠죠.
그래서 유료 셀렉트를 눈으로 만들어주시면 다음과 같이 드래그가 안 되고 적당히 예쁜 형태의
버튼을 만들 수가 있겠습니다.
button {
user-select:none;
cursor: pointer;
}
button:hover {
}
button:active {
}
button[disabled] {
pointer-events: none;
}
#CSS/3장핵심
#CSS/3장핵심/3.2.Responsive
웹이 방대해지면서 CSS를 단순히 꾸미는 것에서 어플리케이션이 되면서 유지보수도 복잡해졌다.
CSS를 관리하는 것에 대해서 어떻게 발전을 해왔는지를 중심으로 현대의 CSS 개발은 어떻게 해야하는지에 대해서 배워보자.
1. CSS Selector란 무엇인가
정의와 기본 개념
CSS (Cascading Style Sheets)는 웹 페이지의 디자인과 레이아웃을 제어하는 언어입니다. CSS를 통해 HTML 요소가 어떻게 화면에 표시될지 결정할 수 있습니다. 이때, 특정 요소에 스타일을 적용하기 위해 사용하는 도구가 바로 'Selector'입니다.
Selector의 기능과 중요성
Selector는 이름 그대로 웹 페이지의 특정 요소를 '선택'하는 역할을 합니다. 예를 들어, 모든
#header
는 'header'라는 ID를 가진 요소를 선택합니다.2. 최초의 Selector: Simple Selector
Simple Selector의 정의
Simple Selector는 CSS의 기본적인 Selector로, 가장 단순한 형태로 요소를 선택합니다. 대표적으로 태그 이름, 클래스, 아이디를 이용해 원하는 요소를 선택할 수 있습니다.
Element, Class, ID Selector의 예시
태그를 선택합니다.
⠀사용 사례
웹 페이지에는 수많은 요소들이 존재합니다. 각 요소에 개별적으로 스타일을 적용하려면 ID Selector를 사용할 수 있으나, 같은 스타일을 공유하는 여러 요소들에 대해서는 Class Selector가 효과적입니다. 예를 들어, 웹사이트의 여러 부분에서 동일한 버튼 스타일을 적용하고 싶다면 해당 버튼들에 동일한 클래스를 부여하고, 해당 클래스에 스타일을 적용할 수 있습니다.
3. 새로운 Selector가 필요해: Combine Selector
Combine Selector의 종류
페이지의 요소 구조가 복잡해짐에 따라, 더욱 세밀한 선택이 필요할 때가 있습니다. Combine Selector는 여러 Selector를 조합하여 사용할 수 있게 해줍니다.
를 선택합니다.
만 선택합니다.
를 선택합니다.
⠀복잡한 구조에서의 활용
웹 페이지는 다양한 구조와 레이아웃을 가집니다. 때로는 목록 내부의 특정 항목만 스타일을 변경하거나, 특정 섹션의 제목 아래에 오는 문단에만 스타일을 적용하고 싶을 때 Combine Selector를 활용하면 편리합니다.
4. Selector의 복잡도가 올라가는 이유
웹 페이지의 발전과 복잡도 증가
웹 페이지는 초기 단순한 문서에서 시작하여 현재는 복잡한 인터랙티브 애플리케이션까지 변화하였습니다. 이러한 변화로 인해 CSS Selector도 복잡해져야만 원하는 요소를 정확하게 선택할 수 있게 되었습니다.
반응형 디자인의 영향
반응형 디자인의 도입으로 웹 페이지는 다양한 화면 크기와 해상도에 맞게 스타일을 적용해야 합니다. 이로 인해 매체 쿼리와 함께 복잡한 Selector가 사용되기 시작했습니다.
다양한 UI/UX 요구 사항
현대 웹은 사용자 경험(UX)에 큰 중점을 둡니다. 따라서 특정 조건 아래에서만 스타일을 적용하거나, 특정 이벤트 발생 시 스타일을 변경하는 등의 복잡한 스타일링이 필요하게 되었습니다.
선택자의 성능 이슈
선택자의 복잡도가 증가하면서, 웹 페이지의 렌더링 성능에도 영향을 미치게 되었습니다. 특히 크고 복잡한 웹 페이지에서는 선택자의 성능 최적화가 중요한 이슈로 부상하였습니다.
5. 새로운 문법의 확장 개념인 Pre-Processor: SaSS
Pre-Processor란?
CSS Pre-Processor는 CSS를 작성하기 전에 코드를 처리하여 CSS로 변환하는 도구입니다. SaSS, LESS와 같은 Pre-Processor는 변수, 중첩, 믹스인 등의 기능을 제공하여 CSS 작성을 더 간편하고 효율적으로 만들어줍니다.
SaSS의 주요 특징
⠀Pre-Processor의 장점
Pre-Processor의 도입으로 CSS 작성 시 반복되는 작업을 최소화하고, 유지 보수를 용이하게 하는 장점이 있습니다. 또한, 코드의 가독성을 높여 개발자 간의 협업도 쉽게 만들어 줍니다.
6. 개념의 변화: Selector의 복잡도를 내리려는 이유
코드의 유지 보수성
복잡한 선택자는 코드를 읽기 어렵게 만들어 유지 보수가 어려워집니다. 간결하고 명확한 선택자는 다른 개발자들과의 협업을 용이하게 하며, 미래의 자신이 코드를 수정하거나 추가할 때도 더 쉽게 작업을 할 수 있게 해줍니다.
브라우저 성능 최적화
복잡한 선택자는 브라우저가 웹 페이지를 렌더링할 때 더 많은 계산을 필요로 합니다. 간결하고 효율적인 선택자는 웹 페이지의 로딩 속도를 빠르게 하여 사용자 경험을 향상시킵니다.
오류 최소화
복잡한 선택자는 예상치 못한 스타일링 오류의 원인이 될 수 있습니다. 간단하게 유지함으로써 스타일링에 관한 버그를 최소화할 수 있습니다.
7. CSS 구조적인 한계를 극복하기 위한 CSS를 잘 작성하기 위한 방법론: BEM
BEM이란?
BEM(Block, Element, Modifier)은 CSS 클래스명을 작성하기 위한 네이밍 컨벤션입니다. BEM은 구조와 목적을 명확하게 나타내는 클래스명을 생성하여 코드의 가독성과 유지 보수성을 향상시킵니다.
BEM의 주요 구성 요소
⠀BEM의 장점
BEM을 사용함으로써 스타일의 충돌을 최소화하고, 코드의 구조와 의도를 명확히 파악할 수 있습니다. 또한, 다른 개발자들과의 협업을 간편하게 만들어 줍니다.
6. 개념의 변화: Selector의 복잡도를 내리려는 이유
코드의 유지 보수성
복잡한 선택자는 코드를 읽기 어렵게 만들어 유지 보수가 어려워집니다. 간결하고 명확한 선택자는 다른 개발자들과의 협업을 용이하게 하며, 미래의 자신이 코드를 수정하거나 추가할 때도 더 쉽게 작업을 할 수 있게 해줍니다.
브라우저 성능 최적화
복잡한 선택자는 브라우저가 웹 페이지를 렌더링할 때 더 많은 계산을 필요로 합니다. 간결하고 효율적인 선택자는 웹 페이지의 로딩 속도를 빠르게 하여 사용자 경험을 향상시킵니다.
오류 최소화
복잡한 선택자는 예상치 못한 스타일링 오류의 원인이 될 수 있습니다. 간단하게 유지함으로써 스타일링에 관한 버그를 최소화할 수 있습니다.
7. CSS 구조적인 한계를 극복하기 위한 CSS를 잘 작성하기 위한 방법론: BEM
BEM이란?
BEM(Block, Element, Modifier)은 CSS 클래스명을 작성하기 위한 네이밍 컨벤션입니다. BEM은 구조와 목적을 명확하게 나타내는 클래스명을 생성하여 코드의 가독성과 유지 보수성을 향상시킵니다.
BEM의 주요 구성 요소
⠀BEM의 장점
BEM을 사용함으로써 스타일의 충돌을 최소화하고, 코드의 구조와 의도를 명확히 파악할 수 있습니다. 또한, 다른 개발자들과의 협업을 간편하게 만들어 줍니다.
8. JS로 구현한 CSS Module
CSS Module이란?
CSS Module은 로컬 스코프의 CSS 클래스명을 생성하여 전역 스코프의 CSS 클래스명과 충돌을 방지하는 방법론입니다. 각 컴포넌트별로 독립적인 스타일을 가질 수 있게 해주며, JavaScript와 통합하여 사용됩니다.
CSS Module의 주요 특징
⠀CSS Module의 장점
CSS Module을 사용하면 스타일의 재사용성과 독립성을 동시에 얻을 수 있습니다. 또한, 컴포넌트 기반의 웹 애플리케이션 개발에 매우 적합합니다.
9. CSS in JS: styledComponent
CSS in JS의 등장 배경
컴포넌트 기반의 프론트엔드 프레임워크 및 라이브러리의 인기 증가와 함께, 스타일과 로직을 더 밀접하게 통합하려는 움직임이 생겨났습니다. 이에 따라 CSS를 JavaScript 내에서 정의하고 사용하는 패러다임이 등장했습니다.
styledComponent란?
styledComponent는 React 애플리케이션에서 인기 있는 CSS-in-JS 라이브러리 중 하나입니다. JavaScript 내에서 스타일을 선언하고, 해당 스타일을 가진 컴포넌트를 직접 생성합니다.
styledComponent의 핵심 특징
⠀CSS in JS의 장단점
장점:
⠀단점:
10. Utility CSS: tailwindCSS
Utility CSS의 철학
Utility CSS는 HTML 요소에 직접적으로 여러 작은 유틸리티 클래스를 적용하여 스타일을 정의하는 방식입니다. 이는 컴포넌트나 모듈의 추상화 없이, 스타일의 변화를 직관적으로 파악하고 조정할 수 있게 합니다.
tailwindCSS란?
tailwindCSS는 인기 있는 Utility-first CSS 프레임워크로, 유틸리티 클래스를 통해 빠르게 UI를 구축할 수 있도록 도와줍니다.
tailwindCSS의 주요 특징
⠀Utility CSS의 장단점
장점:
⠀단점:
시멘틱 CSS의 철학
시멘틱 CSS는 HTML 요소와 클래스명이 내용, 구조, 기능 등의 의미를 표현하는 방식을 기반으로 합니다. 이 접근법은 웹의 접근성과 SEO, 그리고 코드의 유지 보수성을 향상시키는데 중점을 둡니다.
유틸리티 기반 CSS
앞서 언급한 Utility CSS는 각 클래스가 특정 스타일링 작업만을 수행하는 방식을 말합니다. 이는 구성 요소의 추상화를 최소화하면서 빠르게 UI를 제작하는데 도움을 줍니다.
Atomic CSS란?
Atomic CSS는 Utility CSS와 유사한 철학을 가진 스타일링 방법론입니다. Atomic CSS에서 각 클래스는 아주 작은 (원자적인) 스타일 변경만을 담당합니다.
Atomic CSS의 핵심 특징
⠀시멘틱과 유틸리티의 균형
⠀선택의 중요성
프로젝트의 특성, 팀의 스타일링 방식, 유지 보수 요구 사항 등 다양한 요소를 고려하여 가장 적합한 스타일링 방법론을 선택해야 합니다.
위 내용은 CSS와 그 생태계의 발전을 설명하면서, 현대의 웹 개발 환경에서 CSS를 효율적으로 관리하고 유지 보수하는 방법에 대한 깊은 이해를 제공하려는 것을 목표로 합니다. 각 섹션은 해당 주제에 대한 기본 개념, 주요 특징, 장단점 및 실제 사용 사례를 포함하여 구성됩니다. 다음 항목이나 내용의 추가/수정을 원하시면 알려주세요!
CSS는 웹 페이지의 디자인을 담당하는 중요한 요소 중 하나입니다. CSS는 초기에는 단순한 선택자를 사용하여 스타일링을 했지만, 시간이 지나면서 다양한 선택자, 문법, 구조 등이 추가되어 복잡도가 높아졌습니다.
CSS의 발전 과정을 이해하고, 현재의 CSS 개발 방식을 파악하는 것은 CSS를 효율적으로 관리하고 유지보수하는 데 매우 중요합니다.
이번 장에서는 CSS와 CSS 생태계의 발전 과정을 살펴보고, 현대의 CSS 개발 방식에 대해 알아보겠습니다.
⠀CSS Selector는 HTML 요소를 선택하는 데 사용되는 문법입니다. CSS Selector는 HTML 요소의 속성과 값을 지정하여 스타일을 적용합니다.
예를 들어, 다음과 같은 CSS Selector를 사용하여 HTML 요소의 색상을 변경할 수 있습니다.
css
Copy code
p {
color: blue;
}
위 CSS Selector는 모든
요소의 색상을 파란색으로 변경합니다.
⠀CSS의 최초의 Selector는 Simple Selector입니다. Simple Selector는 HTML 요소의 이름을 직접 지정하여 선택하는 방식입니다.
예를 들어, 다음과 같은 Simple Selector를 사용하여
요소를 선택할 수 있습니다.
css
Copy code
p {
color: blue;
}
위 CSS Selector는 모든
요소의 색상을 파란색으로 변경합니다.
⠀Simple Selector는 HTML 요소를 선택하는 데 한계가 있습니다. 예를 들어, 특정 클래스를 가진
요소를 선택하거나, 특정 ID를 가진
요소를 선택하는 경우에는 Simple Selector를 사용할 수 없습니다.
이러한 문제를 해결하기 위해 Combine Selector가 등장했습니다. Combine Selector는 Simple Selector를 결합하여 사용하는 방식입니다.
예를 들어, 다음과 같은 Combine Selector를 사용하여 특정 클래스를 가진
요소를 선택할 수 있습니다.
css
Copy code
.classname p {
color: blue;
}
위 CSS Selector는 classname 클래스를 가진 모든
요소의 색상을 파란색으로 변경합니다.
⠀CSS Selector의 복잡도가 올라가는 이유는 다음과 같습니다.
⠀CSS의 복잡도를 줄이기 위해 Pre-Processor인 SaSS가 등장했습니다. SaSS는 CSS의 문법을 확장하여 다양한 기능을 제공합니다.
예를 들어, 다음과 같은 SaSS 코드를 작성하면,
sass
Copy code
$color: blue;
p {
color: color; } 위 SaSS 코드를 CSS로 변환하면 다음과 같습니다. css Copy code p { color: blue; } 위 CSS 코드에서 color 변수를
만족
불만족
복사
저장
css
Copy code
p {
color: blue;
}
위 CSS 코드에서 $color 변수를 사용하여
요소의 색상을 파란색으로 변경합니다.
SaSS는 CSS의 문법을 확장하여 다양한 기능을 제공하기 때문에 CSS의 복잡도를 줄일 수 있습니다.
⠀CSS Selector의 복잡도가 높아지면 CSS를 관리하고 유지보수하는 데 어려움이 생깁니다. CSS Selector의 복잡도를 내리면 CSS를 더욱 효율적으로 관리할 수 있습니다.
CSS Selector의 복잡도를 내리는 방법은 다음과 같습니다.
⠀CSS의 구조적인 한계를 극복하기 위해 BEM(Block, Element, Modifier)이라는 방법론이 등장했습니다. BEM은 CSS를 블록, 요소, 수정자로 구분하여 작성하는 방법론입니다.
예를 들어, 다음과 같은 BEM 코드를 작성할 수 있습니다.
css
Copy code
.block {
color: blue;
}
.block__element {
color: red;
}
.block--modifier {
color: green;
}
위 코드에서 .block은 블록을 의미하며, .block__element는 블록의 요소를 의미합니다. .block--modifier는 블록의 수정자를 의미합니다.
BEM은 CSS를 구조화하여 효율적인 관리를 할 수 있으며, CSS의 재사용과 모듈화를 쉽게 할 수 있습니다.
⠀CSS Module은 CSS를 JavaScript로 구현한 것입니다. CSS Module은 CSS를 모듈화하여 필요한 부분만 사용할 수 있으며, CSS의 중복을 줄일 수 있습니다.
예를 들어, 다음과 같은 CSS Module 코드를 작성할 수 있습니다.
javascript
Copy code
const styles = {
block: {
color: blue;
},
element: {
color: red;
},
modifier: {
color: green;
}
};
위 코드에서 styles 객체는 CSS Module을 의미합니다. styles 객체의 block, element, modifier 속성은 각각 블록, 요소, 수정자를 의미합니다.
CSS Module은 CSS를 JavaScript로 구현하기 때문에 CSS의 구조화와 재사용이 더욱 쉬워집니다.
⠀CSS in JS는 CSS를 JavaScript로 작성하는 방식입니다. CSS in JS는 CSS를 JavaScript로 작성하기 때문에 CSS의 구조화와 재사용이 더욱 쉬워집니다.
예를 들어, 다음과 같은 CSS in JS 코드를 작성할 수 있습니다.
javascript
Copy code
const StyledComponent = styled.div color: blue;
;
위 코드에서 StyledComponent는 CSS in JS로 작성된 컴포넌트입니다. StyledComponent는
있습니다.
⠀Utility CSS는 CSS를 작은 단위로 작성하는 방식입니다. Utility CSS는 CSS를 작은 단위로 작성하기 때문에 CSS의 중복을 줄일 수 있으며, CSS를 더욱 쉽게 관리할 수 있습니다.
예를 들어, 다음과 같은 Utility CSS 코드를 작성할 수 있습니다.
css
Copy code
.text-blue {
color: blue;
}
.bg-red {
background-color: red;
}
위 코드에서 .text-blue는 텍스트 색상을 파란색으로 설정하는 클래스입니다. .bg-red는 배경 색상을 빨간색으로 설정하는 클래스입니다.
Utility CSS는 CSS를 작은 단위로 작성하기 때문에 CSS의 중복을 줄일 수 있으며, CSS를 더욱 쉽게 관리할 수 있습니다.
CSS의 발전 과정을 이해하고, 현재의 CSS 개발 방식을 파악하는 것은 CSS를 효율적으로 관리하고 유지보수하는 데 매우 중요합니다. CSS의 구조화, 재사용, 모듈화를 통해 CSS의 복잡도를 줄이고, CSS를 효율적으로 관리하는 것이 중요합니다.
CSS in JS, Utility CSS 등 새로운 CSS 개발 방식을 활용하여 CSS를 더욱 효율적으로 작성하고 관리하는 것이 좋습니다.
#CSS/4장_심화
Simple Selector
#CSS/4장_심화
(역사에서 이미 언급 했으니 그중에서 Selector와 방법론을 중심으로 간단한 리캡과 함께 세부적인 내용을 설명하고 Selector의 종류나 내용에 대한 이론을 추가하는 방향으로 다시 작성해보겠습니다.)
https://wattenberger.com/blog/css-cascade
보통 CSS의 간단한 역사와 소개 그리고 문법을 배우고 나서 맨 처음에 배우는 것이 바로 이 Selector입니다.
CSS의 Selector에 대해서 개념적으로 한번 생각을 해보는 시간을 가져볼게요.
워드 프로세서를 상상해봅시다. 내가 원하는 어떤 영역을 드래그 해서 영역을 만들고 그 곳의 색상을 바꾼다거나 크기를 키우는 작업을 할 수 있습니다. 이때 이때 마우스를 누르고 드래그해서 선택 영역을 만드는 이 행위를 컴퓨터에게 시키려면 어떻게 해야 될까요.
컴퓨터에게 저 위치가 어딘지를 정확하게 알 수 있도록 지정을 해줘야 되는 작업이 필요합니다.
그래야만 컴퓨터한테 명령으로 해당 요구 사항을 실행시킬 수 있을 테니까요.
HTML에서 태그를 다는 행위가 곧 <div>드래그해서 영역을 만들어내는 행위</div>
이고 여기에 이름을 붙여둬서 컴퓨터가 찾아 갈 수 있게 해줄 수 있습니다.
어디를 찾아가야 할지 알려주는 주소같은 역할을 바로 Selector라고 합니다.
h1 { color: red}
.class { color: red}
a[href] { color: red}
div > div { color: red}
div + div { color: red}
초창기에는 4가지의 단순한 Selector만이 존재했습니다. 하지만 점점 Selector는 복잡해졌죠. 왜 그럴까요?
웹 문서가 근본이었던 시절 문서와 디자인이 한데 섞이는게 싫어서 분리를 했다고 앞서 설명을 드렸습니다.
문서란 세부 내용이 잘 변하지 않습니다. 하지만 디자인은 계속해서 변화해 갈 수 있겠죠. 그래서 하나의 컨텐츠에 여러 가지 서식을 적용할 수 있도록 하는 방법이 중요한 아젠다였습니다.
그 당시 그러한 취지의 게시판이나 쇼핑몰 솔루션, 블로그등의 서비스가 유행했다는 사실을 떠올려보세요.
그러다 보니까 HTML을 건들지 않고 CSS만으로 디자인을 잘 하는 법이 중요했습니다.
HTML을 변경할 수가 없다보니 내가 원하는 어떤 엘리먼트만 지정하기 위해서는 정교한 Selector가 필요하게 되었습니다. 그렇지 않으면 의도하지 않은 영역이 선택이 되어 버려 원치 않는 결과가 나오게 됩니다.
#navbar > ul > li.foo a[href] { color: red }
더욱이 초창기에는 4개 밖에 없는 Selector를 가지고는 영역을 잘 못 지정하는 경우가 많다보니 정교한 Selector의 요구사항이 늘어나게 되었습니다.
그래서 이 당시에는 Selector를 잘 쓰는 것이 중요했기 때문에 많은 방법의 Selector 사용법을 익히는 것이 중요했습니다.
지금은 어떨까요? 아시다시피 지금은 HTML과 CSS를 프론트엔드에서 작업을 합니다. Ajax가 생겨나면서 HTML을 만들던 백엔드는 이제 데이터만 전달을 하게 되고 HTML의 편집권을 프론트엔드에게 넘겨주게 되었습니다.
그리고 이제는 더 이상 하나의 동일한 컨텐츠에서 여러가지의 스타일을 만들 필요가 적어졌습니다. 예전에는 커스텀을 할 수 있는 것들이 주요한 가치였다면 지금은 하나의 세련된 디자인이 가치를 만드는 세상이 되었습니다.
아직도 네이버 블로그나 티스토리와 같이 테마들을 제공하는 서비스가 있지만 현대에 와서는 미디엄, 브런치, velog등과 같이 아이덴티티가 있는 하나의 디자인을 제공하는 것이 추세가 되었습니다.
누구가 아는 인스타그램을 보세요! 디자인이 곧 아이덴티티입니다.
그러다보니 더더욱 HTML의 편집이 자유로워지고 이는 곧 CSS의 셀렉터를 복잡하게 만드는 것 보다 HTML에 class를 추가하는 편이 더 관리하기가 쉽다는 것을 알게 됩니다.
<section>
<div>
<a href="">foo</a> <!-- 여기에 서식을 적용하고 싶은데 -->
</div>
<div>
<div>
<a href="">bar</a> <!-- 여기는 원하지 않았다. section > div > a 와 같은 식으로 썼어야 했다! -->
</div>
</div>
</section>
<style>
seciton div a { color: red } /* 이렇게 할 경우 의도치 않은 a에 잘못된 서식이 적용할 잠재적 위험이 항상 가지고 있게 된다! */
</style>
vs
<section>
<div>
<a href="" class="link">foo</a> <!-- 그냥 HTML에 class를 추가하는게, -->
</div>
<div>
<div>
<a href="">bar</a> <!-- 여기는 link가 없으므로 적용이 안된다. -->
</div>
</div>
</section>
<style>
.link { color: red } /* 이편이 더 간단하다.*/
</style>
그래서 더이상 복잡한 Selector를 쓰기보다는 class의 이름을 잘 지어서 붙이는 식으로 발전을 하게 됩니다.
HTML의 편집권을 가져오면서 이제 복잡한 Selector의 잠재적인 위험에서는 벗어났지만, 웹이 거대해지면서 이름 붙여야 할 것들이 엄청나게 많아지다보니 이 이름을 짓는 것에서 엄청난 어려움에 봉착하게 됩니다. 가뜩이나 CSS의 경우 global scope를 가지고 있는 태생적인 한계로 인해서 모든 이름들은 겹치지 않아야 합니다. 또한 HTML의 계층과 CSS의 계층이 다르므로 이해를 할 수 있는 계층구조를 잘 표현 할 수 있어야 했고 특히 협업을 할때 서로의 이름을 짓는 방법이 달라서 여간 고생이 아니었습니다.
ITCSS, SMACSS, OOCSS, BEM, CUBE CSS 등 한번쯤 들어봤던 이 CSS 방법론이라는 것은 결국 어떻게 하면 이 이름을 잘 지을 수 있는가에 대한 노력들이었습니다.
여러가지 방법론이 논의되었으나 현재 살아남은 승자는 BEM와 Atomic CSS(Utiliy-First) 이므로 이 2가지에 대해서만 살펴보겠습니다.
(집필하고 있는 이후에 뭔가 새로운 게 또 나올지도 모르겠습니다. 여기에 없는 이름이라면 배우세요! 뭐든 최신의 것을 배우세요!)
http://getbem.com/introduction/
(BEM에 대해서는 자세히 다시 쓰겠습니다.)
.bold { font-weight: bold }
.text-center { text-align: center }
.pull-left { float: left }
.clearfix { clear: both }
.none { display:none }
.no-text { text-indent: -9999px }
.hbox { display: flex; align-items: center; }
.relative { position: relative }
...
이른바 유틸리티 CSS로 자주 쓰는 CSS등을 미리 만들어서 사용하는 방식입니다.
CSS의 초창기부터 오래된 논쟁거리 중 하나였습니다.
.mt10 { margin-top: 10px }
은 좋은 이름인가?
최초에는 시각에서는 이러한 변경의 여지가 없는 시멘틱하지 못한 이름은 좋지 않은 것으로 여겼습니다.
그래서 사람들에게 이러한 방법은 안 좋은 일종의 꼼수로 여겨졌습니다.
하지만 점점 개발하는 환경이 변화하게 되면서 이러한 유틸리티성 class들로만 구성을 해도 좋다는 시각이 나오게 됩니다.
그 출발점을 알리게 된 것이 바로 tailwindCSS 이며 이름을 차라리 직관적인 비주얼한 이름으로 지어두면 오히려 재사용에 유리하고 조립을 통한 확장성이 뛰어나다고 말하고 있습니다.
이렇게 css를 시각적인 이름의 class를 미리 만들어서 재사용하여 조립하는 방식으로,
미리 만들어 두었기 때문에 css를 매번 작성할 필요없이 HTML에서 바로 원하는 서식을 적용할 수 있습니다.
React의 점유율이 높아져 주류가 된 지금 React와 CSS의 궁합이 사실상 좋지 못했던 부분을 Styled Component와 같은 CSS in JS라는 방식을 통해서 해결하려는 움직임이 나타나기 시작했습니다. CSS in JS에서는 더이상 Selector는 더더욱 무의미해졌습니다.
Svelte나 Vue등에서는 single File Component방식으로 인해 모듈화를 시켜주고 있습니다.
StateOfCSS의 2021년 자료에는 이제 CSS의 방법론이라는 항목조차 사라졌습니다.
CSS가 하던 디자인을 구조화하고 모듈화 하는 역할은 이제 프레임워크가 다 가져가 버렸습니다.
앞으로도 복잡한 Selector를 써야 하는 경우도 CSS의 Selector를 써야 하는 방향도 점점 줄어드는 방식으로 진행이 될 것입니다.
그럼에도 Selector라는 스펙이 있고 이걸 써야할 상황은 오겠죠? 그래서 특별히 Selector를 써야하는 경우에 대해서는 부록으로 책 후반부에 기록해 두었습니다.
이 챕터의 제목이 Selector의 사용법이 아니라 Selector 이야기인 이유입니다.
이러한 배경을 이해하고 나면 어떤 것이 오래된 개념이고 어떤 것이 최신의 것인지를 알게 되어 배움이나 사용에 있어 조금더 트렌드한 것들을 선택할 수 있는 지식이 되기를 바랍니다.
#CSS/4장_심화
Sass Sass Sass!
#CSS/4장_심화
#CSS/4장_심화
#CSS/4장_심화
#CSS/4장_심화
#CSS/4장_심화
추상화는 결국 문제라고 생각되는 복잡한 부분을 대신 해결하되 상세한 커스텀은 포기하게 되는 편의성과 유연함의 트레이드 오프 (물론 Sass와 같리 뮤조건 더 확장이 되는 방법도 있다. 이런 경우에는 설치와 의존성 그리고 학습비용이 트레이드 오프가 된다)
그래서 내가 만들고자 하는 웹과 현재의 상황에 맞춰서 기술을 선택해야 한다. 무엇이 문제이며 얻는 이득은 무엇이고 무엇을 비용으로 지불해야 하는가
그리고 각 도구들은 상호베타적인 도구가 아니다. 하나를 선택하면 다른 것들을 못 쓰는게 아니다. (less vs sass 와 같은 경우에는 같은 결의 도구이므로 그럴 수 있지만) 얼마든제 섞어 쓸 수 있다
다행이 CSS는 로직이 필요한 언어가 아니다보니 조금 귀찮더라도 전환이 쉬운 편이다.
그러니 너무 걱정하지말고 선택해보자.
#CSS/4장_심화
지금까지 배웠던 모든 내용을 정리해보도록 하겠습니다.
CSS의 자체적인 발전도 있었지만 이를 보조하기 위해 여러가지 생태계들도 생겨나기 시작했다.
#CSS/4장_심화
#CSS
#CSS/5장_확장
CSS는 어디부터 어디까지를 배워야 할 지 모르겠어요!
CSS in JS, TailwindCSS 이런 것들을 쓰고 있는데 글을 읽다보면 CSS 자체를 잘 알아야 한다는 글이 있어요. 그냥 CSS를 잘한다는 것은 어떤 것일까요?
이번 글에서는 위 질문에 대한 정확한 답은 아니겠지만 CSS에서 알아야 할 내용과 그리고 내가 얼만큼 알고 있는지에 대한 자가진단을 할 수 있으면 좋지 않을까 해서 실무에서의 중요도와 함께 알려드리면 좋을 것 같아서 작성해보았습니다.
요즘의 개발환경에서 당연히 순수 CSS를 가지고 작성을 하는 경우는 드뭅니다. CSS는 프론트엔드에서 중요한 영역이긴하지만 학습에 있어서 큰 비중을 차지하고 있지 않고 있습니다. 최근에는 mui나 antd와 같이 완성형 컴포넌트도 잘 나오는데다가 CSS를 그냥 쓸 일이 없다보니 대부분 부딫혀가며 CSS를 실무레벨에서 필요한 것들 위주로 배우게 되는 것 같아요.
이러한 방법은 나쁘지 않은 접근이라고 생각합니다. CSS의 모든 것을 알 필요도 없고 실무에서 쓰이는 것은 한정적이니까요. 또한 CSS는 예전에 만들었던 방식을 버릴 수가 없기에 지금은 사용하지 않아도 되는 구 스펙들을 다 알 필요도 없긴 합니다.
다만 내가 알고 있는데 안쓰는 거랑 몰라서 안쓰고 있는 것은 다르기에 CSS를 깊게 파지는 않더라도 어떤것들이 있는지 정도는 알면 좋은데 막상 deep dive를 하기에는 방대한 양으로 인해 또 부담이 되는 것이 사실입니다.
그래서 CSS도 한번 공부를 해봐야겠다고 생각하는 분들을 위해서 한번 나는 어떤 것들이 부족한지 어떤것을 공부해야 할지 어떤것이 중요한지 어떤것들은 그렇게 중요하지는 않는지 한번 정리를 해봤습니다.
중요도의 판단 지표는 제 기준이므로 ㅋㅋㅋ 재미로 봐주시면 좋을 것 같습니다.
쓰다보니 계속 생각나는게 있어서 이걸 한번에 다 완벽히 채우지는 못할텐데 야금야금 생각날때마다 업데이트를 하고 댓글로도 공유를 해보겠습니다.
🔥 난이도와 중요도는 별개입니다. 착각하기 쉽습니다. 어렵다고 중요한게 아닙니다!
사실 모든걸 다 알 필요는 없습니다. 실무에서는 중요한것만 반복해서 쓰기 때문에 핵심 20%만 알아도 필요한 것들은 다 할 수 있습니다. (대신 그 핵심이 뭔지를 알려면 다 알긴 해야한다는게 함정)
CSS는 같은 화면은 여러가지 방법으로 만들 수가 있습니다. 그렇기에 같은 방법을 여러개를 찾아보고 그중에서
1) 최근에 나온 기술
2) 더 코드가 간결한 것
3) 쉽게 외워지는 직관적인 것을 선택하시면 됩니다. (이 과정은 끊임없이 최신식으로 업데이트가 되어야 합니다!)
중요도를 알면 그렇다면 조금더 전략적으로 학습을 하는데 도움이 되지 않을까 싶어서 이후 나올 자가진단 목록에는 실무에서의 중요도를 표기하기 위해서 아래와 같은 기호들을 붙여두었습니다.
🔰: 입문
🔥: 쉬운데 실무에도 자주 쓰여서 꼭 알아야 하는 것
🎯: 디자인툴(피그마)에 있기 때문에 꼭 알아야 하는 것들
😎: 알고 있으면 좋은 것
🤔: 몰라도 크게 상관은 없는데 결국 배우게 되는 것들
나는 과연 CSS에 대해서 얼마나 알고 있을까요? 각 항목에 대해서
0: 전혀 모르겠다.
1: 뭔지 들어는 봤다.
2: 할 줄 안다.
3: 쌉가능!
로 한번씩 체크를 해보시면 내가 어떤 것을 공부해보면 좋은지 어느정도 알고 있는지 알 수 있을 거라고 생각합니다.
주의: 현재 진단문장의 내용이 일관성이 없습니다.😅 원래 의도는 property를 감추고 상황에 맞는 property나 혹은 CSS 코드를 떠올릴 수 있기를 바랬습니다. 모든 property에 대해 퀴즈나 상황형식으로 만드는게 쉽지 않네요.
주의2: 출처나 참고자료 같은거는 없습니다. 제 주관적으로 작성된 내용이라는 점 다시 한번 알려드립니다.
/* specificity: 0101 */
#outer a { background-color: red;}
/* specificity: 0201 */
#outer #inner a { background-color: blue;}
/* specificity: 0104 */
#outer div ul li a { color: yellow; }
/* specificity: 0113 */
#outer div ul .nav a { color: white; }
/* specificity: 0024 */
div div li:nth-child(2) a:hover { border: 10px solid black; }
/* specificity: 0023 */
div li:nth-child(2) a:hover { border: 10px dashed black; }
/* specificity: 0033 */
div div .nav:nth-child(2) a:hover { border: 10px double black;}"
#f00
이 무슨 색인지 알고 있다.
https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Fundamental_Layout_Comprehension
가벼운 마음으로 작성을 시작했던 내용들이 쓰다보니 '아... 맞다 이것도 있었지?' 이런식으로 조금씩 늘어나다보니 꽤 길어졌네요. CSS를 다룰때 제일 중요한 컴포넌트와 디자인 시스템에 관련된 항목은 일부러 제외하고 일단 최대한 순수 CSS에 초첨을 맞춰 봤습니다. 놓친게 있다면 댓글로 알려주세요.
막연히 내가 알고 있는 CSS의 능력을 이런식으로 하나씩 체크하면서 생각을 하다보면 객관적으로 내가 어떤것을 잘 모르고 있고 어떤것을 잘 알고 있는지 알 수 있는 계기가 되었으면 좋겠습니다.
그래서 이 글이 내가 무엇을 공부해할지 어떤 것들은 나중에 해도 되고 어떤 것들은 조금 더 살펴보면 좋을 지 이정표의 역할을 할 수 있었으면 좋겠습니다.
생각이 날때 마다 조금씩 해당 리스트를 정제하고 또 업데이트해서 CSS를 공부하려고 하는 분들에게 제대로된 이정표와 같은 역할을 할 수 있기를 바래봅니다.
이 글이 그래도 나를 한번 챙겨보고 혼자 공부하게 될 CSS의 로드맵을 정하는데 도움이 되기를 바랍니다.
감사합니다. ❤️
#CSS/5장_확장
과거 CSS의 가장 큰 이슈는 디자인 변경에 유연한 웹페이지를 만드는 것, 그리고 IE를 필두로 하는 크로스 브라우징이었습니다.
하지만 이제는 IE는 이제 퇴출이 되고있고 웹페이지가 아니라 웹서비스로 발전을 하게 되면서 유연한 디자인이 아니라 하나의 아이덴티티를 가지는 거대한 CSS를 만들고 관리해야 하는 이슈가 새롭게 대두 되었습니다.
그래서 이번 글에서는,
- CSS가 어떠한 문제점을 가지고 있고,
- 다른 주요 라이브러리/프레임워크들은 어떻게 해결하고 있는지
- 그리고 AdorableCSS는 이 문제들을 어떻게 해결하고 있는지
기술적인 이야기를 해볼까합니다.
이미 만들어진 웹 스펙은 변하지 않지만 웹 생태계는 항상 변하고 있다.
최초의 웹은 링크가 있는 전자문서로 시작을 했고 포맷은 신문의 형식을 많이 참고했습니다.
당시 필요에 맞게 반복적인 서식적용을 최소화 하기 위해 Cascade라는 방식을 도입하여으로
컨텐츠와 서식을 분리하고 적은 양의 코드로 반복적인 작업을 줄이면서도
같은 컨텐츠에 여러가지 디자인을 갈아 끼울 수 있는 혁신적인 방식이었습니다.
하지만 시간이 흘러
웹은 이제 웹문서에서 웹 사이트로 발전하고 이제 웹서비스, 웹앱으로 발전하게 되었습니다.
웹은 특정 벤더의 소유물이 아니기에
이미 만들어진 스펙은 하위 호환성 유지를 위해 기존 스펙을 없앨 수 없습니다.
그래서 이미 만들어진 기술과 새로운 시대의 변화를 만나면서
웹 페이지를 만들기 위해 좋았던 장점들이
거대한 웹 서비스를 만들기 위해서는 이제는 단점이 되는
상황들이 맞이하게 되는 것입니다.
그리고 늘 그래왔듯 이러한 문제점을 고쳐나가면서 웹은 발전하고 있습니다.
CSS는 물론 여러가지 태생적인 문제들이 존재하지만
이 글에서는 Facebook FE 개발자가 발표해서 유명해진 7가지 문제에 한번 집중해보겠습니다.
참고로 이 자료는 2014년 React 컨퍼런스에서
- CSS 대신 JS를 통해서 style을 만들어서 inline-style을 넣어보자라고 하는 CSS in JS라는 개념을 소개하고
- 이걸 시작으로 2017년도에 stylex라는 inline-style대신 atomic css를 만들어서 넣어주는 개념으로 발전하고
- 이후 이를 바탕으로 styledComponent라고 하는 CSS in JS 방식의 초석이 되는 자료입니다.
https://speakerdeck.com/vjeux/react-css-in-js?slide=2
- Global namespace: 모든 스타일이 global에 선언되어 중복되지 않는 class 이름을 적용해야 하는 문제
- Dependencies: css와 JS간의 의존관계를 관리하기 힘든 문제
- Dead Code Elimination: 기능 추가, 변경, 삭제 과정에서 불필요한 CSS를 제거하기 어려운 문제
- Minification: 클래스 이름의 최소화 문제
- Sharing Constants: JS 코드와 상태 값을 공유할 수 없는 문제
- Non-deterministic Resolution: CSS 로드 순서에 따라 스타일 우선 순위가 달라지는 문제
- Breaking Isolation: CSS의 외부 수정을 관리하기 어려운 문제(캡슐화)
모든 스타일이 global에 선언되어 중복되지 않는 class 이름을 적용해야 하는 문제
모두가 꼽는 CSS의 가장 큰 문제점입니다.
style은 어디에 선언을 하건 import를 하건 항상 global namespace를 가집니다.
기존에 만들어진 스타일에 override를 하기 쉽다는 장점이 있었지만
그로 인해 side-effect와 기존의 이름을 피해서 복잡하게 지어야만 하는 원흉입니다.
특히 jQuery를 이용한 페이지 단위 개발방식에서
React, Svelte, Vue와 같은 컴포넌트 기반으로 바뀌게 되면서
컴포넌트에만 css가 독립적으로 적용되기를 원하게 되었습니다.
이를 피하기 위해서 먼저 생각해 볼 수 있는 간단한 규칙은
모든 스타일앞에 컴포넌트의 클래스명을 붙이는 것입니다.
<style>
.button { ... } (X)
.header { ... } (X)
</style>
<style>
.MyComponent .button { ... } (O)
.MyComponent .header { ... } (O)
</style>
이러한 방법들은 .MyComponent
역시 global scope이기에
어딘가에서 class="MyComponent"
와 같은 구문을 쓴다면 문제가 발생하고
무엇보다 <slot/>
이나 React의 {children}
과 같은 Nested Component에서
부모 컴포넌트의 스타일이 강제로 적용이 되기 때문에
컴포넌트의 독립적인 스타일 분리 문제는 여전히 발생하게 됩니다.
<MyComponent>
<div class="button">외부에서 만든 버튼</button>
</MyComponent>
<!-- Render Result -->
<div class="MyComponent">
<div class="button">MyComponent의 버튼</div>
<div class="button">외부에서 만든 버튼</div> <!-- 여기에 컴포넌트에 의해 서식의 영향을 받는다 -->
</div>
그래서 BEM과 같은 방법들이 나타나게 됩니다.
<style>
.MyComponent__button { ... } /* (O) */
.MyComponent__header { ... } /* (O) */
</style>
<!-- Render Result -->
<div class="MyComponent">
<div class="MyComponent__button">MyComponent의 버튼</div>
<div class="button">외부에서 만든 버튼</div> <!-- 여기는 서식의 영향을 받지 않는다. -->
</div>
TMI1) 물론 BEM이 꼭 이 문제의 해결책으로 등작한것은 아니었어요.
TMI2) 2014 facebook는 class="MyComponent/button"
이런 식으로 했다고 발표 내용에 있네요.
이후 2015년 쯤에는 다른 해결방식이 나타납니다. style은 그대로 쓰고 알아서 바꿔주자는 방식이죠.
React에서는 CSS Modules
가 Vue, Svelte, Angular의 경우 single-file-component
를 통해서 컴파일 혹은 런타임때 컴포넌트마다 고유 Hash를 부여해서 독립적인 스타일을 강제로 만들어주는 방식들이 나타나게 됩니다.
/* Button.module.css */
.Button {
font-weight:bold;
text-align:center;
}
import React from "react";
import styles from "./Button.module.css";
const Button => <button className={styles.Button}>CSS Module 버튼</button>;
// <button class="_styles__Button_309571057">
이후 나타난 CSS in JS라는 방식에서는 아예 컴파일/런타임시 JS에서 style과 className를 생성하여 컴포넌트마다 독집적인 스타일을 유지 할 수 있도록 인라인 스타일과 같은 느낌으로 작성을 할 수 있게 해줬습니다.
const Button = styled.button`
font-weight:bold;
text-align:center;
`
<Button>CSS in JS</Button>
// => <button class="sc-hBEYos dWjUC">CSS in JS<button>
그러면 AdorableCSS는 Global namespace를 어떻게 해결을 했을까요?
Atomic CSS / Functional CSS라고 불리는 이 방식은 CSS의 Global Scope를 그대로 인정을 합니다.
대신 HTML을 작성하고 CSS를 후술하는 나중의 방식과 달리 변하지 않은 CSS를 먼저 만들어 두는 방식을 택했습니다.
서식의 변경이 필요하다면 CSS를 바꾸지 않고 HTML을 변경하면 그만입니다.
inline-style과 같이 서식의 적용 단위는 Element단위로 이루어지기 때문에 Global Scope의 문제점이 발생하지 않습니다.
<style>
.c\(red\) { color: red; }
.text-center { text-align: center; }
.bold { font-weight: bold}
</style>
<div>
<div class="c(red) text-center">MyComponent의 버튼</div>
<div class="bold text-center">외부에서 만든 버튼</div>
</div>
css와 JS간의 의존관계를 관리하기 힘든 문제
이 문제는 지금 2021년도에 개발을 하고 있는 사람에게는 그리 와닿지 않는 문제일수도 있겠다고 생각이 듭니다. 이제는 개발을 할때 적어도의 하나의 프레임워크는 쓰고있고 그에 맞는 Webpack이나 Rollup, Vite등 번들툴을 쓰고 있으니 CSS를 JS에서 import를 해주는 기능이 너무 당연하게 느껴질지도 모르겠습니다.
당시 Sass나 Less등 pre-processor기반의 환경에서는 CSS를 모듈로 분리하여 하나의 css파일로 만들어서 사용했는데 그러다 보니
CSS 번들러과 JS의 번들러가 달라서
그래서 CSS의 depencency와 JS의 depencency가 따로 노는 문제가 발생을 했습니다.
그래서 사용하지 않은 컴포넌트의 css가 최종 빌드에 포함이 되거나 필요한 css가 로딩이 되지 않는 문제등이 있었습니다.
현재에 와서는 주류 번들러가 기본적으로 포함하고 있는 환경이며 혹 번들러를 쓰지 않는 환경에서는 애초에 이 문제가 고민거리가 아니기에
현재에 와서는 이미 해결된 문제라고 보고 대략 자세한 설명을 생략하도록 하겠습니다.
https://speakerdeck.com/vjeux/react-css-in-js?slide=11
기능 추가, 변경, 삭제 과정에서 불필요한 CSS를 제거하기 어려운 문제
앞서 CSS depencency를 이제 JS의 import 명령어를 통해서 관리가 되기 때문에 사용하지 않는 모듈이 포함되는 문제는 해결이 되었습니다.
그럼에도 아직까지 Dead Code 문제는 남아있습니다. 같은 CSS내 모듈안에서 전혀 사용하지 않는 CSS가 있더라도 빌드 과정에서는 해당 CSS 라인은 포함이 되게 될 것입니다. HTML과 CSS는 각기 형태로 다른곳에 존재하기 때문에 자칫 전임자가 작성한 코드에서 어느 CSS는 사용하고 어느 CSS는 불필요한지 확인하기란 쉽지 않은 일이죠.
이 문제를 어떻게 해결을 할까요?
이러한 문제를 Lint와 같은 정적분석 툴을 통해서 CSS의 Selector를 이 HTML에 실제 존재하는지를 확인하는 방법을 통해서 해결을 하고자 했습니다.
하지만 HTML이 JS에서 동적으로 만들어지기도 하고 웹 프레임워크 마다 언어가 다르고 css도 pre-processor의 문법이 복잡해서 실제로는 사용하지만 찾아내지 못하는 경우가 있어 실수로 지웠다가 이슈를 만드는 일도 있었습니다.
이런일들로 css를 다시 순정으로 쓰려는 시도들도 있었고 PostCSS등이 급부상하는 계기도 생겼습니다.
tailwindCSS의 경우에도 이러한 방식을 이용해 만들어진 코드들을 PurgeCSS를 통해서 사용하지 않는 class를 제거하도록 하였습니다. Atomic CSS의 경우에는 selector가 다른 경우에 비해 훨씬 단순하기 때문에 상대적으로 사용하지 않는 class를 잘못 찾아내는 문제가 상대적으로 줄었습니다.
CSS in JS는 어떨까요?
처음부터 css를 만들어두지 않고 런타임으로 만들어내기 때문에 불필요한 CSS코드가 만들어지지 않습니다. 대신 동적으로 생성하는 비용이 발생하기 때문에 런타임이 아니라 빌드시점에 CSS를 생성하는 방법들도 연구되고 있는 중입니다.
그러면 AdorableCSS는 Dead Code Elimination 문제를 어떻게 해결을 했을까요?
AdorableCSS는 on-dand 즉, 주문형 방식으로 해당하는 코드가 존재할때만 필요한 CSS를 생성합니다.
정적 분석 툴을 이용하는 게 번들러의 import CSS를 사용하기 때문에 폴더나 파일 기준이 아니라
실제로 사용하는 코드에서만 생성하므로 사용하지 않는 파일에 대해서는 생성하지 않습니다.
또한 빌드 시점에 최종적인 CSS코드를 생성하기 때문에 런타임시 만들어지는 비용이 없어 보다 나은 퍼포먼스를 제공할 수 있습니다.
클래스 이름의 최소화 문제
CSS는 원래 시작은 적은 코드로 반복적인 서식을 제거하기 위함이었으나 복잡한 디자인과 레이아웃이 만들어지게 되면서 많은 양의 코드를 작성하게 되었습니다
CSS의 클래스네임이나 태그 셀렉터의 경우 전부 string기반이기에 이름을 다른식으로 축약해서 더 작게 만들수가 없게 되었습니다. CssNano등과 같이 최대 가능한 것들이 불필요한 공백을 제거하는 것 정도를 넘어선 압축을 하기가 힘든 문제입니다
CSS in JS의 경우, 스타일을 JS에서 동적으로 생성하기에 클래스이름이 축약되어 적용되며 CSS 사이즈의 이득을 볼 수 있습니다. 반면 그만큼의 문자열이 JS에 포함되며 CSS in JS을 구동하기 위한 라이브러리의 용량 만큼이나 번들에 포함되게 됩니다
그러면 AdorableCSS는 class minification 문제를 어떻게 해결을 했을까요?
ACSS와 같이 .D(b) { display: block}
극단적인 축약을 통해 CSS번들의 크기를 최소화 하는 방법도 있겠으나 그럴 경우 코드의 가독성을 잃어야 했습니다.
제 추구하는 개발의 가치 중 최고로 치는 가독성을 포기하는 것은 있을 수 없었기에 가독성과 축약을 상호보완할 수 있는 방법을 고민했습니다.
첫째로 CSS에서 극단적으로 1글자만 써도 예측이 가능한 것들은 그렇게 했습니다.
class="c(red) bg(blue) w(100) h(100) m(10) p(20) b(#000) r(25) x(10) y(10) z(100)"
둘째로 통상적으로 매우 자주 사용하는 기능만을 짧은 class로 제공하여 반복되는 class 타이핑을 줄였습니다.
hbox { display: flex; flex-direaction: row }```
```layer { position:absolute; top 0; right: 0; bottom: 0; left: 0;}```
**나머지는 가독성과 러닝커브를 줄이기 위해서 축약없이 CSS에서 사용하던 이름을 그대로 사용하도록 하여**
minification과 clean code의 밸런스를 맞추기 위해 세심하게 고민했습니다.
### 5. Sharing Constants
> JS 코드와 상태 값을 공유할 수 없는 문제
이 역시 2021년에 와서는 고민할 필요가 없는 문제입니다.
CSS Variable이 해당 문제를 해결하기 위한 해결책으로 CSS의 정식 기능으로 이미 탑재가 되었습니다.
물론 해당 기능을 지원하지 않은 IE11은 여전히 문제가 되고 있지만 아마 곧 완전히 퇴출될 거라고 생각합니다.
AdorableCSS의 경우에는 이를 문제로 보고 있지 않으며 CSS Variable을 적극적으로 활용하고 IE11의 경우에도 JS를 이용한 ponyfill등을 사용하기를 권장합니다.
https://jhildenbiddle.github.io/css-vars-ponyfill/#/
### 6. Non-deterministic Resolution
> CSS 로드 순서에 따라 스타일 우선 순위가 달라지는 문제
CSS의 우선순위 문제는 상당히 복잡합니다. CSS 셀렉터마다 고유한 Level과 포인트가 존재하고 그 총 합을 통해 우선수위가 결정되며 같은 우선순위라면 CSS가 나중에 적용되는 순서대로 덮어쓰도록 되어 있습니다.
html
위 경우 어떤식으로 화면에 그려질지는 HTML만 보고는 절대로 예측이 불가능합니다.
현대에 와서 이 문제가 중요해진 이유는 코드 스프리팅이 점점 보편화 되고 있기 때문입니다.
해서 CSS에서 의도한 작성순서와 다르게 로딩순서에 따라서 원하지 않는 형태로 그려지는 문제가 발생할 수 있습니다.
그러면 AdorableCSS는 Non-deterministic Resolution 문제를 어떻게 해결하고 있을까요?
AdorableCSS는 CSS를 근간으로 하다보니 Non-deterministic Resolution 문제를 가질 수 밖에 없습니다.
이미 만들어진 브라우저의 CSS의 스펙은 바꿀 수 없으며
run-time이 아니라 build-time에 생성하는 방식이니 이 문제에는 취약할 수 밖에 없습니다.
@NOTE: 대신 build-time이기에 캐시 및 로딩성능이나 번들의 사이즈등에서 run-time에 비해 이점이 있습니다. ```
그래서
**첫번째로는 수동으로 우선수위를 결정할 수 있는 기능을 제공하고 있습니다.**
```html
<!-- Adorable CSS도 역시 Non-deterministic Resolution 문제를 가지고 있다 -->
<div class="c(red) c(blue)">빨간색일까? 파란색일까?</div>
<div class="c(blue) c(red)">파란색일까? 빨간색일까?</div>
<!-- !기호를 통해 !important를 이용해 override를 지원한다! -->
<div class="c(red) c(blue)!">파란색이다!</div>
<div class="c(blue) c(red)!">빨간색이다!</div>
그렇다면 둘다 !important면 어떻게 하나요? 아직은 개발중인데 very important!라는 기능으로 !의 개수에 따라 더 우선순위를 높여주는 기능을 제공할 예정입니다.
<!-- 그렇다면 둘다 !important라면?? -->
<div class="c(red)! c(blue)!">빨간색!? 파란색!?</div>
<!-- very important!! 기능 제공(예정) -->
<div class="c(red)! c(blue)!!">빨간색! < 파란색!!</div>
하지만 위 방법은 AdorableCSS에 권장하는 방법이 아닙니다.
두번째로는 CSS에서 로딩 순서가 아닌 Selector기반의 우선순위가 만들어진 이유를 최대한 활용하고 있습니다.
<div class="fixed layer">layer는 absolute. fixed가 좀 더 특수한 경우라 우선순위를 더 조정해뒀다.</div>
<div class=".selected:c(blue) c(red) selected">클래스 선택자의 경우 항상 기본 서식보다 우선된다.</div>
<button class="disabled:bg(gray) hover:bg(red) active:bg(blue)" disabled>disabled > active > hover 순으로 우선순위가 배정되어 있다.</button>
CSS의 외부 수정을 관리하기 어려운 문제(캡슐화)
디자인 시스템에 대한 이야기는 많이 들어보셨을 겁니다. 기능의 재사용과 함께 디자인 역시 아이덴티티와 톤 앤 매너를 유지하도록 하기 위해서
마치 잘 만들어진 레고블록 처럼 디자인 블록들을 만들어 원하는 대로 조립을 해도 레고라는 아이덴티티는 유지하면서도 다양한 것들을 만들기 위한 노력이 필요합니다.
이러한 경우 그 잘만들기 위해서는 외부에서 유연하게 수정을 할 수 있는 것과 아이덴티티와 간결함을 유지하기 위한 수정을 하지 못하는 것을 분리하는 장치들이 필요합니다.
이것을 보통 캡슐화라고 부르는데 CSS에는 이점에 있어서 매우 취약합니다.
웹 페이지기반의 같은 데이터를 커스텀이 가능한 여러 디자인을 만들 수 있다는 장점을 가진 방식이
되려 재사용과 Varient를 만들기 위해서는 취약적인 구조인 셈입니다.
이러한 구조화를 하기 위해 BEM과 같은 방법론과, Sass의 Nested Block과 같은 기능들이 제안되었지만,
CSS의 구조적인 한계는 객체지향의 체계나 로직을 심을 수 있는 JS의 체계와 같지 못할 뿐더러
결국 CSS와 JS가 분리되어 있는 구조는 JS기반으로 움직이는 컴포넌트 세계와 함께 관리되기 어렵다는 문제입니다.
Vue나 Svelte등의 경우 이를 single-file-component라는 방식으로 하나의 파일에서 style과 script와 html을 묶어서 관리하는 방식을 제안했고
React에서는 이것을 CSS in JS라는 방식으로 CSS도 JS의 생태계안에 묶어서 관리하자는 방식을 제안하게 됩니다.
그러면 AdorableCSS는 Breaking Isolation를 어떻게 해결을 했을까요?
그것은 바로 주문형 시스템이라는 점입니다. 기존의 CSS와는 다르게 AdorableCSS는 CSS를 직접 작성하지 않습니다.
대개의 웹 프레임워크가 HTML을 저마다의 방식으로 확장하여 사용자에게 DOM API를 직접 쓰지 않고 바인딩을 통해서 관리 할 수 있도록 해줍니다.
AdorableCSS는 HTML의 class문법을 확장하여 사용자가 CSS를 직접 작성하지 않도록 도와 줍니다.
이는 곧 CSS가 별도 관리/작성이 되는 것이 아니라 프레임워크 생태계에 그대로 녹아낼 수 있다는 의미입니다.
한번 만들어진 CSS를 수정하지 않고, 외부에서 CSS를 override하지 않도록 해서 시스템이 망가지지 않도록 하고 있습니다.
글의 시작이 CSS in JS의 태동과 관련된 내용이다보니 결국 CSS in JS를 하면 이 문제들이 해결된다는 것 아닌가? 라는 식의 결론이 날지도 모르겠다는 생각이 듭니다.
하지만 CSS in JS도 한낱 React 진영에서의 CSS 문제 해결법 중 하나 일 뿐이며 각자의 방식으로 CSS 문제들은 해결해보고자 하고 있다라는 말을 드리고 싶습니다.
뭐가 더 우수한 방법인가 대한 얘기는 아니었습니다.
jQuery에서 웹 프레임워크로 진화해오는 변화만큼은 아직 CSS는 그만큼의 변화는 겪지 않았다고 생각합니다.
태생의 목적과 다르게 요구되는 환경에 맞는 변화에 대한 니즈를 이해해보고
나중에 또 완전히 새로운 CSS의 패러다임이 도래한다면 이러한 문제들을 곧 어떻게 해결했는가를 시작으로 학습을 하시게 될꺼라
본인이 지금 사용하고 있는 CSS에서 이러한 문제점과 그리고 해결법등을 간접적으로 느끼고 생각해볼 수 있는 글이었으면 좋겠습니다.
감사합니다.
#CSS/5장_확장
AdorableCSS에서 Reset이나 Normalize를 제공할 생각은 없나요?
현재 AdorableCSS에서 제공하는 Reset CSS는 다음과 같습니다.
*{margin:0;padding:0;box-sizing:border-box;font:inherit;color:inherit;flex-shrink:0;}
최대한 적은수의 양의 CSS를 제공하려고 단순하게 만들었지만, 점차 고민을 하다보니
html,body {height:100%}
a {text-decoration:none}
table {border-collapse:collapse;border-spacing:0}
와 같은 코드도 있으면 좋겠다 싶어서 문득 지금은 CSS Reset을 다들 어떻게 쓰고 있는지 궁금해졌습니다.
초창기에는 분명 IE와 같은 브라우저로 인해 크로스 브라우징이 주요한 아젠다이다 보니 CSS Reset에 대해 관심도가 높았었지만, 2022년을 앞두고 있는 지금은 크로스 브라우징의 원흉이었던 IE는 이제 퇴출길을 걷고 있으며 대부분의 후발부자 브라우저(엣지, 웨일, 브레이브등)은 이제 크로미움으로 통일이 되어가고 있는 상황에서 지금은 CSS Reset을 어떻게 만들어야 할까? 하는 생각이 들었습니다.
그래서 여러가지 관련자료와 애플, 네이버, 다음, 인프런, 오늘의 집, MS, 에어비엔비, 디스코드, 슬랙등의 CSS를 보면서 어떻게 사용을 하고 있는지 한번 확인을 해보았습니다. 그리고 알게된 내용들과 결론을 공유하고자 글을 쓰게 되었습니다.
이번 글의 목차는 다음과 같습니다.
- CSS Reset 이야기
- 실전에서는 어떻게 쓰고 있는가?
- 그래서 뭘 쓰면 좋을까?
웹은 아시다시피 웹 문서를 공유 하기 위해서 시작이 되었습니다. CSS가 없이 HTML만 있던 시절 기본적인 태그에는 적당한 서식이 붙어 있었습니다. 이후 CSS가 생기면서 이 서식은 CSS의 기본 default서식이 되었습니다. 우리는 이 스타일을 User-Agent StyleSheet라고 부릅니다.
3대 브라우저별 UserAgent Style
Chromium (Chrome): https://chromium.googlesource.com/chromium/src/third_party/+/master/blink/renderer/core/html/resources/html.css
Gecko (Firefox): https://searchfox.org/mozilla-central/source/layout/style/res/html.css
WebKit (Safari): https://trac.webkit.org/browser/trunk/Source/WebCore/css/html.css
안타깝게도 이 기본 서식들은 각 브라우저만의 개성이자 표준이 없던 관계로 브라우저마다 서로 다른 서식을 가지게 됩니다. 특히 IE가 주류이던 그 시절은 더 심했습니다.
우리는 작업한 결과물이 어떠한 브라우저에서던 같은 모양을 보여주길 원했고 이러한 작업을 크로스 브라우징(Cross Browsing)이라고 불렀습니다.
그리고 그러기 위해서는 우선 저마다 다른 브라우저의 스타일을 하나로 통일해야 하는 선행작업이 필요했습니다.
이것이 여러분들이 CSS를 공부했다면 한번쯤 들어봤을 CSS Reset과 Normalize 와 같은 것입니다.
* {margin: 0; padding: 0}
모든 태그에 적용된 서식에 margin과 padding을 제거하는 방식으로 시작된 이 CSS Reset이라 방법은 브라우저의 기본요소의 디자인을 모두 없애자는 것입니다. 이렇게 모두 0으로 만드는 방법을 통해서 브라우저들의 서식을 하나로 통일을 하려고 했습니다.
당시 브라우저에서 * {...}
Selector를 이용하여 CSS를 초기화를 하는 부분에는 성능과 출력의 이슈가 있어서 조금씩 정교하게 CSS를 만들어가면서 여러가지 버전의 Reset이 만들어졌는데 그중 에릭마이어의 CSS Reset이 가장 유명한 CSS가 되었습니다. 10년도 넘은 지금도 CSS Reset를 검색하면 최상위로 나타나는 자료이며 아직도 쓰이고 있습니다.
가장 유명한 (그리고 오래된...) 에릭마이어의 CSS Reset
https://meyerweb.com/eric/tools/css/reset/
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
a, abbr, acronym, address, applet, article, aside, audio, b, big, blockquote, body, canvas, caption, center, cite, code, dd, del, details, dfn, div, dl, dt, em, embed, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, html, i, iframe, img, ins, kbd, label, legend, li, mark, menu, nav, object, ol, output, p, pre, q, ruby, s, samp, section, small, span, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, time, tr, tt, u, ul, var, video {border:0;font-size:100%;font:inherit;margin:0;padding:0;vertical-align:baseline}
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {display:block}
body {line-height:1}
ol, ul {list-style:none}
blockquote, q {quotes:none}
blockquote:after, blockquote:before, q:after, q:before {content:"";content:none}
table {border-collapse:collapse;border-spacing:0}
CSS Reset은 브라우저의 모든 CSS를 제거하는 식으로 발전하는 과정에서 여러 비판도 있었습니다.
* {...}
Universal Selector은 성능상에 문제가 있다.그래서 브라우저의 스타일을 통일하고자 하는 방법은 모든 스펙을 0으로 Hard Reset! 이라는 노선에서 다른 방향으로 진행이 됩니다.
재미로 읽는 그 시절 CSS Reset History
그 옛날 CSS Reset의 모든 역사를 다루고 있는 시리즈 입니다. 궁금하시면 읽어보세요 :)
https://www.webfx.com/blog/web-design/the-history-of-css-resets/
표준이 없던 User-Agent StyleSheet에도 표준이 생겼습니다. 그렇다고 이미 만들어진 브라우저가 표준을 바로 따라 갈 수는 없었지만 새롭게 나오는 스펙들에 대해서는 다소 정리도 될 수 있었고 브라우저간 편차는 점점 줄 수 있었습니다.
여전히 크로스 브라우징의 브라우저의 모든 스타일을 통일을 하는 작업은 필요했으므로 브라우저간에 스타일이 표준 브라우저의 스타일과 동일하게 보일 수 있는 방식 이라는 정규화(Normalize)를 통해서 스타일을 통일하려는 방식이 만들어졌습니다.
이는 CSS Reset에서 보이는 거대 규칙 덩어리의 상속체인을 쓰지 않고서 일단 브라우저 스타일을 통일 했기 때문에 내가 개발할때 쓰던 브라우저(대부분 크롬이겠죠?)의 화면과 다른 브라우저와의 화면이 일치할거라고 생각할 수 있게 되었습니다.
Normalize.css
https://github.com/necolas/normalize.css/blob/master/normalize.css
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
html {-webkit-text-size-adjust:100%;line-height:1.15}
body {margin:0}
main {display:block}
h1 {font-size:2em;margin:.67em 0}
hr {box-sizing:content-box;height:0;overflow:visible}
pre {font-family:monospace, monospace;font-size:1em}
a {background-color:transparent}
abbr[title] {border-bottom:none;text-decoration:underline;text-decoration:underline dotted}
b, strong {font-weight:bolder}
code, kbd, samp {font-family:monospace, monospace;font-size:1em}
small {font-size:80%}
sub, sup {font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sub {bottom:-.25em}
sup {top:-.5em}
img {border-style:none}
button, input, optgroup, select, textarea {font-family:inherit;font-size:100%;line-height:1.15;margin:0}
button, input {overflow:visible}
button, select {text-transform:none}
[type=button], [type=reset], [type=submit], button {-webkit-appearance:button}
[type=button]::-moz-focus-inner, [type=reset]::-moz-focus-inner, [type=submit]::-moz-focus-inner, button::-moz-focus-inner {border-style:none;padding:0}
[type=button]:-moz-focusring, [type=reset]:-moz-focusring, [type=submit]:-moz-focusring, button:-moz-focusring {outline:1px dotted ButtonText}
fieldset {padding:.35em .75em .625em}
legend {box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}
progress {vertical-align:baseline}
textarea {overflow:auto}
[type=checkbox], [type=radio] {box-sizing:border-box;padding:0}
[type=number]::-webkit-inner-spin-button, [type=number]::-webkit-outer-spin-button {height:auto}
[type=search] {-webkit-appearance:textfield;outline-offset:-2px}
[type=search]::-webkit-search-decoration {-webkit-appearance:none}
::-webkit-file-upload-button {-webkit-appearance:button;font:inherit}
details {display:block}
summary {display:list-item}
[hidden], template {display:none}
Normalize를 통해서 더 적은 코드로 개별 브라우저의 스타일을 표준 브라우저의 스타일로 맞추는기는 했지만 다음과 같은 의문이 듭니다.
굳이 * {box-sizing: content-box}, html { line-height:1.15 }, sub {bottom:-.25em} 로 통일해야돼?
표준 스타일이 이미 오래된 스펙들로 만들어져있기에,
```img { max-width: 100%; height: auto; }```
table { border-collapse: collapse; border-spacing: 0}```
와 같이 표준은 아니지만 더 나은 Default값들을 반복적으로 쓰게 되니,
아예 Normalize + New Default Style등을 만들려는 방법들이 등장하게 됩니다.
sanitize.css
sanitize.css is a CSS library that provides consistent, cross-browser default styling of HTML elements alongside useful defaults.
https://csstools.github.io/sanitize.css/
/*sanitize.css*/
*, :after, :before {background-repeat:no-repeat;box-sizing:border-box}
:after, :before {text-decoration:inherit;vertical-align:inherit}
:where(:root) {-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:100%;text-size-adjust:100%;cursor:default;line-height:1.5;overflow-wrap:break-word;-moz-tab-size:4;tab-size:4}
:where(body) {margin:0}
:where(h1) {font-size:2em;margin:.67em 0}
:where(dl,ol,ul) :where(dl,ol,ul) {margin:0}
:where(hr) {color:inherit;height:0}
:where(nav) :where(ol,ul) {list-style-type:none;padding:0}
:where(nav li):before {content:"\200B";float:left}
:where(pre) {font-family:monospace, monospace;font-size:1em;overflow:auto}
:where(abbr[title]) {text-decoration:underline;text-decoration:underline dotted}
:where(b,strong) {font-weight:bolder}
:where(code,kbd,samp) {font-family:monospace, monospace;font-size:1em}
:where(small) {font-size:80%}
:where(audio,canvas,iframe,img,svg,video) {vertical-align:middle}
:where(iframe) {border-style:none}
:where(svg:not([fill])) {fill:currentColor}
:where(table) {border-collapse:collapse;border-color:currentColor;text-indent:0}
:where(button,input,select) {margin:0}
:where(button,[type=button i],[type=reset i],[type=submit i]) {-webkit-appearance:button}
:where(fieldset) {border:1px solid #a0a0a0}
:where(progress) {vertical-align:baseline}
:where(textarea) {margin:0;resize:vertical}
:where([type=search i]) {-webkit-appearance:textfield;outline-offset:-2px}
::-webkit-inner-spin-button, ::-webkit-outer-spin-button {height:auto}
::-webkit-input-placeholder {color:inherit;opacity:.54}
::-webkit-search-decoration {-webkit-appearance:none}
::-webkit-file-upload-button {-webkit-appearance:button;font:inherit}
:where(dialog) {background-color:#fff;border:solid;color:#000;height:-moz-fit-content;height:fit-content;left:0;margin:auto;padding:1em;position:absolute;right:0;width:-moz-fit-content;width:fit-content}
:where(dialog:not([open])) {display:none}
:where(details>summary:first-of-type) {display:list-item}
:where([aria-busy=true i]) {cursor:progress}
:where([aria-disabled=true i],[disabled]) {cursor:not-allowed}
:where([aria-hidden=false i][hidden]) {display:initial}
:where([aria-hidden=false i][hidden]:not(:focus)) {clip:rect(0, 0, 0, 0);position:absolute}
:where(iframe, img, input, video, select, textarea) {height:auto;max-width:100%;}
@NOTE: :where(...) 문법은 css selector의 priority를 0으로 만드는 역할을 해서 css로딩 순서와 관계없이 사용할 수 있도록 하기 위함입니다.
Reboot.css
Bootstrap용 Opinionated Normalize
https://github.com/twbs/bootstrap/blob/45eb70e03c1905d247c6e012fff9e263d1326066/scss/_reboot.scss
프레임워크 기반의 개발방식과 시멘틱 태그의 중요성이 상대적으로 낮아진 요즘 normalize.css에 있는 <sup>
<sub>
<details>
<summary>
등 쓰이지 않는 태그들을 위해서 크로스브라우징을 해줄 필요가 있을까요? 라는 생각으로 최소한의 CSS Reset만 사용하면서 box-sizing: border-box
, table { border-collapse: collapse; }
와 같은 기본보다 좋은 스펙들을 default로 만들어주는 형태의 최소한의 CSS Reset 형태를 추구하고 있는 것 같습니다.
minireset.css
https://github.com/jgthms/minireset.css
/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */
blockquote, body, dd, dl, dt, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, html, iframe, legend, li, ol, p, pre, textarea, ul {margin:0;padding:0}
h1, h2, h3, h4, h5, h6 {font-size:100%;font-weight:400}
ul {list-style:none}
button, input, select {margin:0}
html {box-sizing:border-box}
*, :after, :before {box-sizing:inherit}
img, video {height:auto;max-width:100%}
iframe {border:0}
table {border-collapse:collapse;border-spacing:0}
td, th {padding:0}
각 회사 홈페이지 대문을 기준으로 가져왔습니다. 이게 이 회사에서 공통적으로 쓰고 있는 그런거 아닙니다. 그냥 공통점이나 어떠한 흐름이 있을지 파악을 해보고자 가져온 자료이며 실제로 앞서 소개드린 오픈소스와 크게 더 나은 것은 같은 부분은 없고 대동소이한 형태를 이루고 있습니다.
결론부터 말하자면 minireset 과 유사한 형태로 Normalize보다는 Reset이지만 일부만 사용하고 있는 형태이며 대부분 자기들의 CSS이며 라이브러리를 쓰는 곳은 인프런 정도가 minireset을 쓰고 있는 것을 확인했습니다.
좀 특이해 보이는 것들은 이유가 있어서 작성했을테니 골라 담으셔도 될 것 같아요!
html {-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%}
abbr, blockquote, body, button, dd, dl, dt, fieldset, figure, form, h1, h2, h3, h4, h5, h6, hgroup, input, legend, li, ol, p, pre, ul {margin: 0;padding: 0}
address, caption, code, figcaption, pre, th {font-size: 1em;font-weight: 400;font-style: normal}
fieldset, iframe {border: 0}
caption, th {text-align: left}
table {border-collapse: collapse;border-spacing: 0}
details, main, summary {display: block}
audio, canvas, progress, video {vertical-align: initial}
button {background: none;border: 0;box-sizing: initial;color: inherit;cursor: pointer;font: inherit;line-height: inherit;overflow: visible;vertical-align: inherit}
button:disabled {cursor: default}
:focus {outline: 4px solid rgba(0, 125, 250, .6);outline-offset: 1px}
:focus[data-focus-method=mouse]:not(input):not(textarea):not(select), :focus[data-focus-method=touch]:not(input):not(textarea):not(select) {outline: none}
::-moz-focus-inner {border: 0;padding: 0}
html, body, h1, input, select {font-family:'Apple SD Gothic Neo', arial, sans-serif}
body, h1 {font-size:14px;}
h1 {font-weight:normal;margin:0;padding:0}
h3 {font-weight:normal;margin:0;padding:0;font-size:20px;line-height:1.3}
body {margin:0;background:#fff;color:#202124;}
a {color:#1a0dab;text-decoration:none;-webkit-tap-highlight-color:rgba(0, 0, 0, .10)}
a:visited {color:#609}
a:hover {text-decoration:underline}
cite, cite a:link, cite a:visited {color:#202124;font-style:normal}
button {margin:0}
ol li {list-style:none}
ol, ul, li {margin:0;padding:0}
input {font-size:14px}
em {font-weight:bold;font-style:normal}
body, button, dd, dl, dt, fieldset, form, h1, h2, h3, h4, h5, h6, input, legend, li, ol, p, select, table, td, textarea, th, ul {margin:0;padding:0}
body, button, input, select, table, textarea {font-size:12px;line-height:16px;color:#202020;font-family:-apple-system, BlinkMacSystemFont, "Malgun Gothic", "맑은 고딕", helvetica, "Apple SD Gothic Neo", sans-serif}
h1, h2, h3, h4, h5, h6 {font-size:inherit;line-height:inherit}
textarea {-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:transparent;border:0;word-break:keep-all;word-wrap:break-word}
button, input {-webkit-border-radius:0;border-radius:0;border:0}
button {background-color:transparent}
fieldset, img {border:0}
img {vertical-align:top}
ol, ul {list-style:none}
address, em {font-style:normal}
a {color:inherit;text-decoration:none}
a:hover {text-decoration:underline}
iframe {overflow:hidden;margin:0;border:0;padding:0;vertical-align:top}
mark {background-color:transparent}
i {font-style:normal}
blockquote, body, button, code, dd, div, dl, dt, fieldset, form, h1, h2, h3, h4, h5, h6, input, legend, li, ol, p, pre, select, td, textarea, th, ul {margin:0;padding:0}
fieldset, img {border:0}
dl, li, menu, ol, ul {list-style:none}
blockquote, q {quotes:none}
blockquote:after, blockquote:before, q:after, q:before {content:"";content:none}
button, input, select, textarea {vertical-align:middle;font-size:100%}
button {border:0;background-color:transparent;cursor:pointer}
table {border-collapse:collapse;border-spacing:0}
body {-webkit-text-size-adjust:none}
input:checked[type=checkbox] {background-color:#666;-webkit-appearance:checkbox}
html input[type=button], input[type=email], input[type=password], input[type=reset], input[type=search], input[type=submit], input[type=tel], input[type=text] {-webkit-appearance:none;border-radius:0}
input[type=search]::-webkit-search-cancel-button {-webkit-appearance:none}
body {background:var(--baseBackground)}
body, button, input, select, td, textarea, th {font-size:14px;line-height:1.5;font-family:KakaoSmall, Apple SD Gothic Neo, Malgun Gothic, 맑은 고딕, sans-serif;font-weight:400;color:#333}
a {color:#333}
a, a:active, a:hover {text-decoration:none}
address, caption, cite, code, dfn, em, var {font-style:normal;font-weight:400}
CSS는 이래서 참 어렵습니다. 맨날 정답이 없어요...;;
지금까지의 코드들을 통해서 파악한바로는,
이러한 방향성은 알겠지만 어떤식으로 최종적인 Reset 코드를 만들어야 할지 고민이 되었습니다.
아이러니하게도 제가 찾은 정답은 오픈소스도 현업의 코드도 아닌 개인의 블로그에서 발견한 글이었습니다.
My Custom CSS Reset
https://www.joshwcomeau.com/css/custom-css-reset/
*, :after, :before {box-sizing:border-box}
* {margin:0}
body, html {height:100%}
body {-webkit-font-smoothing:antialiased;line-height:1.5}
canvas, img, picture, svg, video {display:block;max-width:100%}
button, input, select, textarea {font:inherit}
h1, h2, h3, h4, h5, h6, p {overflow-wrap:break-word}
#__next, #root {isolation:isolate}
그래서 지금까지 확인한 내용을 바탕으로 초안을 작성해보았습니다. 지금껏 살펴본 내용과 결이 다를 수 있지만,
AdorableCSS는 AtomicCSS를 더하면서 조립하는 방식이기에 가급적 하드리셋을 추구하는 방향으로 설계하는 편이 좋다고 생각했습니다.
table, a, button, img 역시 다루기 편하게 하드리셋을 택했습니다.
box-sizing:border-box, overflow-wrap, webkit-text-size-adjust와 같이 default보다 좋은 값이 있으면 설정해주고 싶었습니다.
IE11은 아직 지원해야 되기 때문에 😢 :where(...)나 all: unset과 같은 최신 스펙은 지양하기로 하였습니다.
*{margin:0;padding:0;font:inherit;color:inherit;}
*, :after, :before {box-sizing:border-box;flex-shrink:0;}
:root {-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:100%;text-size-adjust:100%;cursor:default;line-height:1.5;overflow-wrap:break-word;-moz-tab-size:4;tab-size:4}
html, body {height:100%;}
img, picture, video, canvas, svg {display: block;max-width:100%;}
button {background:none;border:0;cursor:pointer;}
a {text-decoration:none}
table {border-collapse:collapse;border-spacing:0}
자세한 내용은 항목별로 추가 설명을 적어보았습니다.
margin, padding, font, color를 초기화 시켜줍니다. 대부분의 Reset은 여기에 치중되어 있고 Reset의 크기가 커지는 것을 원하지 않아서 **을 사용하였습니다. 예전과 달리 최신 브라우저의 ** 성능은 문제가 없는 수준이기에 조금 더 간결한 형태의 Reset을 원했습니다.
font:inherit는 버튼이나 Input등의 글자가 고유의 시스템 글자로 되는 문제가 있어 현재 글자와 동일하게 보이기 위해서 추가하였습니다.
color:inherit의 경우 a나 input, textarea의 글자색을 그대로 쓸 수 있게 하기 위해서 추가하였습니다.
box-sizing을 border-box로 바꾸는것은 작업을 훨씬 더 편리하게 만들어 줍니다. 최초 박스 모델이었던 content-box는 paddig과 border가 정해진 content-width 바깥으로 만들어지는 구조였습니다.
하지만 width가 auto일 경우에는 부모의 크기를 따라가면서 안쪽으로 padding과 border가 만들어지는 방식이었습니다. 이 점도 충분히 혼란스러운데 대부분의 디자인 툴이 width에서 안쪽으로 padding을 잡는식으로 되다 보니 padding이나 border가 생기면 그에 맞게 계속 계산을 하는게 불편하기 때문에 🔥 최근에 나온 border-box가 default로 설정되는 것은 바람직하다고 생각합니다.
또한 flex-shrink:0 역시 default가 1이 아니라 0이 되어야 한다고 생각합니다. 가급적 원본의 컨텐츠가 잘리지 않고 크기대로 나와주는 것이 좋다고 생각합니다.
-webkit-tap-highlight-color: 모바일에 클릭시 검은색 영역이 사라집니다.
-webkit-text-size-adjust: 모바일에서도 원래의 폰트 크기대로 출력됩니다.
👍 overflow-wrap:break-word;word-break:break-word;을 :root에 걸어두면 띄어쓰기가 없이 글자를 입력하면 wrap이 되지 않고 삐져나가는 일이 사라집니다.
이제 더이상 CSS는 AWESOME하지 않아도 됩니다!
이미지나 비디오가 글자 취급인 inline으로 되어 있어서 외부에서 엘리먼트를 감싸다 보면 꼭 하단에 4px씩의 여백이 생기곤 합니다. 대부분의 미디어 컨텐츠는 block 취급을 받는게 낫습니다. max-width:100%는 CSS가 AWESOME하지 않게 하도록 하기 위함입니다. (삐져나가는 거 금지)
CSS는 공부하면 할수록 선택장애가 오는 것 같습니다. 🤔 어떠한 방법이든 화면만 잘 나오면 되는 것은 맞지만 '이게 맞나?'의 끊임없는 물음을 불러일으킵니다.
글을 쓰고 나면 최종 CSS Reset가 정해지지 않을까 하는 생각으로 글을 쓰기 시작했고 그게 한발자국 나아가는 효과를 줬네요. 조금이라도 발전을 할 수 있어서 기분이 좋습니다.
*{margin:0;padding:0;font:inherit;color:inherit;}
*, :after, :before {box-sizing:border-box;flex-shrink:0;}
:root {-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:100%;text-size-adjust:100%;cursor:default;line-height:1.5;overflow-wrap:break-word;word-break:break-word;tab-size:4}
html, body {height:100%;}
img, picture, video, canvas, svg {display: block;max-width:100%;}
button {background:none;border:0;cursor:pointer;}
a {text-decoration:none}
table {border-collapse:collapse;border-spacing:0}
그래서 "저는 뭐 써야 하는데요?"라고 물어보신다면 "CSS에 정답은 없습니다. 필요한것만 그때 그때 골라담으세요." 라는 답변을 드려야 될것 같아요.
하지만 "그래도 하나를 추천한다면은요?" 라고 물어본다면 하드리셋을 원하신다면 제 것을 추천합니다. 그냥 무난한 것을 택한다면 SPA를 하신다면 minireset을 홈페이지를 하신다면 sanitize를 추천드리고 싶네요. (그렇다고 하고 있던 프로젝트에 덮어씌우거나 하지는 마세요~ 엄청 귀찮아집니다! 사실 Reset이 그렇게 막 대단한 것은 아니잖아요.)
minireset.css
https://github.com/jgthms/minireset.css
sanitize.css
sanitize.css is a CSS library that provides consistent, cross-browser default styling of HTML elements alongside useful defaults.
https://csstools.github.io/sanitize.css/
끝으로 이거 하나는 확실하게 추천드릴 수 있을 것 같습니다. 제가 새롭게 알게된 이것은 Reset과 관련없이 추천드립니다.
띄어쓰기 안한 글자가 삐져나가는 현상을 막는 꿀팁!
:root {overflow-wrap:break-word;word-break:break-word;}
https://developer.mozilla.org/ko/docs/Web/CSS/overflow-wrap
아무쪼록 이 글이 도움이 되기를 바라면서 여기에 나와있지 않는데 본인이 쓰고 있는 좋은 Base CSS 라인 1줄이 있다면 공유 부탁드려요. 😘
궁금한 내용이 있다면 댓글로 남겨주세요.
감사합니다. :)
UPDATE 1/14:
tailwindCSS를 말해주셔서 한번 찾아 봤습니다. :) 감사합니다!
*,::before,::after{box-sizing:border-box;border-width:0;border-style:solid;border-color:theme('borderColor.DEFAULT','currentColor')}
::before,::after{--tw-content:''}
html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:theme('fontFamily.sans',ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji")}
body{margin:0;line-height:inherit}
hr{height:0;color:inherit;border-top-width:1px}
abbr:where([title]){text-decoration:underline dotted}
h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}
a{color:inherit;text-decoration:inherit}
b,strong{font-weight:bolder}
code,kbd,samp,pre{font-family:theme('fontFamily.mono',ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-size:1em}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sub{bottom:-0.25em}
sup{top:-0.5em}
table{text-indent:0;border-color:inherit;border-collapse:collapse}
button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:inherit;color:inherit;margin:0;padding:0}
button,select{text-transform:none}
button,[type='button'],[type='reset'],[type='submit']{-webkit-appearance:button;background-color:transparent;background-image:none}
:-moz-focusring{outline:auto}
:-moz-ui-invalid{box-shadow:none}
progress{vertical-align:baseline}
::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}
[type='search']{-webkit-appearance:textfield;outline-offset:-2px}
::-webkit-search-decoration{-webkit-appearance:none}
::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}
summary{display:list-item}
blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}
fieldset{margin:0;padding:0}
legend{padding:0}
ol,ul,menu{list-style:none;margin:0;padding:0}
textarea{resize:vertical}
input::placeholder,textarea::placeholder{opacity:1;color:theme('colors.gray.400',#9ca3af)}
button,[role="button"]{cursor:pointer}:disabled{cursor:default}
img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}
img,video{max-width:100%;height:auto}
[hidden]{display:none}
#CSS/5장_확장
https://web.dev/state-of-css-2022/#table-of-contents
On this page
#CSS/5장_확장
역사편에 넣으려고 했다가 굳이 할 필요가 없을 것 같아 하지 않았습니다.
Internet Explorer는 버전별로 다른 소프트웨어로 구성되어 있기 때문에, 이전 버전에서는 지원하지 않는 CSS 기술을 사용하기 어려웠습니다. 이러한 구조는 웹 개발자들이 다양한 버전의 Internet Explorer에서 일관된 디자인을 유지하기 위해 많은 노력을 기울여야 했으며, 이는 개발 비용과 시간의 증가로 이어졌습니다.
또한, Internet Explorer의 버전별로 다른 소프트웨어로 구성되어 있기 때문에, 보안 이슈와 호환성 문제 등이 발생하기 쉬웠습니다. 이는 사용자들이 다른 웹 브라우저로 이동하게 된 주요한 이유 중 하나였습니다.
따라서 현재는 Internet Explorer와 같은 구식 브라우저 대신 최신 웹 기술을 지원하는 웹 브라우저를 사용하고, 최신 CSS 기술을 활용하여 일관된 디자인을 유지하는 것이 바람직합니다.
#CSS/5장_확장
Basic properties
Font family
Font weight
Font size
Alignment
Decoration
Strikethrough
Underline
Letter case
Lists
Numbers
Style
Position (subscript and superscript)
Fractions
Slashed zero
OpenType features
Resizing
Auto width
Auto height
Fixed size
Text truncation
Spacing and formatting
Letter spacing
Line height
List spacing
Paragraph indent
Paragraph spacing
Variable fonts
text-indent: 첫 번째 줄의 들여쓰기를 지정합니다. 일반적으로 픽셀(px), em, rem 등의 단위를 사용하여 값을 설정합니다.
#CSS/5장_확장
이 정도로 알찬 정보글을 무료로 공유해주신다니... 정말 압도적 감사...!