분류 html

HTML 및 CSS 양식 가이드

컨텐츠 정보

  • 조회 29 (작성일 )

본문

역사적으로 HTML 양식은 매우 까다로웠습니다. 첫째는 최소한 약간의 JavaScript가 필요했기 때문이고 둘째는 CSS가 아무리 많아도 작동하지 않기 때문입니다. 


https://www.sitepoint.com/a-guide-to-html-css-forms-no-hacks/ 


그러나 최신 웹의 경우 반드시 그런 것은 아니므로 HTML과 CSS 만 사용하여 양식을 마크업하는 방법을 알아 보겠습니다.


기본 구조 형성 


A form input with a prefilled value 


<form> 요소로 시작하십시오.


여기에 멋진 것은 없습니다. 기본 구조 만 다루고 있습니다.


<form>
    ...
</form>

양식 데이터를 자연스럽게 제출하는 경우 (즉, JavaScript없이) 작업 속성을 포함해야 합니다. 여기서 값은 양식 데이터를 보낼 URL입니다. 방법은 달성하려는 목표에 따라 GET 또는 POST 여야 합니다 (GET으로 민감한 데이터를 보내지 마십시오).


또한 전송되는 데이터의 인코딩 유형을 정의하는 덜 사용되는 enctype 속성도 있습니다. 또한 대상 속성은 양식에 고유 한 속성 일 필요는 없지만 새 탭에 출력을 표시하는 데 사용할 수 있습니다.


JavaScript 기반 양식에는 이러한 속성이 반드시 필요하지는 않습니다.


<form method="POST" action="/subscribe" enctype="application/x-www-form-urlencoded" target="_blank">
    ...
</form>

양식은 데이터 값을 예상하는 입력으로 구성됩니다.


<form>
    <input type="text"><!-- text input -->
    <input type="text" value="Prefilled value">
</form>

https://codepen.io/SitePoint/pen/jOqjEqx 


더 나은 사용성과 접근성을 위한 레이블 포함 


모든 입력에는 레이블이 필요합니다.


레이블은 입력의 용도를 설명하는 텍스트 설명자입니다. 레이블을 선언하는 방법에는 세 가지가 있지만 그중 하나가 다른 두 가지보다 우수합니다. 이제 이것에 대해 자세히 살펴 보겠습니다.


인접 라벨(Adjacent labels) 


인접한 레이블은 레이블이 설명하는 입력을 명시적으로 선언해야 하므로 가장 많은 코드가 필요합니다. 대부분의 경우, 이것은 더 적은 코드로 동일한 효과를 얻기 위해 레이블 내부에 입력을 래핑 할 수 있기 때문에 직관적이지 않습니다.


<label for="firstName">First name</label>
<input id="firstName">

위의 예에서 볼 수 있듯이 <label>의 for 속성은 입력의 id 속성과 일치해야 하며, 이것이 어떤 텍스트 설명자가 어떤 입력에 속하는지 입력 장치에 설명합니다. 그런 다음 입력 장치는 이를 사용자에게 전달합니다 (예 : 스크린 리더는 음성을 통해 지시합니다).


ARIA labels 


시맨틱 HTML이 더 좋지만 ARIA (Accessible Rich Internet Applications) 레이블이 없는 경우 이를 보완 할 수 있습니다. 이 경우 실제 HTML <label>이 없을 때의 레이블은 다음과 같습니다.


<input aria-label="First name">

안타깝게도 이 접근 방식의 단점은 시각적 레이블이 없다는 것입니다. 그러나 일부 마크 업 (예 : 제목과 자리 표시자가 있는 단일 입력 양식)에서는 문제가 없을 수 있습니다.


<h1>Subscribe</h1>
<form>
    <input aria-label="Email address" placeholder="bruce@wayneenterpris.es">
</form>

(잠시 자리 표시자가 무엇인지 설명하겠습니다.)


포장 라벨(Wrapping labels) 


