CSS, ::before, ::after 간단하게 알아보기

가상 요소(pseudo element) ::before, ::after의 역할

pseudo(슈도)는 [가짜의, 허위의]라는 뜻을 갖고 있습니다.

그렇다면 이 가상 요소가 존재하는 의미는 무엇일까요?

가장 큰 목적은 HTML에 존재하지 않는 요소를 CSS가 임의로 생성해서 스타일링하는 것입니다.

모양은 ::before 또는 ::after이며, 콜론이 두 개(!)가 붙는 것이 가상 요소, 콜론 하나가 가상 클래스입니다(최신 명세).

before와 after의 의미에서 알 수 있듯이 요소의 앞과 뒤에 가상 요소를 생성하여 HTML에 존재하지 않는 요소를 CSS로 생성합니다.

예를 들면 다음과 같습니다.

<h3> - 오늘 할 일</h3> 

위 태그는 다음과 같은 화면을 렌더링합니다.

텍스트에 ‘-‘가 포함되어 있으므로 마우스로 드래그하면 ‘-‘도 함께 텍스트로 선택이 됩니다.

그러나 가상 요소를 사용하면 다음과 같습니다.

‘-‘는 텍스트가 아닌 가상 요소에서 다루고 있으므로 텍스트로 선택되지 않습니다.

// css
.list::before{
  content:'-'
}


// html
<h3 class="list">오늘 할 일</h3>

‘-‘가 h3 태그에는 텍스트로 존재하지 않지만 ::before를 통해 content로 추가해 주었으므로 외형은 위와 같지만 속은 다른 방식이 됩니다.

이 가상 요소를 사용하면 세부적인 스타일링이 가능해집니다.

// css
.list::before{
  content:'';
  display:inline-block;
  width:20px;
  height:20px;
  background:gold;
}

.list::after{
  content:'😋'
}


// html
<h3 class="list">
 오늘 할 일
</h3>

<h3 class="list">
내일 할 일
</h3>

before로 요소의 앞, after로 요소의 뒤를 설정했으며 content에는 문자 이외에도 이모지나 이미지(url(주소)) 등을 사용할 수도 있습니다.

이외에도 ::first-line, ::selection, ::placeholder 등이 있습니다.

추가로 form과 이미지에는 가상 요소가 적용되지 않습니다.

CSS, 알면 쉬운 display 속성(inline, flex, …others)

inline, block, inline-block, flex, inline-flex, grid, inline-grid, none

display는 요소를 보여주고 숨기거나 위치를 설정하기 위한 옵션으로, display만 잘 알아도 레이아웃의 많은 부분을 해결할 수 있습니다.

이번 포스팅에서 display의 속성인 inline, flex, inline-flex, block, inline-block, grid, inline-grid, none의 구현을 통해 각각의 표시 방식을 알아보도록 하겠습니다.

알아보기 편하도록 배경은 블랙, 요소는 각각 레드, 오렌지, 그린으로 표현하겠습니다.

inline : inline으로 표시(width는 요소 크기)
block : block으로 표시
inline-block : inline + block으로 표시
flex : 자식 요소를 모두 inline-block으로 설정
inline-flex : inline + flex(전체 width는 자식 width의 합)
grid : flex처럼 한 방향이 아닌 가로, 세로로 설정 가능한 레이아웃
inline-grid : inline + grid(전체 width는 자식 width의 합)
none : 표시하지 않음(공간을 차지하지 않음)


줄바꿈 없이 태그를 표시하는 요소를 inline 요소, 태그마다 줄바꿈이 되는 요소를 block 요소라고 합니다.

대표적인 inline 요소는 <span>, <a> 등이 있으며, block 요소는 <div>,<p>,<h1>,<h2> 등이 있습니다.

먼저 아무 속성도 설정하지 않은 div를 확인해 보겠습니다.

.setContainer{
  background-color:black;
}

.setOne{
  background-color: red;
}

.setTwo{
  background-color: orange;
  width:95%;
}

