[HTML5&CSS] Form styling하기

label을 styling하기 위해서 font와 text의 크기를 조절한다.

textboxes나 textareas는 일반적으로 그 크기를 바꾸고, border를 제거한다. 또 예시 입력값인 placeholder를 추가해서 어떤 값을 입력하면 되는지를 도와주도록 한다.

 

button을 styling하기 위해서 일반적으로 배경색과 크기를 바꾼다. button의 box 바깥이 흉하므로 좀 손본다.

 

Select boxes를 styling하기 위해서는 일반적으로 text box처럼 보이게 만들고, 오른쪽의 아래 화살표를 styling한다.

 

form validation을 위해서 HTML은 required attribute를 제공한다. 입력이 꼭 필요한 field는 required attribute를 사용한다. CSS에서 이를 select하기 위해서 :valid 와 :invalid pseudo selector를 사용할 수 있다.

[HTML5&CSS] Box model

각 HTML element들은 여러 layer로 구성되는데, 가장 바깥쪽에 margin, 그 안에 외곽선인 border, 그 안에 padding 그리고 그 안에 width와 height의 content가 위치한다. 반대로 안쪽부터 보자.

 

Content Box는 실제 content가 들어가는 부분이다. 가장 중요한 property는 width와 height이다. 실제 px값이나 %로 준다.

width: 300px;

height: 200px;

 

Padding은 border와 content box 사이에 공간을 준다. top, bottom, left, right 모두에 줄 수도, 좌우와 상하에만 줄 수도, 원하는 곳에 padding-top, padding-bottom, padding-left, padding-right로 줄 수도 있다.

모두에 padding 값을 줄 때는 값 하나만 쓴다.

padding: 25px;

상하와 좌우에 같은 값들을 줄 때는 값 두개를 쓴다. 아래는 상하에 25px를, 좌우에는 0px를 준다

padding: 25px 0px;

 

border는 padding의 끝에서 margin의 시작까지 자리한다. 기본값은 visible하지 않아서 명시적으로 정해주어야만 볼 수 있다. padding처럼 각 direction마다 줄 수도 있다. 모든 값은 width, style, color의 3가지 값을 갖는다. 예제들은 다음과 같다.

border: 1px solid red;

border-top: 1px solid blue;

border-right: 2px dotted red;

border-bottom: 5px dashed yellow;

border-left: 10px double pink;

 

margin은 border의 끝과 페이지 상의 다른 element의 외곽 사이에 공간을 준다. 역시 padding처럼 모든 방향에, 상하/좌우를 나눠서 줄 수도, 각 direction 별 top, right, bottom, left에 따로 줄 수도 있다.

 

4 방향을 속성에 한꺼번에 써서 줄 때는 clock-wise로 돈다. top->right,->bottom->left

개발자 도구에서 각 속성 값을 확인할 수 있다.

[HTML5&CSS] CSS 개요

CSS는 HTML에 style을 더할 때 사용한다. 다음과 같은 형식이다.

selector or selector list {

CSS declarations (= property: value;)

}

예를 들면 다음과 같다.

p, h1, h2 {

background: black;

color: white;

}

 

이를 HTML에 적용하는 방법은 여러가지가 있다.

  1. HTML tag의 style attribute를 이용하는 방법. 예를 들면, <h1 style=”color: red;”>…</h1>

  2. <head>나 <body> 태그 내에 <style> 태그를 추가하는 방법. head안에 넣는 게 더 빠르다.

  3. <link>를 통해 외부 리소스로부터 적용하는 방법. 예를 들면, <link href=”styles/mystyle.css” rel=”stylesheet”>. 가장 추천.

 

CSSOM (CSS Object Model)은 HTML DOM과 비슷하게 style에 대한 in-memory representation이다.

javascript로 HTML DOM을 접근할 때 다음과 같은 코드를 사용해서 DOM element의 style property를 access할 수 있다.

const contentElement = document.querySelector(‘.content’);

contentElement.style.fontWeight = ‘bold’;

 

비슷하게 CSSOM은 window object의 getComputedStyle 메소드로 access할 수 있다.

const contentElement = document.querySeletor(‘.content’);

window.getComputedStyle(contentElement);

이건 contentElement class attribute로 그 element의 read-only computed style을 return한다.

 

CSS로 HTML 문서의 element를 지정하고자 할 때 selector를 사용한다.

3가지 일반적인 selector가 있다.

  1. Element type: 예를 들면, 모든 그 HTML 문서 내의 p element를 select하고자 한다면 CSS ruleset에 p selector를 쓴다.

  2. class attribute: . 으로 시작하는 class selector. <h1 class=”heading”>Heading</h1> 을 select하고 싶다면, .heading selector를 쓴다.

  3. id attribute: # 으로 시작하는 id selector. <div id=”dasomoli”> <!– login content –> </div> 라면, #dasomoli를 쓴다.

 

