postcss에 대한 작은 지식들 (feat. vendor prefix)

dante Yoon·2021년 12월 14일
2
post-thumbnail

post-processing CSS

css는 웹 표준이 정해지지 않아 브라우저마다 지원하는 범위가 각 속성들마다 다르다.

CSS vender prefix란?

vender prefix는 css 문법에만 국한되어 사용되는 용어는 아니며, 사전적 의미로는 css 속성, 자바스크립트 api들 중 프로덕션에 쓰일 경우 표준화된 다른 api들과 같이 쓰임으로 혼돈이 오는 것을 방지하기 위해 구문의 어두에 붙이는 기호법이다. 개발자가 이 prefix를 쓰기 싫다면, 해당 문법이 완벽하게 표준화될 때까지는 해당 기능을 사용하면 안된다.

Can I Use?

css vendor prefix에 대해 이야기를 해보면, IE는 버전 10미만 까지는 user-select 속성을 지원하지 않기 떄문에 이 실험적인 속성을 IE 11버전 이상부터는 사용하고 싶다면, IE에서 사용해야 하는 css vendor prefix인 -moz-를 붙여 아래와 같이 사용해야 한다.

-moz-user-select: none;

mdn 문서를 보면 조금 더 잘 와닿는다.
문서에 따르면 -x- 기호 표시는 vendor-prefix이며
아래 그림에서 user-select의 경우 IE 10버전 이상부터는 -x- 표시와 함께 가능하다고 나와있다. 즉, IE 10 이상 부터는 -moz-user-select 표시와 함께 사용이 가능하다는 설명이다.

vendor prefix와 표준 문법이 함께 쓰이는 경우에는 헷갈릴 수 있어 다음과 같이 TCPSCHOOL.com에서 제공하는 예제 코드를 가져온다.

<style>

    .button {

        background: red;          <!-- gradient 속성을 지원하지 않는 모든 브라우저를 위한 코드 -->

        background: -webkit-linear-gradient(red, yellow); <!-- 크롬과 사파리 4.0 이상을 위한 코드 -->

        background: -moz-linear-gradient(red, yellow);    <!-- 파이어폭스 3.6 이상을 위한 코드 -->

        background: -ms-linear-gradient(red, yellow);     <!-- 익스플로러 10.0 이상을 위한 코드 -->

        background: -o-linear-gradient(red, yellow);      <!-- 오페라 10.0 이상을 위한 코드 -->

        background: linear-gradient(red, yellow);         <!-- CSS 표준 문법 코드 -->

    }

</style>

즉, 위의 코드에서 linear-gradient 속성을 지원하는 곳에서만 적용하고 싶은 경우, 위와 같이 linear-gradient를 지원하지 않는 브라우저 또한 폴백 스타일을 제공하기 위해서 다음과 같이 한다.

1.background: red;를 제일 먼저 작성한 후,
2.vendor-prefix를 이용해 작성하고
3.제일 마지막에 CSS 표준 문법 코드를 작성해야 한다.

vendor-prefix를 코드를 작성하는 사람이 일일이 순서와 기호를 신경쓰며 적는 것은 매우 고되고 유지보수성에 좋지 않은 영향을 가져다줄 여지가 있다. 이를 해결하는 여러 방법 중 한 가지로 autoprefixer를 이용하는 것이다.

autoprefixer는 all, break, custom, media query range와 같은 속성들을 최대한 많은 브라우저가 지원할 수 있게끔 자동으로 폴리필 해주는 라이브러리다.

Webpack을 이용해서 autoprefixer 기능을 사용하려고 할 때

CRA(Create-React-App) 환경에서는 추가 설정 없이도 autoprefixer를 자동으로 사용한다. 웹팩을 이용해 수동으로 autoprefixer 기능을 제공하기 위해서는 설정 파일에서 postcss-loader를 사용해야 한다.

다른 사람이 이미 구성해 놓은 웹팩 설정을 사용하는 것에 익숙하다면, postcss-loader 설정에 대해 충분히 살펴보지 못했을 수 있다. 또한 누구한테 물어보기도 조금 애매한 부분이라는 점에 공감하는 사람이 많을 것 같다. 내 케이스는 아니지만 같이 프로젝트를 진행하는 팀이 조금 냉정한 분위기라면 문서 링크 하나 던져주고 이거 보세요 했을 수도..

웹팩에서 postcss-loader를 설정할 때는 두가지 방법이 있다. 참고로 아래 예제 코드들은 웹팩 문서에서 또한 확인할 수 있다.