.setThree{
  background-color: green;
  width:90%;
}

<div class='setContainer'>
  <div class='setOne'>
    red
  </div>
  <div class='setTwo'>
    org
  </div>
  <div class='setThree'>
    grn
  </div>
</div>

div의 default 설정은 width 100%입니다.

기본 설정을 확인하기 위해 setTwo와 setThree에 width를 설정한 결과입니다.

먼저 display의 inline 속성을 확인해보죠.


1. inline

위 속성은 말 그대로 요소를 일렬로 늘어선 방식으로 표시하며 줄바꿈을 하지 않습니다.

각 요소마다 설정하며 width는 자동으로 크기에 맞게 변형됩니다.

.setContainer{
  background-color:black;
  display:inline;
}
.setOne{
  background-color: red;
  display:inline;
}
.setTwo{
  background-color: orange;
  display:inline;
}
.setThree{
  background-color: green;
  display:inline;
}

<div class='setContainer'>
  <div class='setOne'>
    red
  </div>
  <div class='setTwo'>
    org
  </div>
  <div class='setThree'>
    grn
  </div>
</div>

inline은 위와 같이 문자열처럼 일렬로 늘어선 상태로 표시됩니다.


2. block

block은 inline 요소를 block으로 표시합니다.

block 요소 div 대신 inline 요소 span을 사용하면 다음과 같은데요.

위에서 div에 display:inline을 설정한 것과 같은 모양입니다.

그러므로 span에 display:block을 설정하면 반대로 div를 사용한 것과 같은 결과가 나오는 것을 알 수 있습니다.

.setContainer{
  background-color:black;
}
.setOne{
  background-color: red;
  display:block;
}
.setTwo{
  background-color: orange;
  display:block;
}
.setThree{
  background-color: green;
  display:block;
}

<div class='setContainer'>
  <span class='setOne'>red</span>
  <span class='setTwo'>org</span>
  <span class='setThree'>grn</span>
</div>

block 속성은 inline 요소를 block 요소처럼 표현하는 것을 알 수 있습니다.


3. inline-block

그렇다면 inline-block은 언제 사용할까요?

display:block이 필요하지만 표시는 inline으로 표시를 하고 싶은 상황입니다.

그러면 그게 그냥 span의 default 아닌가라고 생각할 수도 있지만 span에는 width, height 등 속성이 적용되지 않기 때문에 block으로 설정을 해야 합니다.

위의 코드에서 첫 번째 요소에 width:300px, height:200px를 설정하면 다음 그림과 같은 모습이 됩니다.

위 요소를 inline으로 설정하기 위해 inline-block를 사용할 수 있습니다.

.setContainer{
  background-color:black;
}
.setOne{
  background-color: red;
  display:inline-block;
  width:300px;
  height:200px;
}
.setTwo{
  background-color: orange;
  display:inline-block;
}
.setThree{
  background-color: green;
  display:inline-block;
}

<div class='setContainer'>
  <span class='setOne'>red</span>
  <span class='setTwo'>org</span>
  <span class='setThree'>grn</span>
</div>

div를 사용해 위와 같이 나타내려면 어떻게 해야 할까요?

.setContainer{
  background-color:black;
}
.setOne{
  background-color: red;
  display:inline-block;
  width:300px;
  height:200px;
}
.setTwo{
  background-color: orange;
  display:inline;
}
.setThree{
  background-color: green;
display:inline;
}

<div class='setContainer'>
  <div class='setOne'>
    red
  </div>
  <div class='setTwo'>
    org
  </div>
  <div class='setThree'>
    grn
  </div>
</div>

위와 같이 사용하면 됩니다.

만약 위와 같이 사각형 사이 사이에 빈공간이 들어가는 경우가 있다면 <div> 태그 사이의 띄워쓰기나 줄바꿈을 확인해봐야 합니다.

보기에는 안좋지만 다음과 같이 태그 사이를 모두 붙여쓰면 공백이 발생하는 것을 제거할 수 있습니다.

