#03 CSS 언어란?

Edwin·2023년 1월 25일
post-thumbnail

CSS언어의 등장

이전 글에서 간단하게 언급한 것과 같이 CSS는 HTML을 보다 세련되고 우아하게 만들기 위해서 고안된 언어이다. Cascading Style Sheet의 알파펫 첫자리를 따서 명시되는 CSS는 1994년 하콤 비움 리가 처음 제안함으로 세상에 등장하였다.

CSS로 HTML을 꾸며주기

CSS는 HTML의 태그나 각각에게 부여한 이름들을 선택자라고 부른다. 이러한 선택자를 지정하고 {중괄호} 안에 다양한 꾸미기를 설정함으로 HTML을 보다 세련되고 우아하게 만들어낸다.

  • HTML의 태그로 지정할 때,
a {}
p {}
span {}
  • HTML의 태그의 class 속성으로 지정할 때,
.className {}
  • HTML의 태그의 id 속성으로 지정할 때,
#idname {}

우선순위는 태그 < class속성 < id속성으로 부여된다. 예를 들어 해당 문서 안에 무수히 많은 a태그들이 존재하더라도 class 속성이 부여되었다면, a태그의 css는 무력화되고, class속성이 적용된다. 그러나 그러한 class에 id속성이 존재한다면, class속성의 적용이 무산되고 id속성의 css가 최종적으로 적용된다는 것이다. 이러한 상관관계를 잘 활용하여 코드를 작성하는 것이 중요할 것이다.

CSS선택자이미지 출처

위의 사진에서 볼 수 있듯이 선택자를 호출할 때 보다 구체적으로 명시하여 기록할 수 있는데 예를 들어 지정한 class를 가진 부모태그 내에 있는 특정한 태그(예를들어 a태그)들을 구체적으로 지명하고 싶을 때는 다음과 같이 선택자를 선택하면 된다는 말이다. 또한 동일한 꾸미기 내용을 가진 태그들은 ,(콤마)를 통해서 지정할 수 있다.

.className a {}
td,th {}

이러한 설정은 코드의 효율성을 높이고, 용량을 줄일 수 있기에 활용할 수록, 똑똑한 코드작성이 될 수 있다. 아래의 이미지와 같이 말이다.

CSS의 기록위치

보통 CSS는 HTML의 head태그에 style태그를 지정하고, 그 안에 위와 같이 선택자들을 지정하여 각각의 사례에 따라 꾸미기효과를 지정한다. 그런데 이렇게 사용함에 있어서 고민이 생겨날 것이다. 만약에 HTML문서가 여러 개인데, page1.html, page2.html, page3.html 동일한 CSS효과를 주고 싶다면 방법이 있을까?

물론 방법이 있다. css를 head태그에 style태그에 위치시키는 것이 아니라, 별도의 파일로 만들고 css를 적용하고자 하는 html문서에 link태그로 연결시켜주면 된다.

<link rel="stylesheet" href="파일의경로.css">

그리고 이렇게 작성하는 것에 또다른 효용은 html의 용량이 작아지며, html를 읽어낼 때 지불되는 비용을 감소시킬 수 있다는 점이다. page1.html을 실행할 때, 연결된 css가 한 번 다운받아지면, page2.html, page3.html를 실행할 때 재다운 받는 것이 아니라, 기존에 받은 css를 재활용한다는 측면에서, 비용을 절감할 수 있고, 중복되는 코드를 재입력하지 않아도 된다는 측면에서 효율적이다. 이렇게 별도로 만든 css파일에서는 style태그를 사용할 이유가 없다. 바로 선택자를 지정하고 꾸미기를 설정하면 된다.

HTML 태그가 가지고 있는 display에 대한 이해

CSS를 저정함에 있어서 유의할 점은 태그들이 모두 동일한 속성을 가지고 있지 않다는 말이다. 어떤 태그들은 자신이 가지고 있는 값의 길이와 너비로 공간을 한정한다. 예를 들어 a태그나 span태그, img태그 등은 각자가 가지고 있는 크기만큼만 한정해서 CSS를 적용시킨다. a태그에 단어 하나가 기록되어 있다면, 한 단어에만 CSS가 적용되는 것이다. 반면에 어떤 태그들은 별도로 지정하지 않으면 가로(width)너비 전체의 공간에 CSS를 적용하는 태그들이 있다. 대표적인 것이 div태그와 p태그이다.

