장용석 블로그
4 min read
CSS로 논리게이트 만들기 - if() 함수를 활용하여

CSS conditionals with the new if() function  |  Blog  |  Chrome for Developers

Learn about the new CSS if function, which enables a cleaner developer interface for dynamic styles like style queries and media queries.

https://developer.chrome.com/blog/if-article?hl=en
CSS conditionals with the new if() function  |  Blog  |  Chrome for Developers

새로나온 CSS if() 함수

최근에 CSS에 새롭게 if() 함수가 추가되었다.
CSS 에서 조건문을 사용할 수 있게 된 것이다.
얼마나 구미가 당기는 기능인가!

CSS Logic Gates

기존에도 선택자들을 이용하면 사실상 조건을 다룰 수는 있다고 생각하지만, 이렇게 직접적으로 조건을 다룰 수 있다는 것은 많은 가능성을 열어준다.

이를 통해서 CSS로 논리 게이트도 표현 해볼 수 있지 않을까?

먼저 이전에 CSS 를 통해서 논리 게이트를 만든다고 생각해보자. 어떻게 만들 수 있을까?
선택자들을 이용해서 만들었을 것이다. :has() 선택자와 :not() 선택자를 이용해서 말이다. 대략적으로 아래와 같은 형태로 만들 수 있을 것이다. 혹은 calc()을 이용해서 묘수를 찾을 수도 있겠다.
AND 게이트를 예로 들면 아래와 같은 형태가 될 것이다.

/* :has() */

.and {
  --out: 0;
}

.and:has(.a, .b) {
  --out: 1;
}

/* calc() */

.and {
  --out: calc(var(--a) * var(--b));
}

그나마 calc()을 이용한 방법이 간결해 보인다.
그치만 if() 함수가 추가되면서 이제는 훨씬 명시적으로 만들어볼 수 있겠다 싶었다.

기본 단위인 비트 부터 정의해보자. 비트는 변수 --value에 따라 검정, 흰색으로 표현된다.
여기서 처음 if() 함수를 사용해보자.

.bit {
  /* value가 1 이면 검정색, 0 이면 흰색 */
  background: if(style(--value: 1): black; else: white);
}

그 다음 논리 게이트를 구성해보자.
게이트를 부모로 만들고 부모에서 --a, --b 값을 넣어주었다. 그리고 .out 에 결과를 출력해보기로 했다.

<div class="and" style="--a: 1; --b: 1">
  <div class="bit a"></div>
  <div class="bit b"></div>

  <div class="bit out"></div>
</div>

먼저 input 비트(a, b)를 정의해줬다.
각 비트는 상위에서 입력 받은 --a, --b 값을 --value로 지정해서 표현한다

/* 입력 블록들 */
.a {
  --value: var(--a, 0);
}
.b {
  --value: var(--b, 0);
}

이제 출력 비트(.out)를 정의해보자.
AND 게이트이므로, --a--b가 모두 1일 때만 1이 출력되어야 한다.
if() 함수를 사용해서 조건을 정의해보자.

--a가 0이면 바로 평가되어 0을 출력하고,
--b가 0이면 역시 0을 출력한다.
그 외 케이스인 --a--b가 모두 1일 때만 1을 출력하도록 한다.

/* AND Gate */
.and .out {
  --value: if(style(--a: 0): 0; style(--b: 0): 0; else: 1);
}

위와 같이 만들게 되면 아래와 같이 출력된다.
devtool을 통해서 직접 확인해보자.

AND

게이트 모양은 직접 만들어보았다.
이어서 OR, NOT, XOR 게이트도 만들어보자. if()를 통해서 먼저 각 논리 게이트의 동작을 정의해보자.

/* OR Gate */
.or .out {
  --value: if(style(--a: 1): 1; style(--b: 1): 1; else: 0);
}

/* NOT Gate */
.not .out {
  --value: if(style(--a: 1): 0; else: 1);
}

/* XOR Gate */
.xor .out {
  --value: if(
    style(--a: 0): if(style(--b: 1): 1; else: 0);
    style(--a: 1): if(style(--b: 0): 1; else: 0);
    else: 0
  );

화면에 그려보면 아래와 같이 된다.

OR

NOT

XOR

XOR 게이트는 그리기 어려워서 그냥 네모로 퉁쳤다.
이렇게 기본적인 게이트들을 만들어봤는데
그렇다면 조합도 가능할까? 몇가지 이어서 만들어봤다.

출력값 하위에 있는 게이트의 첫번째 input 으로 값을 상속 하도록 처리해봤다\

.out:has(.bit) > .and, .or, .not, .xor {
  --a: var(--value);
}
(a AND b) OR c

NAND (NOT AND)

NOR (NOT OR)

만들고 보니 거꾸로 만들었음을 깨달았다.
돔은 아래로 향하는 트리 구조인데, 게이트는 위로 향하는 트리 구조로 만들어야 했다.
부모가 출력값이 되어야하는데 거꾸로 된것이다. 그렇다 보니 여러 값을 input 으로 받을 수 없다.

하지만 그렇게 되면 자식의 값을 부모가 받아야하는데 조금 복잡해진다. 아마 그러면 변수를 상속받거나 하는 로직쪽이 꼬이게 될거같다…

쨋든…

if 함수가 나온기념으로 논리 게이트를 만들어보았다. 요즘 너무 정신이 없다보니, 써야하는 글들도 밀리고 있다.
이 글은 계획에는 없었지만, 퇴근길에 문득 재밌을 것 같아서 만들어봤다.

이렇게 갑자기 만들어보고 나면 만드는데 에너지를 다써서 글이 두서가 없어지는 듯 싶다.
그치만 그렇게 마무리하지 않게 되면 영영 못 쓸거같아, 글은 미완성으로 마무리 해본다. 나중에 다시 다듬을 지는 모르겠다.

오늘의 노르웨이어 : Det vanskeligste er å komme i gang.(시작하는 것이 가장 어렵다.)

다음에는 if함수를 더 들여다 볼 계획을 세워보며 오늘은 마무리 해본다.

다음에 살펴볼것 : if() 함수란…

CSS Conditional Values Module Level 1

No description available

https://drafts.csswg.org/css-conditional-values-1/#funcdef-if

Intent to Prototype: CSS if() function

No description available

https://groups.google.com/a/chromium.org/g/blink-dev/c/ySEBHgVlhBM

Explainer: CSS if() function - Google Docs

No description available

https://docs.google.com/document/d/1mbHBUR40jUBay7QZxgbjX7qixs5UZXkdL9tVwGvbmt0/edit?tab=t.0#heading=h.xzptrog8pyxf
Explainer: CSS if() function - Google Docs
RSS 구독