<div class='setContainer'><div class='setOne'>red</div><div class='setTwo'>org</div><div class='setThree'>grn</div></div>

4. flex

flex는 새로운 속성 중 하나로 부모 요소에서만 설정을 합니다.

display:flex를 설정하면 모든 자식 요소에 display:inline-block을 설정한 것과 같은 효과를 줍니다.

따라서 모든 자식 요소는 display를 설정할 필요 없이 width, height 등의 속성이 사용 가능합니다.

.setContainer{
  background-color:black;
  display:flex;  
}
.setOne{
  background-color: red;
}
.setTwo{
  background-color: orange;
  width:200px;
}
.setThree{
  background-color: green;
}

<div class='setContainer'>
  <div class='setOne'>
    red
  </div>
  <div class='setTwo'>
    org
  </div>
  <div class='setThree'>
    grn
  </div>
</div>

개별 요소에 모두 display를 설정할 필요 없이 부모 요소에서만 편하게 설정이 가능합니다.

만약 자식 요소를 가운데 정렬하고 싶으면 부모 요소에서 justify-content:center;를 사용하면 됩니다.


5. inline-flex

flex는 이미 inline-block의 기능을 갖고 있는데 그럼 inline-flex의 기능 무엇일까요?

바로 inline 특징 중 하나인 자동 크기 조절입니다.

inline-flex는 자식 요소를 합친 크기 만큼만 크기를 설정하므로 width는 100%가 아닌 자식 크기의 합입니다.

flex의 결과와 비교해보면 알 수 있듯이 부모 요소를 의미하는 블랙이 공간을 차지하고 있지 않습니다.


6. grid, inline-grid

이 grid는 무엇일까요?

그리드는 flex처럼 가로나 세로 한 방향으로만 레이아웃을 설정하는 것이 아니라 가로, 세로 두 방향 모두 설정할 수 있는 속성입니다.

grid 역시 부모 요소에서 설정을 하며 자식 요소를 block으로 표현합니다.

다양한 속성을 통해 레이아웃을 구성하는데 효과적이지만 내용이 많아 다른 포스팅을 통해 좀 더 알아봐야 할 필요성이 있을 것 같습니다.

.setContainer{
  background-color:black;
  display:grid;  
  grid-template-columns: 100px 100px 100px;
}
.setOne{
  background-color: red;
}
.setTwo{
  background-color: orange;
}
.setThree{
  background-color: green;
}

<div class='setContainer'>
  <div class='setOne'>
    red
  </div>
  <div class='setTwo'>
    org
  </div>
  <div class='setThree'>
    grn
  </div>
</div>

inline-grid 역시 inline-flex 속성과 마찬가지로 width를 자식 요소에 맞게 조절하는 기능을 합니다.


7. none

none은 해당 요소를 표시하지 않으며 공간도 차지하지 않는 방식입니다.

.setContainer{
  background-color:black;
}

.setOne{
  background-color: red;
  display:none;
}

.setTwo{
  background-color: orange;
}

.setThree{
  background-color: green;
}


<div class='setContainer'>
  <div class='setOne'>
    red
  </div>
  <div class='setTwo'>
    org
  </div>
  <div class='setThree'>
    grn
  </div>
</div>

이렇게 없는 놈 취급을 합니다.

이와 반대되는 속성이 visibility로 이는 공간은 차지하되 표시만 하지 않는 속성입니다.

visibility, display 사용 관련 포스트

display:none을 visibility:hidden으로 변경한 결과입니다.

있는데 없는 척을 합니다.

물론 visibility도 공간만 차지할 뿐 할 수 있는 일은 없습니다.



CSS의 기본이지만 모든 기능을 다 이해하고 사용하기까지는 어느 정도의 시간과 경험이 필요한 것 같습니다. 무작정 외우기보다는 사용하면서 답답함이 쌓였을 떄 한번씩 소화제 느낌으로 설명을 삼켜주면 조금 더 와닿는 설명이 되지 않나 싶습니다..🧔