모든 element를 선택하고 싶으면 Universal Selector (*)를 쓴다. 다음과 같은 예제는 html에 값을 셋팅하고, 모든 자식 element들에 이를 inherit한다.

html {

box-sizing: border-box;

}

*, *:before, *:after {

box-sizing: inherit;

}

 

Attribute selector를 사용하면 attribute가 있는지 또는 attribute 값에 따라서 select할 수 있다. 대괄호([, ])를 쓴다.

  • [attribute]: 그 attribute가 있는 모든 element를 select한다. [href]는 href attribute가 있는 모든 element를 select한다.

  • [attribute=value]: attribute값이 value인 모든 element를 select한다. [lang=”en”] 은 lang attribute가 en인 모든 element를 select한다.

  • [attribute^=value]: attribute 값이 value로 시작하는 모든 element를 select한다. [href^=”https://] 는 href attribute가 https:// 로 시작하는 모든 element를 select한다.

  • [attribute$=value]: attribute 값이 value로 끝나는 모든 element를 select한다. [href$=”.com”] 은 href attribute가 .com으로 끝나는 모든 element를 select한다.

  • [attribute=value]: attribute 값 안에 value가 들어간 모든 element를 select한다. [href=”co.kr”] 은 href attribute가 co.kr과 들어간 모든 element를 select한다.

 

Pseudo-class는 특정 상태에 있는 element를 select한다. :keyword 같은 형식으로 쓴다. 대단히 많은 pseudo-class가 있는데, 대부분의 개발자들은 link를 styling할 때 처음 본다. link는 여러 상태를 갖는다.

  • href를 갖는 link는 :link pseudo-class를 갖는다.

  • 사용자가 link에 마우스를 올렸을 때, :hover pseudo-class가 적용된다.

  • 가 본 link일 때, :visited pseudo-class가 적용된다.

  • click될 때, :active pseudo-class가 적용된다.

예를 들면,

a:link, a:visited: {

color: blue;

text-decoration: none;

}

a:hover, a:active {

color: red;

text-decoration: dashed underline;

}

순서에 주의해야 하는데, 위의 순서를 바꾸면 hover 효과를 볼 수 없다. love-hate로 외우면 쉽다.

다른 유용한 pseudo-class로 :checked, :disabled, :focus가 있다.

 

중첩된 자식들의 패턴을 select할 때 도움이 되는 pseudo-class가 있다. :first-child, :last-child, :nth-child, :nth-last-child, :first-of-type, :last-of-type, :nth-of-type, :nth-last-of-type 등등.

예를 들어, 다음과 같이 하면 3줄마다 반복되는 패턴을 만들 수 있다.

li {

display: block;

padding: 16px;

}

li:nth-child(3n-1) {

background: deepskyblue;

color: white;

font-weight: bold;

}

li:nth-child(3n) {

background: skyblue;

color: white;

font-weight: bold;

}

위의 예제에서 3n-1 대신 odd 나 even 같은 keyword를 사용할 수도 있다.

 

element의 일부를 select하고 싶을 때는 Pseudo-element를 쓴다. ::keyword 형식으로 쓴다.

::first-letter, ::first-line, ::selection, ::backdrop 등등.

 

위에서 설명한 여러 방법을 합쳐서 사용하면 더 강력하다. 예를 들면, primary class인 li element를 select하고 싶다면, li.primary를 쓰면 된다.

  • ul element의 자식인 모든 li element를 select하고 싶으면. ul li

  • primary class인 ul element의 direct children인 모든 li를 select하고 싶으면, ul.primary > li

  • selected class인 li element의 다음 sibling을 select하고 싶으면, li.selected + li

  • selected class인 li element의 모든 다음 sibling들을 select하고 싶으면, li.selected ~ li

li.selected + li 는 다음 하나만, li.selected ~ li 는 다음부터 전부 다인 것을 주의하라.

 

CSS specificity는 어느 style이 적용될지를 결정하는 factor이다. 태그에 style attribute로 적용되는 inline style은 가장 높은 specificity 값을 갖는다. 그 다음이 ID selector, 그 다음이 class selector나 attribute selector, 그리고 다음이 element type이다. 일반적으로 이를 표현하는 방법이 ,로 나눈 integer list로 많이 표현한다. inline style은 1, 0, 0, 0이다. id selector는 0, 1, 0, 0. class selector나 attribute selector는 0, 0, 1, 0. h1 같은 element selector는 0, 0, 0, 1이 된다.

예를 들면, li,selected a[href] 는 2 element selectors(li, a), 하나의 class selector(.selected)와 하나의 attribute selector([herf])를 갖으므로, 0, 0, 2, 2가 된다.

다른 예로 #newItem #mainHeading span.smallPrint는 두 ID selector, 하나의 class selector(.smallPrint), 하나의 span element를 갖으므로, 0, 2, 1, 1이 된다.

위의 둘을 비교하면, 두번째 것이 첫번째 것보다 더 specific하다.

그런데 여기에 !important 를 쓰면 가장 우선한다. 위의 표현 방법에 따르면 1, 0, 0, 0, 0이 된다. inline보다 더 우선한다.

예를 들면, 다음과 같은 걸 보자.

<style>

div.media {

display: block;

width: 100%;

float: left;

}

.hide {

display: none;

}

</style>

<div class=”media hide”> 어쩌고 저쩌고 </div>

여기서 div는 media와 hide 둘 중 어느 것이 적용될까. div.media는 0, 0, 1, 1 이다. .hide는 0, 0, 1, 0이다. 따라서 .hide의 display: none을 div.media의 display: block이 override한다. .hide는 적용이 안된다. 이럴 때 아래처럼 하면 된다.

.hide {

display: none !important;

}

 

 

구글도 한다. 자동 checkpatch!

작년 8월부터 10월에 “개발 환경 개선 Git + Gerrit + checkpatch + cleanpatch” 에서 이야기했던대로
회사에서는 아무도 나에게 이런 것을 하라고 한 적은 없지만,

1. Gerrit 시스템 상에서 리눅스 커널에 대한 Change는 자동으로 checkpatch.pl 를 실행해서 해당 결과를 자동으로 comment하고, Error 나 Warning이 있는 경우 해당 패치셋에 -1로 리뷰 점수를 부여하고,
2. White space error, 소스 코드, Kconfig, Makefile 등의 파일의 Execution 권한 에러 등이 있는 경우 자동으로 수정해서 새로운 Patch set으로 올려주는

시스템을 구현해서 도입했다(나중에 연말 임원 회의 때 “우리 부서의 자랑” 같은 발표를 하려고 했던 것으로 알고 있다. 했나?).

그런데 올해 2월 초부터 구글의 gerrit 시스템에도 비슷한 것이 보이기 시작했다. “Kernel code style” 이라는 사용자 이름으로 checkpatch 결과가 붙기 시작한 거다. 내가 구현한 위의 것에서는 1단계까지의 것으로 보인다. 보자마자 ‘어라? 이것들 나랑 비슷한거 만들었네?’ 란 생각에 흥미로움을 감출 수 없었다. 더 재밌는 건 내 스크립트가 comment 하는 형식과 구글의 comment 형식이 거의 같다는 거다. 난 너무 많으면 길어서 내용을 좀 자르긴 했다. 도입 초기에는 에러가 3만개, 6만개씩 있는 패치들도 있었으니까! ㅎㅎㅎㅎ

그래서 찾아보니 구글의 커널 개발자 Brian Swetland 가 2009년 9월에 이를 할 수 있으면 좋겠다는 이슈를 올렸었고, 2010년 2월에 hooks 를 이용할 수 있다는 답변으로 closed 되었다. 답변으로 달린 방법이 거의 정확히 1단계를 위해 내가 구현한 방법과 일치하는데, 구글 내부 gerrit 에서도 사용했었는지는 알 수 있는 방법은 없다. 그런데 Nexus S때도, Galaxy Nexus 때도 2월 이전에는 쓴 적이 없단 말이지… ㅎㅎㅎ

동작하는 방식을 조금 보니 아마 커널 Change를 올리는 개발자 그룹이 있어서 해당 그룹에 속한 개발자가 Change를 올리면 checkpatch로 체크를 하는 것 같다.

이글을 쓰다가 TI 커널 브랜치에서부터 시작이 된 것 같아서 찾아보니 TI Gerrit(http://review.omapzoom.org/)은 2011년 7월부터 Ruslan Bilovol 이란 개발자가 자기 Bot을 사용해서 Change-Id check와 checkpatch를 자동으로 돌리는 것을 시작했었다! 난 작년 7월에 산호세에 있었고 7월 말부터 이 일을 맡아서 시작했었으니! 오! 세계 최초라 한 것이 부끄럽구나! …근데 자동으로 고쳐서 올려주는 건 아직 나밖에 안했잖아???? ㅎㅎㅎㅎ

아무튼 내가 생각한 것과 비슷한 생각들, 그리고 비슷한 구현물들을 세계 이곳저곳에서 발견할 수 있다는 게 너무나도 재밌다!!!

p.s.: 나한테 더 성능좋은 PC, 서버들이 더 많이 주어진다면, 아마 더 많은 일을 할 수 있을텐데…