이렇게 자신이 가지고 있는 크기만큼을 지정하는 태그들을 inline element 이라고 부르고, 가로너비 전체를 지정하는 태그들을 block level element라고 부른다. 그러나 이러한 요소는 고유한 값일 뿐이고 얼마든지 inline을 block으로, block을 inline으로 변경할 수 있는데, 이는 display의 값을 각각의 요소의 명으로 지정함으로 변경이 가능하다.

공간의 위치설정 및 공간활용1 (margin, padding)

여백에는 두 가지 종류가 있다. 바깥여백(margin)과 안쪽여백(padding)이 그것이다. 바깥여백을 위/오른쪽/아래/왼쪽으로 모두 10px씩 주고 싶다면 아래와 같이 기록하면 된다. 첫번째 코드와 같이 한 번에 기록할 수도 있고, 시계방향에 따라 위/오른쪽/아래/왼쪽을 보다 구체적으로 선택할 수 있다.

선택자 {marging: 10px;
      padding:10px;}
선택자 {marging: 10px 10px 10px 10px;
      padding: 10px 10px 10px 10px;}

그리고 기록할 때 하나의 꾸미기가 끝나면 ;(세미콜론)을 붙여주는 것이 CSS의 문법이니 기억하자.

공간의 위치설정 및 공간활용2 (display)

1) 먼저 문자(inline element)를 정렬하고 싶을 때는 어떻게 할 수 있을까? block element 안에 담겨 있는 문자라면, 그 문자의 왼쪽정렬(첫번째코드), 가운데정렬(두번째코드), 오른쪽정렬(세번째코드), 좌우정렬(네번째코드) 가능하다.

block선택자 {text-align:left;}
block선택자 {text-align:center;}
block선택자 {text-align:rigth;}
block선택자 {text-align:justify;}

영어의 경우, 기본설정으로 단어가 나눠지지 않도록 기본설정이 되어 있지만, 한글은 그렇지 못하다. 그런데 정렬을 하더라도 단어의 의미가 나눠지지 않도록 설정하고 싶을 때는 어떻게 해야할까? 아래의 코드를 설정해주면 된다.

선택자 {word-break: keep-all;}

2) 문자(inline element)를 정렬해 보았다면, block element를 정렬할 수 있는 방법이 있을까? 물론 존재한다. 기본적으로 block element는 가로너비 전체를 사용하기 때문에, 특정한 가로너비를 지정해주어야 한다.

선택자 {width:500px}

만약 웹페이지가 800px이라면, 위의 block element는 300px의 여유공간이 발생될 것이다. 기본적으로 block element는 왼쪽정렬이 되어있다. 이를 가운데정렬, 또는 오른쪽 정렬을 하려면 어떻게 해야할까? CSS에서는 바깥여백을 조절함으로 이를 수행한다.

선택자 {width:500px;margin: 0 auto 0 auto;}

바깥여백의 값을 보면 위와 아래는 0이지만, 오른쪽과 왼쪽은 auto로 되어 있다. 즉 화면의 좌우 끝에서 안쪽으로 같은 힘으로 밀어준다고 생각해보자. 그러면 800px에서 가운데 위치한 500px의 block element를 두고 오른쪽에서 150px이, 왼쪽에서 150px이 밀려와서 멈춰지게 될 것이다. 그렇다면 오른쪽정렬을 어떻게 할까?

선택자 {width:500px;margin-left:auto}

그렇다. 화면의 왼쪽에서만 밀어주면, 500px의 block element가 오른쪽으로 밀려나며 오른쪽에 위치하지 않겠는가! 맞다.

3) 그렇다면 위의 예를 통하여 가운데 정렬된 block element1이 있다고 치자. 그 안에 자녀태그로 block element2가 있다고 할 때, block element2를 가운데 위치하고 싶다면 어떻게 할 수 있을까? 이때 사용되는 것이 display:flex이다. 이는 justify-content와 align-items과 함께 사용된다.

  • block element1 : 500px(w) x 200px(h)
  • block element2 : 300px(w) x 100px(h)
blockElement1 {width:500px; height:200px;margin: 0 auto 0 auto;
			   display:flex; flex-content:center; align-items:center}
blockElement2 {width:300px; height:100px;}

그런데 이런 고민이 생기지 않을까? width는 가운데인데, height는 위쪽에 위치시키고 싶다. 가능하다. align-item를 center에서 flex-start로 바꿔주면 된다.