라벨 내에서 입력을 감싸는 것이 가장 깔끔한 접근 방식입니다. 또한 CSS의 : focus-within 덕분에 자식 입력이 포커스를 받는 동안 레이블 스타일도 지정할 수 있지만 나중에 논의 할 것입니다.


<label>
    First name<input>
</label>

자리 표시자와 레이블(Placeholders vs labels) 


Two inputs with placeholder text visible 


간단한 비교 :


  • 라벨은 입력이 기대하는 바를 나타냅니다.
  • 자리 표시자는 상기 기대치의 예를 보여줍니다.

자리 표시자는 레이블의 대안으로 설계되지 않았습니다. 위의 ARIA 예에서 보았 듯이 시각적 레이블이 없어서 손실 된 컨텍스트를 다시 추가 할 수 있습니다.


하지만 이상적으로는 다음 두 가지를 모두 사용해야 합니다.


<label>
    First name<input placeholder="Bruce">
</label>

https://codepen.io/SitePoint/pen/qBZzEaE 


입력 유형 선택(Input Types) 


자리 표시자는 텍스트 기반 입력에만 적용되지만 실제로는 다음과 같은 다양한 입력 유형이 있습니다.


<input type="button">
<input type="checkbox">
<input type="color">
<input type="date">
<input type="datetime-local">
<input type="email">
<input type="file">
<input type="hidden"> <!-- explained later -->
<input type="image">
<input type="month">
<input type="number">
<input type="password">
<input type="radio">
<input type="range">
<input type="reset">
<input type="search">
<input type="submit"> <!-- submits a form -->
<input type="tel">
<input type="text"> <!-- the default -->
<input type="time">
<input type="url">
<input type="week">

의미론적 입력 유형은 양식 유효성 검사 중에 유용하며, 특히 기본 유효성 검사에 의존 할 때 유용합니다. 이에 대해서는 곧 살펴 보겠습니다. 먼저 이러한 입력의 스타일을 지정하는 방법을 알아 보겠습니다.


스타일링 입력 


양식을 코딩 할 때 가장 짜증 나는 부분은 브라우저의 기본 스타일을 무시하는 것입니다. 고맙게도 오늘 appearance: none; caniuse.com에 따르면 96.06 %의 브라우저 지원을 제공합니다.


다음 CSS 코드를 사용하여 웹 브라우저의 기본 스타일을 재설정 한 후 원하는 대로 입력 스타일을 지정할 수 있으며 여기에는 라디오 및 확인란 입력 유형도 모두 포함됩니다.

input {
 -webkit-appearance: none;
 -moz-appearance: none;
    appearance: none;
    ...
}

그러나 이러한 입력 중 일부는 극복하기 어렵거나 심지어 불가능한 단점이 있을 수 있습니다 (웹 브라우저에 따라 다름). 이러한 이유로 많은 개발자는 이러한 특성이 바람직하지 않다고 판단되면 기본 type = "text"attribute = value로 돌아가는 경향이 있습니다 (예 : 입력 type = "number"의 "캐럿").


하지만 은색 안감이 있습니다.


입력 모드(inputmode) 지정 


caniuse.com에 따르면 82.3 % 웹 브라우저 지원을 통해 새로운 inputmode 속성은 사용 중인 입력 유형에 관계없이 핸드 헬드 장치에 표시 할 키보드 레이아웃을 지정합니다.


없는 것보다 낫죠?


<input type="text" inputmode="none"> <!-- no keyboard 👀 -->
<input type="text" inputmode="text"> <!-- default keyboard -->
<input type="text" inputmode="decimal">
<input type="text" inputmode="numeric">
<input type="text" inputmode="tel">
<input type="text" inputmode="search">
<input type="text" inputmode="email">
<input type="text" inputmode="url">

사용자 입력 확인 