설정 코드들에 많은 괄호들이 있어 가독성이 좋지 않으나, 다음처럼 생각해보자.
PostCSS는 스타일링 파일들을 JS 플러그인들을 이용해 린팅하거나, vendor prefix를 붙여주는 기능등을 해주는 역할을 한다.
즉, 앞서 살펴본 autoprefixer는 PostCSS에서 사용하는 여러 플러그인 중 가장 범용적으로 사용되는 JS 플러그인이고, 아래와 같은 문법을 이용해 postcss-loader가 postCSS에서 사용될 플러그인들을 설정해준다.

[정리] 웹팩에서 postCSS 기능을 이용해 스타일링을 린팅, autoprefix 하려면 postcss-loader를 이용해 설정해야 한다. postcss-loader가 웹팩에서 postCSS를 사용할 수 있게 해준다. 우리는 이 설정을 webpack.config.js 에서 하거나 postcss-loader에서 사용할 수 있다.

위의 설명을 먼저 읽어두고 아래 코드를 마주하면 위화감이 조금 덜하지 않을까?

(postcss-preset-env, postcss-short는 postcss의 default plugin이 아니므로 패키지 매니저를 사용해 수동으로 설치해줘야 한다._)

1. webpack.config.js 내부에서 postcss-loader를 설정한다.

먼저 webpack.config.js 내부에서 설정하는 경우를 살펴보자.

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  "postcss-preset-env",
                  ["postcss-short", { prefix: "x" }],
                ],
              },
            },
          },
        ],
      },
    ],
  },
};

style-loader, css-loader와 다르게 postcss-loader의 경우 postcssOptions 키 값에 plugins를 키값으로 가지는 객체를 value로 매핑해주고 있다.
plugins의 배열 안에는 string, 혹은 배열이 들어갈 수 있는데, 각 플러그인 마다 디폴트 옵션이 있다. 추가 설정을 하지 않으려면 postcss-preset-env 와 같이 설정한다. autoprefixer는 postcss-preset-env의 디폴트 옵션에 속한다.

postcss-short 플러그인의 경우에는 prefix 옵션을 설정하기 위해 객체를 배열안에 같이 포함했다.

postcss-preset-env의 세부 옵션은 문서에서 확인할 수 있다.

2.postcss.config.js 파일에서 플러그인을 설정한다.

설정 파일을 다른 곳에 별도로 만들 수 있다.
이 방법을 사용할 경우, webpack.config.js가 조금 더 간소화 됨을 아래에서 확인할 수 있다.

// postcss.config.js
module.exports = {
  plugins: [
    // Plugins for PostCSS
    ["postcss-short", { prefix: "x" }],
    "postcss-preset-env",
  ],
};

//webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader", "postcss-loader"],
      },
    ],
  },
};

commonJS 방식을 이용해 객체를 exports 했으나, 다음처럼 함수를 정의할 수도 있다.

1. webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.(css|sss)$/i,
        loader: "postcss-loader",
        options: {
          postcssOptions: (loaderContext) => {
            if (/\.sss$/.test(loaderContext.resourcePath)) {
              return {
                parser: "sugarss",
                plugins: [
                  ["postcss-short", { prefix: "x" }],
                  "postcss-preset-env",
                ],
              };
            }

            return {
              plugins: [
                ["postcss-short", { prefix: "x" }],
                "postcss-preset-env",
              ],
            };
          },
        },
      },
    ],
  },
};
2. postcss.config.js
module.exports = (api) => {
  // `api.file` - path to the file
  // `api.mode` - `mode` value of webpack, please read https://webpack.js.org/configuration/mode/
  // `api.webpackLoaderContext` - loader context for complex use cases
  // `api.env` - alias `api.mode` for compatibility with `postcss-cli`
  // `api.options` - the `postcssOptions` options

  if (/\.sss$/.test(api.file)) {
    return {
      // You can specify any options from https://postcss.org/api/#processoptions here
      parser: "sugarss",
      plugins: [
        // Plugins for PostCSS
        ["postcss-short", { prefix: "x" }],
        "postcss-preset-env",
      ],
    };
  }

  return {
    // You can specify any options from https://postcss.org/api/#processoptions here
    plugins: [
      // Plugins for PostCSS
      ["postcss-short", { prefix: "x" }],
      "postcss-preset-env",
    ],
  };
};

본 글이 postcss를 학습하는데 어려움을 겪는 사람들에게 도움이 되었으면 좋겠다.

reference
https://webpack.js.org/loaders/postcss-loader/#config
https://www.npmjs.com/package/postcss-loader
https://yamoo9.gitbook.io/webpack/webpack/webpack-loaders/postcss

profile
성장을 향한 작은 몸부림의 흔적들

0개의 댓글