blockElement1 {width:500px; height:200px;margin: 0 auto 0 auto;
			   display:flex; flex-content:center; align-items:flex-start}
blockElement2 {width:300px; height:100px;}

그렇다면 width는 가운데인데, height는 아래쪽에 위치시키고 싶다. 가능하다. 역시 align-items를 변경해주면 된다.

blockElement1 {width:500px; height:200px;margin: 0 auto 0 auto;
			   display:flex; flex-content:center; align-items:flex-end}
blockElement2 {width:300px; height:100px;}

그렇다면 height는 가운데인데, width는 왼쪽에 위치시키고 싶다. 가능하다. 이때는 justify-content를 변경해주면 된다.

blockElement1 {width:500px; height:200px;margin: 0 auto 0 auto;
			   display:flex; flex-content:flex-start; align-items:center}
blockElement2 {width:300px; height:100px;}

4) 이번에는 block element1 내에 자녀태그로 block element2와 block element3이 있다고 하자.

  • block element1 : 500px(w) x 400px(h)
  • block element2 : 200px(w) x 100px(h)
  • block element3 : 200px(w) x 100px(h)

block element1내에 block element2와 block element3을 행으로 정렬하고 싶다면? 기왕이면 block element1에 정가운데에서 행으로 정렬해보자. 이때는 간단하다. flex-direction을 row로 설졍해주면 된다. 잘보기게 하기 위해서 선과 배경색을 입혔다. 유심히 볼 곳은 코드의 두번째 줄이다.

<div style="width: 500px; height:400px;border: 1px solid black; 
	display: flex; flex-direction: row; justify-content: center; align-items: center;">
  <div style="width: 200px; height:100px;border: 1px solid black; background-color:rgba(255, 0, 0, 0.5);">block element2</div>
  <div style="width: 200px; height:100px;border: 1px solid black; background-color:rgba(255, 166, 0, 0.5);">block element3</div>
</div>

5) block element1내에 block element2와 block element3을 열으로 정렬하고 싶다면? 기왕이면 block element1에 bottom(h)의 right(w)에서 행으로 정렬해보자.

<div style="width: 500px; height:400px;border: 1px solid black; 
	display: flex; flex-direction: column; justify-content: center; align-items: center;">
  <div style="width: 200px; height:100px;border: 1px solid black; background-color:rgba(255, 0, 0, 0.5);">block element2</div>
  <div style="width: 200px; height:100px;border: 1px solid black; background-color:rgba(255, 166, 0, 0.5);">block element3</div>
</div>

그런데 flex-direction: column일때 유의해야 할 점이 있다.

  • justify-content : 위아래의 위치를 설정한다는 점이고,
  • align-items : 좌우의 위치를 설정한다는 점이다.

flex-direction: row이거나, 명시되지 않았을 때는 기본적으로

  • justify-content : 좌우의 위치를 설정하고,
  • align-items : 위아래의 위치를 설정한다.

공간의 위치설정 및 공간활용3 (grid)

display 속성 가운데 grid라는 것이 있다. grid는 비교적 최근에 도입된 좋은 공간활용의 도구라고 한다. grid의 활용은 고정되지 않은 웹브라우저의 가로너비에 비례한다. 웹브라우져는 그 브라우져를 사용하는 사용자에 따라서 500px의 너비를 가질 수도 있도, 1000px의 너비를 가질 수도 있다. 이러한 사용자들의 환경에 따라서 개발자는 하나하나 대응하기 어려울 것이다. 이럴 때 grid의 활용은 빛을 바란다.

가로의 너비가 얼마가 되었든, 위에 사례에서 들보았듯이 block element1에 담겨 있는 block element2와 block element3이 1:1의 가로 너비로 한 행으로 기록되기를 바란다면? grid에서는 간단하다.

blockElement1 {
  display: grid;
  grid-template-columns: 1fr 1fr;}

이와 같이 코드를 입력하면 block element1 안에서 block element2와 block element3은 동일한 비율을 유지하며, 공간을 활용한다. 만약에 block element1 안에 block element2~4(3개) 가 존재할 때는 어떻게 할까? 아래와 같이 설정을 더해주면 된다.

blockElement1 {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;}

이때, block element2만 특정한 가로너비를 지정하고, 남은 공간에 대해서 block element3~4가 공간을 활용하도록 할 수 있을까? 물론 가능하다.

blockElement1 {
  display: grid;
  grid-template-columns: 100px 1fr 1fr;}