JavaScript 솔루션에 대한 네이티브 HTML 유효성 검사를 선택하는 경우 inputmode는 이와 관련하여 아무것도 달성하지 못합니다. inputmode = "email"은 이메일 주소를 확인하지 않지만 input type = "email"은 확인합니다. 그것이 차이입니다.


이 문제를 제쳐두고 유효성 검사를 트리거 하는 것이 무엇인지 살펴 보겠습니다.


<input required> <!-- value is required -->
<form required> <!-- all values are required -->

<!-- alternative input types -->
<input type="email"> <!-- blank or a valid email address -->
<input type="email" required> <!-- must be a valid address -->

<!-- text-based inputs -->
<input minlength="8"> <!-- blank or min 8 characters -->
<input maxlength="32"> <!-- blank or max 32 characters -->
<input maxlength="32" required> <!-- max 32 characters -->

<!-- numeric-based inputs -->
<input type="date" min="yyyy-mm-dd"> <!-- min date -->
<input type="number" max="66" required> <!-- max number -->

사용자 지정 규칙 만들기 


사용자 지정 규칙에는 RegExp 개체에서 사용되는 JavaScript 정규식에 대한 지식이 필요합니다 (슬래시 또는 따옴표 없이). 다음은 하나의 규칙에서 소문자 (a–z) 및 minlength / maxlength를 적용하는 예입니다.


<input pattern="[a-z]{8,12}">

여기에 더 많은 정보가 있습니다.


참고 : 프런트 엔드 유효성 검사 (네이티브 HTML 또는 기타)는 절대로 서버 쪽 유효성 검사를 대신하여 사용해서는 안됩니다!


유효 / 잘못된 상태 스타일 지정 


The form with placeholder text in form fields and a submit/subscribe button 


더 명확하게 하기 위해 다음과 같이 유효성을 스타일링했습니다


input:valid {
    border-left: 1.5rem solid lime;
}

input:invalid {
    border-left: 1.5rem solid crimson;
}

form:invalid {
    /* this also works, technically! */
}

입력은 즉시 값의 유효성을 검사하려고 시도하므로 (또는 값이 없는 경우) 다음 코드 (입력이 값을 보유하는 동안 유효 / 무효 상태 만 표시)가 더 좋을 수 있습니다.


input:not(:placeholder-shown):valid {
    border-left: 1.5rem solid lime;
}

유효한 / 잘못된 스타일이 표시되지만 자리 표시자가 표시되지 않은 경우에만 표시됩니다 (사용자가 입력했기 때문에).


https://codepen.io/SitePoint/pen/oNxrgBj


기타 기본 사항 


양식 데이터 보내기 


양식 데이터를 서버로 보내려면 일반적으로 입력에 name 속성이 있어야 합니다. 이것은 숨겨진 입력에도 적용됩니다.


<input type="email" name="email">
<input type="hidden" name="email" value="{{ user.email }}">

긴 양식 입력 허용 


기본적으로 <textarea> </ textarea>는 텍스트 영역이 여러 줄을 지원한다는 사실을 제외하면 <input type = "text">와 동일합니다. 예, <input type = "textarea">는 확실히 더 직관적이지만, 아쉽게도 <textarea> </ textarea>는 사용자의 긴 형식 입력을 받아들이는 올바른 방법입니다. 또한 입력이 수행하는 속성의 대부분 (전부는 아님)을 허용합니다.


접근성 향상을 위한 입력 그룹화 


짧은 양식이 훨씬 더 나은 사용자 경험을 제공하지만 때로는 긴 양식이 불가피합니다. 이러한 시나리오에서 <fieldset> 요소를 사용하여 관련 입력을 포함 할 수 있으며 하위 <legend>가 <fieldset>의 제목 / 제목으로 사용됩니다.


<fieldset>
    <legend>Name</legend>
    <input type="text" name="title">
    <input type="text" name="firstName">
    <input type="text" name="lastName">