CSS transition, 작동 원리 이해하기(왜 작동을 안할까?)

transition의 작동원리와 transition 대체할 수 있는 방법

transition은 애니메이션 효과를 주는 CSS입니다.

transition 하나만으로도 투박한 느낌을 지우고 부드러운 느낌을 줄 수 있는데요.

메뉴가 부드럽게 열리고 닫히거나 화면에 fade-in 효과 등을 줄 수 있습니다.

CSS의 대표적인 애니메이션 처리는 transition와 animation이 있는데요.

transition은 변경이 발생하는 순간 작동하고, animation은 transition보다 더 자유롭고 다양하게 사용이 가능한 친구입니다.

그럼 transition을 작성하는 코드부터 확인해 보겠습니다.

1. transition 사용하기

.setBox{
  background-color:pink;
  width:200px;
  height:200px;
  transition:all 1000ms linear 500ms;
}

위와 같은 방식으로 사용하며, 한 줄 표기의 의미는 다음과 같습니다.

transition: property duration timing delay;

property : color, background-color, border, position, all 등의 속성

duration : 완료까지 걸리는 시간. ms(밀리초) 또는 s(초)로 설정

timing : linear(동일), ease(느림->빠름->느림), ease-in(느림->빠름), ease-out(빠름->느림)

delay : 딜레이 시간(ms 또는 s로 설정)

물론 property나 delay 는 생략도 가능합니다.

이를 풀어 쓰면 다음과 같이 작성할 수 있습니다.

transition-property : property
transition-duration : duration
transition-timing-function : timing
transition-delay: delay

transition을 사용해 마우스를 올리면(hover) 박스가 부드럽게 커졌다가 줄어드는 코드를 확인해 보겠습니다.

.setBox{
  background-color:pink;
  width:100px;
  height:50px;
  transition:all 1000ms linear 500ms;
}

.setBox:hover{
  background-color:gold;
  width:200px;
  height:100px;
  transition:all 300ms ease;
}

<div class='setBox'></div>

박스가 커질 때는 .setBox:hover{}의 transition 설정에 따라 300ms, 줄어들 때는 .setBox{}의 transition 설정에 따라 1000ms동안 움직입니다.

그럼 이제는 요소 숨기기&표시하기 기능을 확인해 보겠습니다.

.setBox{
  background-color:gray;
  color:white;
  width:100px;
  height:50px;
  text-align:center;
  line-height:50px;
}
.showMenu{
  visibility:hidden;
  height:150px;
  width:100px;
  background-color:lightgray;
  opacity:0;
  color:black;
  border-radius:5px;
  transition:linear 500ms;
}
.setBox:hover .showMenu{
  visibility:visible;
  transition:linear 500ms;
  opacity:1;
}

<div class='setBox'>MENU
    <div class='showMenu'>
        <div class='menu'>
          메뉴 A
        </div>
        <div class='menu'>
          메뉴 B
        </div>
        <div class='menu'>
          메뉴 C
        </div>
    </div>
</div>

위 코드의 실행 결과는 아래와 같습니다.

마우스를 올리면 숨겨둔 div를 표시하거나 숨기면서 transition이 작동하는 것을 볼 수 있습니다.

위 코드에서 visibility가 아닌 display를 사용하면 결과는 어떨까요?

display를 사용하면 transition이 작동하지 않는 것을 볼 수 있습니다.

이유는 바로 display와 visiblility의 작동 방식에 차이가 있습니다.

transition은 위에서 이야기한 것처럼 변경이 발생하는 순간 작동합니다.

예를 들어 A 모양에서 B 모양으로 변경될 때 작동을 하는데요.

visibility는 공간은 그대로 두고 설정에 따라 요소를 숨기거나 나타내므로 A에서 B로 변경을 적용할 수 있습니다.

다음 그림과 같은 느낌입니다.


2. transition 작동하지 않는 이유

그렇다면 display가 작동하지 않는 이유도 추측할 수 있습니다.