위와 같이 block element1 안에 있는 첫번째 태그인 block element2에 100px을 지정하면, 남은 공간에 대해서 block element3~4는 1:1의 비율로 공간을 활용한다. 그런데 이러한 생각도 들 수 있다. 가로너비를 4로 나누고, 1:1:2의 비율로도 가능할까? 가능하다.

blockElement1 {
  display: grid;
  grid-template-columns: 1fr 1fr 2fr;}

grid는 이렇게 활용될 수 있지만, 모든 웹브라우저에서 사용한 것은 아니기 때문에 언제나 검색이 필요하다. 이럴 때 사용할 수 있는 좋은 사이트가 있다.
CSS 적용가능 웹브라우저 확인 사이트(caniuse)

grid는 현재(2023년 01월) 전세계적으로 95.91%가 사용중인 CSS 기술이다. 크롬버전도 57버전 이상이면 사용이 가능하고, Safari의 경우도, 10.3버전 이상이면 사용가능하다. 그러나 때에 따라 사용할 수 없는 브라우저가 있을 수도 있으니, 기술을 사용할 때, 확인하고 작업하는 것은 중요할 것이다.

공간의 위치설정 및 공간활용4 (position)


이번에는 position이라는 속성에 대해서 다뤄보려고 한다. 기본적으로 block element2 선택자들은 position : static 상태이다. 이미지에서 보는 빨간색과 같다. 그러나 position의 값을 다르게 하면 역동적인 효과를 얻을 수도 있다.

1) position : relative; left:0px, right:0px, top:0px, bottom:0px의 값을 지정함으로 공간의 변칙을 줄 수 있다. 먼저 position : static에 대해서 알아야 할 필요가 있다. position : static는 현재 해당 block element2가 위치하고 있는 자신의 위치(좌표)가 있음을 의미한다. 이러한 상황에서 position : relative를 설정해주면, 자신의 부모태그인 block element1 안에 있는 자신의 위치에서 이동이 가능해지게 된다. 주황색에서 볼 수 있듯이 첫번째 주황색은 right:20px을 주어 오른쪽에서 20px 안쪽으로 이동하도록 설정한 것이고, 두번째 주황색은 left:20px을 주어 왼쪽에서 20px 안쪽으로 이동하도록 설정한 것이며, 세번째 주황색은 bottom:20px을 주어 아래에서 위쪽으로 20px 이동하도록 설정한 것이다.

<div style="border: 5px solid rgb(255, 89, 0);height:30px; background-color:rgb(255, 89, 0,0.5);
          position:relative;right:20px"></div>
<div style="border: 5px solid rgb(255, 89, 0);height:30px; background-color:rgb(255, 89, 0,0.5);
          position:relative;left:20px"></div>
<div style="border: 5px solid rgb(255, 89, 0);height:30px; background-color:rgb(255, 89, 0,0.5);
          position:relative;bottom:20px"></div>

2) position:absolute는 부모태그인 block element1 내라면 그 위치를 어디든지 변화시킬 수 있다. 첫번째 녹색은 top:0;라고 설정된 내용에 따라서, 자신의 위치에서 벗어나 부모태그에서 이동할 수 있는 최상단으로 이동하였다. 두번째 녹색은 bottom:0; left:0;에 따라 설정된 자신의 위치에서 벗어나 부모태그에서 이동할 수 있는 최하단의 왼쪽으로 이동하였으며, 세번째 녹색은 top:0; right:0;에 따라 설정된 자신의 위치에서 벗어나 부모태그에서 이동할 수 있는 최상단 오른쪽으로 이동하였다. 네번째 녹색은 bottom:0; right:0;에 따라 설정된 자신의 위치에서 벗어나 부모태그에서 이동할 수 있는 최하단 오른쪽으로 이동하였다.

<div style="border: 5px solid rgb(119, 255, 0);height:30px; background-color:rgb(119, 255, 0,0.5);
          position:absolute;top:0;"></div>
<div style="border: 5px solid rgb(119, 255, 0);height:30px; background-color:rgb(119, 255, 0,0.5);
          position:absolute;bottom:0; left:0;"></div>
<div style="border: 5px solid rgb(119, 255, 0);height:30px; background-color:rgb(119, 255, 0,0.5);
          position:absolute;top:0; right:0;"></div>
<div style="border: 5px solid rgb(119, 255, 0);height:30px; background-color:rgb(119, 255, 0,0.5);
          position:absolute;bottom:0; right:0;"></div>