</fieldset>
<fieldset>
    <legend>Contact details</legend>
    <input type="email" name="email">
    <input type="tel" name="homePhone">
    <input type="tel" name="mobilePhone">
</fieldset>

알아두면 좋은 것들 


입력 비활성화 


disabled 속성을 추가하면 일반적으로 JavaScript를 통해 적용 / 적용되지 않지만 입력 (또는 포커스 가능한 요소)이 작동하지 않게 될 수 있습니다. 하지만 작동 방식은 다음과 같습니다.


<form disabled>...</form>
<fieldset disabled>...</fieldset>
<input type="submit" disabled>

필요한 경우 함께 제공되는 CSS :


:enabled {
    opacity: 1;
}
:disabled {
    opacity: 0.5;
}

그러나 사용자의 입력이 유효하지 않다는 것을 암시하는 추가 시각적 신호를 추가하는 것뿐이라면 일반적인 형제 결합 자 (~)를 사용하는 것이 좋습니다. 다음 코드는 기본적으로 "잘못된 입력이 있는 요소를 따르는 제출 버튼"을 의미합니다. 이는 기능을 변경하지 않지만 기본 HTML 양식 유효성 검사 (제출 기능의 비활성화 / 활성화를 자동으로 처리)를 활용하는 경우 괜찮습니다.


:invalid ~ input[type=submit] {
    opacity: 0.5;
}

입력을 비활성화 하지만 어쨌든 데이터 보내기 


<input disabled> 및 <input type = "hidden">이 혼합 된 다음 예제는 값을 변경할 수 없도록 합니다. 차이점은 비활성화와 달리 읽기 전용 값이 양식 데이터로 전송된다는 것입니다. 숨김과 달리 읽기 전용이 표시됩니다.


<input readonly value="Prefilled value">

증분 변경 


숫자 기반 입력에는 숫자 값을 조정하는 "스핀 버튼"이 있으며 각 조정의 대체 증분 값을 결정하는 단계 속성도 허용합니다.


<input type="number" step="0.1" max="1">

포커스에 대한 양식, 레이블 및 필드 세트 스타일 지정 


focus-within :을 사용하여 현재 포커스를 받는 입력의 부모 스타일을 지정할 수 있습니다. 이 요소는 입력의 <form>, <label> 또는 <fieldset> 컨테이너 일 가능성이 높습니다.


form:focus-within,
fieldset:focus-within,
label:focus-within {
    ...
}

하나의 입력으로 여러 값 보내기 


다중은 파일 및 이메일 입력 유형에 유효합니다.


<input multiple type="file"> <!-- multiple files -->
<input multiple type="email"> <!-- comma-separated emails -->

속기 양식 코드 작성 


양식이 하나의 <button>, <input type = "image"> 또는 <input type = "submit">로만 구성된 경우 HTML 양식을 마크 업하는 약식 방법이 있습니다. 예를 들면 다음과 같습니다.


<input type="image" formaction formmethod formenctype formtarget>

이와 반대로 :


<form action method enctype target>
    <input type="image">
</form>

내가 놓친 것이 있습니까? 



HTML은 10 년 전보다 훨씬 더 직관적입니다. 지속적으로 진화하고 있으며 곧 HTML / CSS 양식의 주제에 추가 할 내용이 더 많아 질 것입니다. 떠오르는 한 가지 예는 현재 매우 버그가 있을 수 있는 (특히 Firefox에서) datalist 요소입니다. 하지만 그 외에 내가 놓친 것이 있습니까?


HTML 양식의 사용을 권장하지 않기 때문에 설명하지 않은 HTML 양식의 몇 가지 측면은 다음과 같습니다.


  • Autofocus (접근성에 좋지 않음)
  • Autocomplete (자동 완성을 사용하지 않는 것은 기본값이 아닌 사용자의 선택이어야 함)
  • Accesskey (나쁜 지원 및 접근성)
  • Novalidate (JavaScript 없이는 쓸모가 없습니다)