PostCSS
PostCSS 란?
매해 아무 공신력도 없고 의미도 없지만 들어가서 확인하게 되는 developer roadmap을 보면 CSS Pre-processors로 Sass와 항상 언급되는 것이 하나 있다. 바로 PostCSS이다.
PostCSS is a tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more.
PostCSS는 Autoprefixer를 만든 Andrey Sitnik가 시작한 프로젝트이며 자바스크립트로 작성된 플러그인을 통해 CSS에
1. 린트를 통해 코드 스타일을 제한하거나(https://stylelint.io/)
2. 마치 Sass처럼 변수, 믹스인을 CSS내에서 사용하거나(https://github.com/jonathantneal/precss)
3. babel처럼 아직 지원하지 않는 새로운 구문들을 사용할 수 있게 트랜스파일 해주는(http://cssnext.io/)
등 여러가지를 한번에 도와주는 도구이다. PostCSS는 자체로 의미있는 것이 아니라 여러 플러그인을 함께 사용할 때 큰 힘을 발휘할 수 있으며 sourcemap과 AST(Abstract Syntax Tree)를 제공하여 어떻게 코드가 변형되는지 이해할 수 있다고 한다.
- 다른 곳에서도 쓰일까?
create-react-app(v2.1.2)로 프로젝트를 기본으로 생성한 결과를 살펴보면 PostCSS 플러그인들을 기본으로 제공하는 것을 볼 수 있다.
vue-cli에서는 3.0 버전 이후로 PostCSS를 디폴트로 지원하게 된다고 한다.
위키피디아, 페이스북, 구글, 알리바바 등에서 지속적으로 유지보수를 하고 있으며 권장되고 있는 설정이다.
갑자기 분위기 PostCSS?
다음과같은 이유 때문에 고민하게 되었다.
- 아직은 부족한 마크업 실력(신경 쓸 것이 많음)
- 매번 prefix를 붙여야 하는 위기
- IE에서 지원이 안되는 요소는?
- — 약간의 귀찮음 —
결론은 pre-processor
- prefix Hell!
그리고 prefix가 필요한 CSS 요소들
1. box-sizing
2. column-width
3. box-shadow
4. transform
5. flexbox
6. flex-order
7. …..
등등 외우기엔 너무 많다.
또한 순서도 신경써야 한다! 사실 어려운 내용은 아니지만 prefix를 붙일 때 순서의 영향이 있다. 항상 표준 속성을 마지막에 적어줘야 한다.
* https://css-tricks.com/ordering-css3-properties/
PostCSS가 이 수고를 덜어줄 수 있을까?
PostCSS 사용하기(with webpack)
- 설치
$ npm i — save-dev postcss postcss-loader
- PostCSS 설정
루트 경로 postcss.config.js에 기본적인 설정 작성
자세한 옵션은 https://github.com/postcss/postcss#options를 참고.
plugin에 설정시 주의해야할 점이 있는데 `순서의 영향`을 받는다.
plugin은 탑다운 방식으로 실행. 위 예제에서 나타난 것 처럼 [0]->[1]->[2] 순서로 실행이 된다. (대부분 순서의 영향을 받는 plugin은 깃헙의 README에 플러그인 순서를 명시하고 있으니 문제가 발생한다면 의심해 보자.)
- webpack 설정
webpack.config.js에 들어가 기존 scss 확장자들의 로더를 지정하는 부분의 설정을 바꿔준다.
파서를 postcss-scss로 하여 scss처럼 사용할 수 있지만 sass-loader를 사용하기 때문에 별다른 parser를 추가할 필요가 없다. (추가적으로 postcss-scss는 scss를 css로 컴파일 해주지 않는다. 본인들이 비슷하게 작동하도록 코드를 작성한 것이라.. Sass를 사용할 것이라면 sass-loader를 거친 후 나온 결과에 postcss-loader를 사용하는 것이 좋을 것 같다.)
- 지원 브라우저 제한
브라우저를 명시하지 않을 경우 browserslist에서 디폴트로 지정한 브라우저에 맞게 컴파일 된다.
브라우저를 명시하고 싶다면 .browserslistrc 파일을 생성하여 작성 필요.
토스트 파일의 경우 IE10 부터 chrome, safari 최신 브라우저를 지원하여 최근 두 버전을 지원하도록 명시했다.
* 참고: https://github.com/browserslist/browserslist#best-practices
- 결과 확인
밑 그림은 변경된 결과이다.(develop)
PostCSS 플러그인 소개
- PostCSS 플러그인 소개: https://github.com/postcss/postcss/blob/master/docs/plugins.md
약 270개가 존재한다. 모두를 살펴 볼 수는 없고(모두를 다 알고 있지도 않고 몇가지만 소개하려 한다.)
- Autoprefixer
Autoprefixer는 CSS를 파싱할 때 자동으로 vendor 별 prefix를 붙여주는 플러그인이다. 데모 사이트에서 지원 브라우저에 따라 맞게 prefix를 붙여 주는 것을 테스트해 볼 수 있다. Autoprefixer는 polyfill이나 핵을 제공하는 것이 아니라 단순히 prefix가 붙는 것이기 때문에 필요하다면 다른 플러그인을 활용해야 한다.
- (부록) postcss-unprefix
postcss-unprefix는 자동으로 prefix를 붙여주는 autoprefixer와 반대로 prefix를 없애주는 플러그인이다.
- postcss-flexbugs-fixes
postcss-flexbugs-fixes는 주로 IE10, 11에서 발생하는 flex 관련 버그가 일어날 부분들을 찾아 수정해준다.
예를 들어 flex의 축약형을 이용해서 단위가 없는 flex-basis는 무시 되는 버그가 IE10, 11에서 존재한다.
이외에 IE 10, 11에서 발생하는 버그들을 정상 작동할 수 있게 수정해준다.
(부록) flex의 축약형은 flex: flex-grow, flex-shrink, flex-basis로 이뤄져 있다. 관련 설명은 MDN 링크에서 확인 할 수 있다.
* flex-basis: 기준
* flex-shrink: 총 basis가 적을 경우 값이 큰 것부터 우선적으로 축소
* flex-shrink: 총 basis가 남을 경우 값이 큰 것부터 우선적으로 확대
- PostCSS Preset Env
PostCSS Preset Env는 미래에 추가될 것으로 논의되고 있는 css 기능들을 여러 브라우저에서 사용할 수 있게 변경해주는 플러그인이다. postcss-flexbug-fixes와 같이 CRA에 기본으로 포함되어있는 플러그인이다.
를 `&`를 이용하여 nesting해 줄 수 있다. 또한 var를 이용하여 변수처럼 사용할 수 있다.
그 외 `custom-media`, `custom-selector`등 각 stage 별로 기능을 선택해 사용할 수 있다.
- cssnano
cssnano는 css 작성 시 실수할 수 있는 요소들, 불필요하게 길게 작성하는 요소들을 정리해주는 플러그인이다. 밑 예시를 살펴보자.
결과는 다음과 같이 나온다. 다음과 같이 css를 압축시켜 파일의 크기를 줄이는데 큰 도움을 준다.
- Oldie
이름에서 느껴지는 것처럼 Oldie는 IE8 이하의 브라우저에서 작동하지 않는 css 요소들을 변경해주는 플러그인이다. calc, media, :root, rgba 등 IE8에서 사용할 수 없는 요소들을 변경해준다.
마치면서
마크업을 직접 작성해야 하는 사람이라면 별다른 설정 없이 놓칠 수 있는 여러 부분들을 자동으로 교정해주는 PostCSS를 사용하는 것이 좋다고 생각한다. 아직 모든 플러그인을 보지 못했지만 자동으로 일을 줄여주는 플러그인이 많이 있으니 적절히 선택해서 쓴다면 큰 효율을 얻을 수 있을 것이다.
참고한 글
- https://github.com/postcss/postcss
- https://www.smashingmagazine.com/2015/12/introduction-to-postcss/
- https://medium.com/@FourwingsY/webpack-postcss-설정하기-34f9c486093a
- https://webpack.js.org/loaders/postcss-loader
- https://github.com/michael-ciniawsky/postcss-load-config
- https://velog.io/@leejh3224/Postcss-preset-env-Use-tomorrows-CSS-today