본문 바로가기

프로그래밍

[HTML/CSS]여러 클래스 중 하나의 클래스만 선택하여 속성주기

[HTML/CSS]여러 클래스 중 하나의 클래스만 선택하여 속성주기

웹페이지를 만들 때 class나 id 또는 속성으로 구분하는 선택자를 많이 이용합니다.
그 중 class를 다룰 때 애매한 것이 몇 가지 있었는데, 최근에야 삽질을 멈추고 
답을 찾아 글을 남겨봅니다.


대강 이런 식으로 선언을 했습니다.
아주 간단하게 편성했습니다. 
두개의 div하위에 input과 span을 하나씩 자식으로 두고 있는데,
둘다 같은 속성을 주어야 할 것이 있어서 input.bigger를 통해 class bigger에게 스타일을 부여했습니다.

이렇게만 클래스를 사용한다면 얼마나 좋겠냐만은 맘같지 않은 상황이 생기기 마련입니다.
두번재 DIV만 margin-top을 주고 싶습니다.

그렇다면 방법이 몇 가지 있습니다.

1. 해당 div만 유일한 속성을 부여하여 선택후 style 태그에서 스타일을 부여한다.



2. 해당 태그에 style 속성을 줘서 태그 자체에서 스타일을 부여한다.


3. 여러 div중 하나만 선택을 하고 스타일을 부여한다.

bold를 준 이유는 제가 하고자 하는 것은 이것이기 때문입니다.

위에 방법은 간단하지만 불편합니다.

예를 들어 server-side에서 가져오는 결과물들을 화면에 출력하게 되었을 때, 
어느 하나에만 속성을 다르게 주기 위해서는 if문이라던지 삼항연산자라던지
어떤 상태에 도달했을 때 이를 다르게 조작하는 부분이 생기게 됩니다.

때문에 위에 두 방식 보다는 공통된 속성을 가진 요소들을 분리하는 것이 아닌
유지한 채로 스타일만 부여해주는 것이 최선이라고 생각했습니다.

그래서 찾은 것이 바로 css3선택자 nth-of-type()입니다.

호환성은 


이곳을 참고하시기 바랍니다.

:nth-of-type()은 :(콜론)앞에 있는 선택자와 같은 대상중에서 ()안에 있는 대상을 선택합니다.
index는 1-base이고, 다양한 방법으로 응용이 가능합니다.
2n+1라던지, 3n*1라던지 수열을 이용하는 것입니다. 
수열 사용시 n은 0-base입니다.

바로 선택해 보도록 하죠.


이대로 작성하여도 아까와 같이 적용이 됩니다.
그렇다면 이번엔 수열을 테스트해보겠습니다.


이 역시 마찬가지로 적용되었습니다. 
div같은 태그 뿐만 아니라 클래스 등 여러 요소가 선택되는 경우도 사용할 수 있습니다.


클래스 bigger에 대해서 같은 선언을 하여서 사용했습니다.
아무효과가 없지요?
단순하게 선택자에서 선택되어진 요소들 중에서 선택하는 것이 아니라,
같은 depth에 위치한 선택되어진 요소들로 부터 수를 세어 선택합니다.

무슷 뜻인가 하면,
지금 .bigger:nth-of-type(2)라고 선언했는데, 이 뜻이 class가 bigger인 것의 두번째를 뜻하는 것이 아니라,
bigger라는 class를 가진 같은 depth의 요소 중 2번째를 뜻하는 것입니다.

때문에 아무것도 선택되지 않는 것이지요. 
처음 소스에서 bigger class는 input에만 부여되었는데, 같은 depth에 있는 input은 한개 뿐이기 때문에,
두번째가 없는 것입니다. 
그럼 index를 2에서 1로 바꾸겠습니다. 


이런식으로 .bigger라는 클래스를 가진 input이 선택되었습니다. 같은 depth 오로지 bigger를 클래스로 가진 태그는
하나 뿐이기 때문입니다.

그렇다면 두번째에 있는 div의 클래스 bigger에게만 영향을 주려면 어떻게 해야할까?
처음에 했던 div:nth-of-type(2)으로 선택후 거기에 자식을 선택하도록 조합하면 됩니다.

div:nth-of-type(2) > input 또는 
div:nth-of-type(2) > .bigger

결과보도록 하지요.



햇갈리는 부분이 있지만 잘만 사용하면, 코드 몇줄을 줄일 수 있는 선택자입니다.
ie9버전 부터 호환이라는 점이 마음에 걸리긴 합니다만...
상관없어 진다면 정말 많이 사용하게 될 것 같습니다.

이방법을 대체할 방법이 바로 +와 :first-child인데 이렇게 하면 ie7까지는 커버가 됩니다.
사용방법은 
div:nth-of-type(2) 를 div:first-child + div 변경

하면 됩니다. div선택자중 첫번째에서 그 다음에 위치한 div를 찾아 선택합니다.
혹시나 이상하게 동작하지 않을까라는 걱정에 이번에는 div 하위에 div를 하나 더 넣어서 테스트 하겠습니다.

<html>
<head>
<title>CSS에서 class선택자 사용하기</title>
<style>

div {width:200px;height:200px;border:1px solid #000;}
input.bigger{width:100%;}
div:first-child+div > .bigger{margin-top:30px;height:50px;}

</style>

</head>
<body>
<div>
     <div>
          <input type='button' class='bigger'>
          <span>1. 테스트중입니다</span>
     </div>
</div>
<div>
     <div>
          <input type='button' class='bigger'>
          <span>2. 테스트중입니다</span>
     <div>
</div>
</body>
</html>

이렇게 소스를 바꿔두고 실행하겠습니다. 
아마도 아무 일도 안일어날겁니다. 
왜냐면 div가 하나 더 생겼으니 한 depth 더들어가야 bigger클래스에 접근할 수 있겠습니다. 
때문에 두 가지 방법중 하나로 바꿔야 겠지요.

1. div:first-child+div .bigger
2. div:first-child+div >div >.bigger

지금이야 결과가 같지만, 자식이 많은 부모라면 혼란이 올수 있으니 자식을 콕콕 찍어주는 > 로 바꾸는게 좋겠네요.


이런 식으로 나타나게 됩니다. 
얼른 ie 6~8 이 없어지길 기원합니다. ㅠㅠ