display:none은 요소의 표시 뿐만 아니라 표소가 있는 공간도 비워버리는 설정입니다.

따라서 ‘A모양 -> B모양’으로의 변형이 아니라 ‘없음 -> B모양’ 이 되므로 transition이 작동하지 않는 것입니다.

그러므로 transition은 ‘모양의 변형‘만 기억하면 됩니다.

그렇다면 같은 효과를 내는 animation은 어떻게 사용할까요?

코드만 봐도 이해하기 쉬운 구조이므로 코드로 확인해 보겠습니다.

.setBox:hover .showMenu{
  visibility:visible;
  animation:setMotion 3s;
}
@keyframes setMotion{
  0%{
      opacity:0;
    }
  100%{
      opacity:1;
    }
}


CSS3는 아주 다재다능한 친구라 기존에는 jquery를 사용해 복잡하게 구현할 수 있던 애니메이션 효과들을 이제는 한 행의 코드만으로 해결할 수 있게 되면서 CSS3는 조금만 배워 둬도 아주 유용하게 사용할 수 있는 친구가 되었네요. CSS에 조금 더 관심을 갖고 포스팅을 늘려 가야겠습니다.

CSS Combinators, make your CSS works easier (+,~, ,>)

Four combinators [Adjacent Sibling(+), General Sibling(~), Child(>), Descendant( )]

When set CSS Styles, below syntax is a basic.

h1 {
  color:#FFFF11;
  background: #000000;
}

.subTitle {
  font-size:13px;
  color:#FFFFFF;
  font-family:inherit;
}

#timeLine {
  background:gray;
}

But when you want to set Styles to a specific tag, using combinators is a smart selection.

combinators are mixed Styles. like ‘div + h1’ or ‘div > span’.

Any tags are mixable and there are four combinator types.

  • Adjacent Sibling (+)
  • General Sibling (~)
  • Child (>)
  • Descendant ( space )

1. Adjacent Sibling (+)

Adjacent Sibling uses + mark when specifies one element right after designated element.

h1 + p {
  color:orange;
}

Result is shown below.

<div>
  <h1>I'm h1 tag</h1>
  <p>I'm orange</p>
  <h2>I'm h2 tag</h2>
  <p>I'm a second p tag</p>
  <h1>I'm h1 tag again</h1>
  <p>I'm orange too</p>
<div>

There are two conditions for adjacent sibling.

Element should share the same parent and second element has to come only if right after first element.

In the above HTML result, there are three <p> tag lines but only two lines are matched to the condition.

Therefore only two matched elements are working as mentioned.

2. General Sibling (~)

General Sibling uses ~ mark when specifies elements come after designated element.

h1 ~ p {
  color:orange;
}

Result is shown below.

<div>
  <h1>I'm h1 tag</h1>
  <p>I'm orange</p>
  <h2>I'm h2 tag</h2>
  <p>I'm orange too</p>
<div>

There are two conditions for general sibling.

Element should share the same parent and second element has to come after first element.

In the above HTML result, every <p> tag after <h1>tag is working.

3. Child (>)

Use > marks when express child elements.

div > p {
  color:orange;
}

Result is shown below.

<div>
  <h1>I'm just h1 tag</h1>
  <p> I'm colored orange</p>
  <span>
    <p>I'm not the one</p>
  </span>
  <p> I also am colored orange</p>
</div>

Second element has to be a direct child of first element.

In the above HTML result, only two direct child lines are working.

Fifth line is not working because its position is parent-child-child.

4. Descendant

Use space when express descendant elements.

div p {
  color:orange;
}

Result is shown below.

<div>
  <h1>I'm just h1 tag</h1>
  <p> I'm colored orange</p>
  <span>
    <p>Count me in</p>
  </span>
  <p> I also am colored orange</p>
</div>

As long as second element is a descendant of the first element, every matched line is working.


Combinators are easy and simple for efficient CSS work.

I hope this post is helpful to your CSS design.