3) position:fixedposition:absolute와 비슷하지만 더 자유로운 특징을 가진다. absolute가 부모태그 내에서 자신의 이동범위에 제한을 걸었다면, fixed는 부모태그 밖으로 나가는 아이이다. bottom:0; right:0;의 설정에 따라서 fixed는 부모태그 밖에서 갈 수 있는 웹페이지의 최하단 오른쪽으로 이동하였다. 위의 이미지에서 볼 수 있는 파란색 친구이다. 그런데 이 친구는 재미있는 친구이다. 웹브라우저의 높이가 길어서 스크롤을 할 때 따라온다. 스크롤을 가장 위로 움직여도 이 친구는 언제나 최하단 오른쪽에 위치해 있으며, 스르콜을 가장 아래로 움직여도 이 친구는 언제나 최하단 오른쪽에 위치해 있다. 이러한 특징들을 잘 활용하면, HTML은 동적으로 더 다채로움을 얻게 될 것이다.

<div style="border: 5px solid rgb(0, 128, 255);height:30px; background-color:rgb(0, 128, 255,0.5);
          position:fixed; bottom:0; right:0;">position:fixed</div>

공간의 위치설정 및 공간활용5 (반응형 디자인, Media-Query)

공간활용에 대한 마지막 이야기는 Media-Query에 대한 이야기이다. 먼저 이 아이의 등장에 대해서 살펴볼 필요가 있다. 현대의 사용자들의 웹브라우저 사용환경이 이전과 많이 달라졌기 때문이다. 바로 스마트폰의 등장으로 이러한 일이 발생되었다. 기존의 사용자들은 대부분 1440px 너비의 가로환경을 가진 데스크탑을 통해서 웹서버에 접근하였다. 그러나 스마트폰의 이용자들은 대략 350px 너비의 가로환경을 가진 환경으로 웹서버에 접근하고 있다. 그러기에 기존의 1440px에 맞춰진 웹브라우저들은 작아진 스마트폰의 환경에 적응하지 못하게 되었고, 이를 해결하기 위해 등장한 개념이 반응형 디자인으로서의 Media-Query이다. 이를 통해서 웹서버 제공자들은 어느정도의 작은 가로환경에 직면하더라도 웹페이지를 보기 좋게 디자인 할 수 있게 되었다. 방법은 비교적 단순하다. css 파일에 @media를 선언하고 조건을 달아주면 된다.

@media(max-width:500px) {
  #선택자 {
  	display:block;
    font-size: 20px;
    background-color: rgb(30, 30, 30);}

위의 코드를 읽어보면, 가로의 최대길이가 500px 이하가 되면, 아래에서 선택된 선택자는 다음과 같이 작동할 것이라는 선언이다. 먼저 위에서 display가 grid로 선언되어있다면, block을 선언함으로 800px 이상일 때 작동하던 grid의 효과를 무력화 할 수 있으며, 800px 이상인 웹브라우저에 비해 500px 이하의 크기의 웹브라우저 사용환경에 기존의 글자의 크기가 너무 크다면 크기를 지정함으로 축소할 수도 있고, 배경의 색상을 다르게 하고 싶을 때는 이렇게 선언함으로 적용할 수 있다.

그런데 유의할 점은 정확하게 내가 원하는 선택자가 변경되어야 이러한 효과가 극대화 된다는 점에서 개발자는 선택자(태그명, class명, id명)를 활용함에 있어서 지혜가 요구된다.

그런데 HTML, 더 동적일 수는 없을까?

1990년 WEB이 등장하고, 이를 보기 좋게 하기 위해 1994년 CSS가 발전되었지만, 사용자들은 만족하지 못했다. 바로 사용자로부터 정보를 받거나(사용자와 서버 간의 상호작용), 웹브라우저의 특정한 동작을 통해서 HTML이 조금 더 동적이게 움직이도록 만들고 싶었던 것이다. 바로 이러한 요구에 따라서 새로운 언어가 등장하게 되었으니, 1995년 Javascript가 세상에 등장하였다. 이 언어의 등장은 프론트엔드 디자이너라는 직군을 탄생시켰다. 단적인 비유로, HTML이 정적이라면, Javascript는 동적이다. 다음 글에서는 Javascript에 대해서 자세히 다뤄보겠다.

author. EDWIN
date. 2023/01/26

profile
신학전공자의 개발자 도전기!!

0개의 댓글