๐ 1๏ธโฃ ํผ ๊ตฌ์กฐ ํต์ฌ ์์ฝ & ์๋งจํฑ ์๋ฏธ
ํ๊ทธ |
์ญํ |
์๋งจํฑ ์๋ฏธ |
์ ๊ทผ์ฑ |
SEO ์ํฅ |
๋น์ ๐ |
<form> |
์
๋ ฅ ๋ฐ์ดํฐ ์์ญ |
โ
|
๊ทธ๋ฃนํ ๋ช
ํ |
์ ์ก URL์ ๋ฐ๋ผ |
๐ฆ ์๋ฅ ๋ดํฌ (๋ฐ์ดํฐ ์ ์ถ) |
<input> |
์
๋ ฅ ํ๋ |
โ
|
์คํฌ๋ฆฐ๋ฆฌ๋ ์ธ์ |
์์ (์ปจํ
์ธ ์
๋ ฅ) |
โ๏ธ ์์ฑ๋ |
<textarea> |
์ฌ๋ฌ ์ค ์
๋ ฅ |
โ
|
์ฝ์ |
์์ |
๐ ๋ฉ๋ชจ์ฅ |
<select> +<option> |
๋๋กญ๋ค์ด ๋ชฉ๋ก |
โ
|
ํญ๋ชฉ ํ์ |
ํค์๋ ๊ฐ๋ฅ |
๐ ์ ํ์ง ๋ชฉ๋ก |
<button> |
๋ฒํผ (์ ์ถ/์ด๊ธฐํ) |
โ
|
ํด๋ฆญ ๊ฐ๋ฅ |
์์ |
๐ ๋ฒํผ ํด๋ฆญ |
<fieldset> |
ํผ ๊ทธ๋ฃนํ |
โ
|
๊ทธ๋ฃน ๋ช
ํํ |
- |
๐ ํผ ํด๋ |
<legend> |
๊ทธ๋ฃน ์ ๋ชฉ |
โ
|
๊ทธ๋ฃน ์ ๋ชฉ ์ฝ์ |
- |
๐ท๏ธ ๋ผ๋ฒจ |
<label> |
์
๋ ฅ ํ๋ ์ค๋ช
|
โ
|
์คํฌ๋ฆฐ๋ฆฌ๋ ์ฐ๊ฒฐ |
- |
๐ ์ค๋ช
์ |
<datalist> |
์๋์์ฑ |
โ
|
์ ์ ๋ชฉ๋ก ์ธ์ |
- |
๐ฝ ์ถ์ฒ ๋ฆฌ์คํธ |
<output> |
๊ณ์ฐ ๊ฒฐ๊ณผ ํ์ |
โ
|
์ค์๊ฐ ํ์ |
- |
๐งฎ ๊ณ์ฐ๊ธฐ ๊ฒฐ๊ณผ์ฐฝ |
<progress> |
์งํ๋ฅ |
โ
|
์ํ ์ ๋ฌ |
- |
๐ ์งํ ๋ฐ |
<meter> |
๊ฒ์ด์ง |
โ
|
๋ฒ์ ์๊ฐํ |
- |
๐งญ ๊ฒ์ด์ง ๋ฐ |
๐งฉ 2๏ธโฃ ๋น์ ๋ก ์ฝ๊ฒ ์ดํด
ํ๊ทธ |
๋น์ ๐ |
<form> |
๐ฆ ๋ดํฌ (์ ์ถ์ฉ ๋ฐ์ดํฐ ๋ฌถ์) |
<input> |
โ๏ธ ์
๋ ฅ ์นธ (ํ
์คํธ, ์ด๋ฉ์ผ, ๋น๋ฐ๋ฒํธ ๋ฑ) |
<textarea> |
๐ ๊ธด ์๊ฒฌ ์นด๋ |
<select> +<option> |
๐ ์๋ฅ์์ ๊ณ ๋ฅด๋ ์ฒดํฌ๋ฆฌ์คํธ |
<button> |
๐ ํ์ธ/์ ์ถ ๋ฒํผ |
<fieldset> |
๐ ํผ ๊ทธ๋ฃน (์ฌ๋ฌ ํญ๋ชฉ ๋ฌถ๊ธฐ) |
<legend> |
๐ท๏ธ ๊ทธ๋ฃน ์ ๋ชฉ |
<label> |
๐ ๊ฐ ํญ๋ชฉ ๋ผ๋ฒจ |
<datalist> |
๐ฝ ์๋ ์ถ์ฒ ๋ฆฌ์คํธ |
<output> |
๐งฎ ์๋๊ณ์ฐ ํ์์ฐฝ |
<progress> |
๐ ํ์ผ ์
๋ก๋ ์ํ๋ฐ |
<meter> |
๐งญ ์ ์, ์ฉ๋, ํผ์ผํธ ๊ฒ์ด์ง |
๐๏ธ 3๏ธโฃ ํผ ๊ธฐ๋ณธ ๊ตฌ์กฐ ์์ (์ค๋ฌดํ)
html
๋ณต์ฌํธ์ง
<form action="/submit" method="POST" novalidate>
<fieldset>
<legend>๐ค ์ฌ์ฉ์ ์ ๋ณด</legend>
<label for="name">์ด๋ฆ:</label>
<input type="text" id="name" name="name" required minlength="2" maxlength="20"><br><br>
<label for="email">์ด๋ฉ์ผ:</label>
<input type="email" id="email" name="email" required><br><br>
<label for="password">๋น๋ฐ๋ฒํธ:</label>
<input type="password" id="password" name="password" required pattern=".{8,}"><br><br>
<label for="role">์ง๋ฌด ์ ํ:</label>
<select id="role" name="role">
<option value="">์ ํ</option>
<option value="frontend">ํ๋ก ํธ์๋</option>
<option value="backend">๋ฐฑ์๋</option>
</select><br><br>
<label for="browser">๋ธ๋ผ์ฐ์ ์ถ์ฒ:</label>
<input list="browsers" id="browser" name="browser">
<datalist id="browsers">
<option value="Chrome">
<option value="Firefox">
<option value="Safari">
</datalist><br><br>
<button type="submit">์ ์ถ</button>
</fieldset>
</form>
โ
ํฌ์ธํธ:
- required, pattern, minlength, maxlength ํ์ฉ โ ๊ธฐ๋ณธ ๊ฒ์ฆ
label
+ id
์ผ์น โ UX & ์ ๊ทผ์ฑโ
novalidate
๋ก ๋ธ๋ผ์ฐ์ ๊ฒ์ฆ ๋๊ณ JS ์ปค์คํ
๊ฒ์ฆ ๊ฐ๋ฅ
datalist
๋ก UX ์๋์์ฑ ์ ๊ณต
ํ์
|
์ค๋ช
|
๊ฒ์ฆ ์์ฑ |
UX ํ |
text |
์ผ๋ฐ ํ
์คํธ |
required, minlength |
๊ธฐ๋ณธ |
email |
์ด๋ฉ์ผ ๊ฒ์ฆ |
pattern ์๋ ์ ์ฉ |
๋ชจ๋ฐ์ผ ํค๋ณด๋ @ ํ์ |
password |
๋น๋ฐ๋ฒํธ |
minlength, pattern |
๋ณด์ ๊ฒฝ๊ณ |
number |
์ซ์ ์ ์ฉ |
min, max, step |
์ซ์ ์คํผ๋ ์ ๊ณต |
tel |
์ ํ๋ฒํธ |
pattern |
๋ชจ๋ฐ์ผ ์ซ์ํจ๋ |
url |
URL ํ์ |
์๋ pattern |
http ํฌํจ ์ฌ๋ถ ์ฃผ์ |
checkbox |
๋ค์ค ์ ํ |
required |
ํ์ ์ ํ ์ ์ฒดํฌ |
radio |
๋จ์ผ ์ ํ |
required |
๊ทธ๋ฃนํ ํ์ |
file |
ํ์ผ ์
๋ก๋ |
accept=โ.jpg,.pdfโ |
MIME ํ์
์ ํ |
date /time |
๋ ์ง/์๊ฐ |
min, max |
๋ ์ง ํผ์ปค ์ ๊ณต |
range |
์ฌ๋ผ์ด๋ |
min, max, step |
UI ์ฌ๋ผ์ด๋ ์ ๊ณต |
color |
์์ ์ ํ |
- |
ํ๋ ํธ ์ ๊ณต |
๐๏ธ 5๏ธโฃ ๊ณ ๊ธ ํผ ๊ธฐ๋ฅ ์ฌํ ์์
html
๋ณต์ฌํธ์ง
<label for="lang">์ฌ์ฉ ์ธ์ด:</label>
<input list="languages" id="lang" name="lang">
<datalist id="languages">
<option value="HTML">
<option value="CSS">
<option value="JavaScript">
</datalist>
๐งฎ 2) <output>
์ค์๊ฐ ๊ณ์ฐ (JS ์ฐ๋)
html
๋ณต์ฌํธ์ง
<form oninput="total.value = parseInt(price.value) * parseInt(qty.value)">
<input type="number" id="price" value="1000"> ์ ร
<input type="number" id="qty" value="1"> ๊ฐ =
<output name="total">1000</output> ์
</form>
๐ 3) <progress>
ํ์ผ ์
๋ก๋ ์ํ๋ฐ
html
๋ณต์ฌํธ์ง
<label for="file">์
๋ก๋ ์งํ:</label>
<progress id="file" value="60" max="100">60%</progress>
๐งญ 4) <meter>
๋ฒ์ ๊ฒ์ด์ง
html
๋ณต์ฌํธ์ง
<label for="score">์ ์:</label>
<meter id="score" value="0.7" min="0" max="1">70%</meter>
๐ 6๏ธโฃ ์ค๋ฌด Best Practice & ์ฌํ ํฌ์ธํธ
ํฌ์ธํธ |
์ค๋ช
|
label for + id ์ ํํ ๋ง์ถ๊ธฐ |
์คํฌ๋ฆฐ๋ฆฌ๋, ํด๋ฆญ UX ๊ฐ์ |
fieldset + legend ์ ๊ทน ํ์ฉ |
๊ทธ๋ฃน ๊ตฌ์กฐ ๋ช
ํ, ์ ๊ทผ์ฑ โ |
HTML5 ๊ฒ์ฆ ์์ฑ (pattern , min , max , step , required ) ์ ๊ทน ํ์ฉ |
๋ณด์ & UX ๊ฐํ |
ํ์ผ ์
๋ก๋ โ accept๋ก ํ์ผ ์ ํ, multiple ํ์ฉ |
์
๋ก๋ ๊ด๋ฆฌ ํธ๋ฆฌ |
progress , meter , output ๋ก ์ค์๊ฐ ์๊ฐํ ์ ๊ณต |
ํ๋์ UI |
๋ณด์: CSRF ํ ํฐ ๋ฐ๋์ ํผ ์์ ํฌํจ |
POST ์ ์ก ์ ํ์ |
autocomplete="off" ๋ก ๋ฏผ๊ฐ ๋ฐ์ดํฐ ์
๋ ฅ UX ์ ์ด |
๋น๋ฐ๋ฒํธ ํ๋ ๋ฑ์์ ์ฌ์ฉ |
๐ผ 7๏ธโฃ ๊ธฐ์ ๋ฉด์ ์์ ์ง๋ฌธ (๊ณ ๊ธ)
์ง๋ฌธ |
ํฌ์ธํธ ์ ๋ฆฌ |
GET vs POST์ ๋ณด์ ์ฐจ์ด๋? |
GET: URL ๋
ธ์ถ, ์บ์ฑ, ๋ฐ์ดํฐ ์ ์ / POST: ๋ฐ์ดํฐ ์จ๊น, ๋๋ ๋ฐ์ดํฐ ๊ฐ๋ฅ |
<label> ๊ณผ <legend> ์ ๊ทผ์ฑ ํจ๊ณผ๋? |
์คํฌ๋ฆฐ๋ฆฌ๋ ํ์์ฑ ํฅ์, UX ๊ฐ์ |
<datalist> vs <select> ์ฐจ์ด์ ์? |
datalist: ์์ ์
๋ ฅ+์ถ์ฒ / select: ๊ณ ์ ์ต์
|
<progress> ์ <meter> ์ฐจ์ด์ ์? |
progress: ์งํ๋ฅ , ๋ถํ์ ๊ฐ๋ฅ / meter: ๋ฒ์ ๋ด ์์น |
CSRF ๊ณต๊ฒฉ ๋์ ๋ฐฉ๋ฒ์? |
CSRF Token hidden ํ๋ ์ฌ์ฉ, SameSite Cookie ์ ์ฑ
ํ์ฉ |
novalidate ์์ฑ์ ์ค๋ฌด ํ์ฉ์? |
๋ธ๋ผ์ฐ์ ๊ธฐ๋ณธ ๊ฒ์ฆ ํด์ โ ์ปค์คํ
JS ๊ฒ์ฆ ์ ์ฉ |
๐ 8๏ธโฃ ๋ ์ฌํ ์ํ์๋์?
- ARIA ์์ฑ๊ณผ ํผ ํ๊ทธ ์ ๊ทผ์ฑ ์ฌํ
- ๋ณด์ ์ด์ (CSRF, XSS) ๋์ ์ค์ ์ ์ฉ๋ฒ
- ์ค๋ฌด์์ ์์ฃผ ๋ฐ์ํ๋ UX ๋ฌธ์ & ํด๊ฒฐ๋ฒ
- HTML5 ๊ฒ์ฆ ์์ฑ ์์ ๋ง์คํฐ
- React, Vue์์ ํผ ๊ด๋ฆฌ ํจํด๊น์ง ํ์ฅ ๊ฐ๋ฅ
ํ์ํ์๋ฉด ๋ฐ๋ก ๋ ์ฌํํด์ ์ ๋ฆฌํด๋๋ฆด๊ฒ์! ๐๐ฅ