[{"data":1,"prerenderedAt":3267},["ShallowReactive",2],{"blog-post-\u002Fko\u002Fsemantic-html-common-mistakes":3,"blog-related-source":2975},{"id":4,"title":5,"body":6,"description":2964,"extension":2965,"meta":2966,"navigation":157,"path":2970,"seo":2971,"sitemap":2972,"stem":2973,"__hash__":2974},"ko\u002Fko\u002Fsemantic-html-common-mistakes.md","의미 있는 HTML 쓰기: 대부분이 하는 시맨틱 HTML 실수 7가지",{"type":7,"value":8,"toc":2946},"minimark",[9,14,27,520,535,541,548,617,620,623,629,632,713,718,751,762,1115,1141,1143,1147,1155,1168,1316,1331,1333,1337,1356,1458,1478,1480,1488,1502,1721,1733,1738,1749,1764,1766,1774,1779,1827,1937,1953,1955,1962,1969,2218,2225,2227,2234,2247,2369,2575,2602,2604,2608,2618,2623,2642,2644,2648,2702,2810,2812,2816,2932,2942],[10,11,13],"h2",{"id":12},"보기엔-똑같은데-뭐가-다를까","보기엔 똑같은데, 뭐가 다를까?",[15,16,17,18,22,23,26],"p",{},"아래 미리보기에는 카드 두 개가 있다. 하나는 전부 ",[19,20,21],"code",{},"div","로, 하나는 의미에 맞는 태그로 만들었다. 겉모습은 완전히 같다. 아래 ",[19,24,25],{},"html"," 탭에서 코드를 비교해보자.",[28,29,30,254],"code-group",{},[31,32,36],"pre",{"className":33,"code":34,"language":25,"meta":35,"style":35},"language-html shiki shiki-themes github-light github-dark","\u003Cdiv class=\"card\">\n  \u003Cdiv class=\"title\">div로 만든 카드\u003C\u002Fdiv>\n  \u003Cdiv class=\"text\">모든 걸 div로 만들었다.\u003C\u002Fdiv>\n  \u003Cdiv class=\"btn\" onclick=\"alert('클릭!')\">자세히 보기\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\u003Carticle class=\"card\">\n  \u003Ch2 class=\"title\">시맨틱 태그로 만든 카드\u003C\u002Fh2>\n  \u003Cp class=\"text\">의미에 맞는 태그를 썼다.\u003C\u002Fp>\n  \u003Cbutton class=\"btn\" onclick=\"alert('클릭!')\">자세히 보기\u003C\u002Fbutton>\n\u003C\u002Farticle>\n","",[19,37,38,64,86,107,142,152,159,175,195,215,245],{"__ignoreMap":35},[39,40,43,47,50,54,57,61],"span",{"class":41,"line":42},"line",1,[39,44,46],{"class":45},"sVt8B","\u003C",[39,48,21],{"class":49},"s9eBZ",[39,51,53],{"class":52},"sScJk"," class",[39,55,56],{"class":45},"=",[39,58,60],{"class":59},"sZZnC","\"card\"",[39,62,63],{"class":45},">\n",[39,65,67,70,72,74,76,79,82,84],{"class":41,"line":66},2,[39,68,69],{"class":45},"  \u003C",[39,71,21],{"class":49},[39,73,53],{"class":52},[39,75,56],{"class":45},[39,77,78],{"class":59},"\"title\"",[39,80,81],{"class":45},">div로 만든 카드\u003C\u002F",[39,83,21],{"class":49},[39,85,63],{"class":45},[39,87,89,91,93,95,97,100,103,105],{"class":41,"line":88},3,[39,90,69],{"class":45},[39,92,21],{"class":49},[39,94,53],{"class":52},[39,96,56],{"class":45},[39,98,99],{"class":59},"\"text\"",[39,101,102],{"class":45},">모든 걸 div로 만들었다.\u003C\u002F",[39,104,21],{"class":49},[39,106,63],{"class":45},[39,108,110,112,114,116,118,121,124,126,129,132,135,138,140],{"class":41,"line":109},4,[39,111,69],{"class":45},[39,113,21],{"class":49},[39,115,53],{"class":52},[39,117,56],{"class":45},[39,119,120],{"class":59},"\"btn\"",[39,122,123],{"class":52}," onclick",[39,125,56],{"class":45},[39,127,128],{"class":59},"\"",[39,130,131],{"class":52},"alert",[39,133,134],{"class":59},"('클릭!')\"",[39,136,137],{"class":45},">자세히 보기\u003C\u002F",[39,139,21],{"class":49},[39,141,63],{"class":45},[39,143,145,148,150],{"class":41,"line":144},5,[39,146,147],{"class":45},"\u003C\u002F",[39,149,21],{"class":49},[39,151,63],{"class":45},[39,153,155],{"class":41,"line":154},6,[39,156,158],{"emptyLinePlaceholder":157},true,"\n",[39,160,162,164,167,169,171,173],{"class":41,"line":161},7,[39,163,46],{"class":45},[39,165,166],{"class":49},"article",[39,168,53],{"class":52},[39,170,56],{"class":45},[39,172,60],{"class":59},[39,174,63],{"class":45},[39,176,178,180,182,184,186,188,191,193],{"class":41,"line":177},8,[39,179,69],{"class":45},[39,181,10],{"class":49},[39,183,53],{"class":52},[39,185,56],{"class":45},[39,187,78],{"class":59},[39,189,190],{"class":45},">시맨틱 태그로 만든 카드\u003C\u002F",[39,192,10],{"class":49},[39,194,63],{"class":45},[39,196,198,200,202,204,206,208,211,213],{"class":41,"line":197},9,[39,199,69],{"class":45},[39,201,15],{"class":49},[39,203,53],{"class":52},[39,205,56],{"class":45},[39,207,99],{"class":59},[39,209,210],{"class":45},">의미에 맞는 태그를 썼다.\u003C\u002F",[39,212,15],{"class":49},[39,214,63],{"class":45},[39,216,218,220,223,225,227,229,231,233,235,237,239,241,243],{"class":41,"line":217},10,[39,219,69],{"class":45},[39,221,222],{"class":49},"button",[39,224,53],{"class":52},[39,226,56],{"class":45},[39,228,120],{"class":59},[39,230,123],{"class":52},[39,232,56],{"class":45},[39,234,128],{"class":59},[39,236,131],{"class":52},[39,238,134],{"class":59},[39,240,137],{"class":45},[39,242,222],{"class":49},[39,244,63],{"class":45},[39,246,248,250,252],{"class":41,"line":247},11,[39,249,147],{"class":45},[39,251,166],{"class":49},[39,253,63],{"class":45},[31,255,259],{"className":256,"code":257,"language":258,"meta":35,"style":35},"language-css shiki shiki-themes github-light github-dark",".card { border: 1px solid #ddd; border-radius: 12px; padding: 16px; margin-bottom: 12px; max-width: 320px; }\n.title { font-size: 18px; font-weight: 700; margin: 0 0 6px; }\n.text { color: #555; margin: 0 0 12px; }\n.btn { display: inline-block; font: inherit; font-size: 14px; padding: 6px 12px; border: 0; border-radius: 8px; background: #f59e0b; color: #fff; cursor: pointer; }\n","css",[19,260,261,340,387,419],{"__ignoreMap":35},[39,262,263,266,269,273,276,279,283,286,289,292,295,297,300,302,304,307,309,312,314,316,319,321,323,325,327,330,332,335,337],{"class":41,"line":42},[39,264,265],{"class":52},".card",[39,267,268],{"class":45}," { ",[39,270,272],{"class":271},"sj4cs","border",[39,274,275],{"class":45},": ",[39,277,278],{"class":271},"1",[39,280,282],{"class":281},"szBVR","px",[39,284,285],{"class":271}," solid",[39,287,288],{"class":271}," #ddd",[39,290,291],{"class":45},"; ",[39,293,294],{"class":271},"border-radius",[39,296,275],{"class":45},[39,298,299],{"class":271},"12",[39,301,282],{"class":281},[39,303,291],{"class":45},[39,305,306],{"class":271},"padding",[39,308,275],{"class":45},[39,310,311],{"class":271},"16",[39,313,282],{"class":281},[39,315,291],{"class":45},[39,317,318],{"class":271},"margin-bottom",[39,320,275],{"class":45},[39,322,299],{"class":271},[39,324,282],{"class":281},[39,326,291],{"class":45},[39,328,329],{"class":271},"max-width",[39,331,275],{"class":45},[39,333,334],{"class":271},"320",[39,336,282],{"class":281},[39,338,339],{"class":45},"; }\n",[39,341,342,345,347,350,352,355,357,359,362,364,367,369,372,374,377,380,383,385],{"class":41,"line":66},[39,343,344],{"class":52},".title",[39,346,268],{"class":45},[39,348,349],{"class":271},"font-size",[39,351,275],{"class":45},[39,353,354],{"class":271},"18",[39,356,282],{"class":281},[39,358,291],{"class":45},[39,360,361],{"class":271},"font-weight",[39,363,275],{"class":45},[39,365,366],{"class":271},"700",[39,368,291],{"class":45},[39,370,371],{"class":271},"margin",[39,373,275],{"class":45},[39,375,376],{"class":271},"0",[39,378,379],{"class":271}," 0",[39,381,382],{"class":271}," 6",[39,384,282],{"class":281},[39,386,339],{"class":45},[39,388,389,392,394,397,399,402,404,406,408,410,412,415,417],{"class":41,"line":88},[39,390,391],{"class":52},".text",[39,393,268],{"class":45},[39,395,396],{"class":271},"color",[39,398,275],{"class":45},[39,400,401],{"class":271},"#555",[39,403,291],{"class":45},[39,405,371],{"class":271},[39,407,275],{"class":45},[39,409,376],{"class":271},[39,411,379],{"class":271},[39,413,414],{"class":271}," 12",[39,416,282],{"class":281},[39,418,339],{"class":45},[39,420,421,424,426,429,431,434,436,439,441,444,446,448,450,453,455,457,459,461,464,466,468,470,472,474,476,478,480,482,484,487,489,491,494,496,499,501,503,505,508,510,513,515,518],{"class":41,"line":109},[39,422,423],{"class":52},".btn",[39,425,268],{"class":45},[39,427,428],{"class":271},"display",[39,430,275],{"class":45},[39,432,433],{"class":271},"inline-block",[39,435,291],{"class":45},[39,437,438],{"class":271},"font",[39,440,275],{"class":45},[39,442,443],{"class":271},"inherit",[39,445,291],{"class":45},[39,447,349],{"class":271},[39,449,275],{"class":45},[39,451,452],{"class":271},"14",[39,454,282],{"class":281},[39,456,291],{"class":45},[39,458,306],{"class":271},[39,460,275],{"class":45},[39,462,463],{"class":271},"6",[39,465,282],{"class":281},[39,467,414],{"class":271},[39,469,282],{"class":281},[39,471,291],{"class":45},[39,473,272],{"class":271},[39,475,275],{"class":45},[39,477,376],{"class":271},[39,479,291],{"class":45},[39,481,294],{"class":271},[39,483,275],{"class":45},[39,485,486],{"class":271},"8",[39,488,282],{"class":281},[39,490,291],{"class":45},[39,492,493],{"class":271},"background",[39,495,275],{"class":45},[39,497,498],{"class":271},"#f59e0b",[39,500,291],{"class":45},[39,502,396],{"class":271},[39,504,275],{"class":45},[39,506,507],{"class":271},"#fff",[39,509,291],{"class":45},[39,511,512],{"class":271},"cursor",[39,514,275],{"class":45},[39,516,517],{"class":271},"pointer",[39,519,339],{"class":45},[15,521,522,523,531,532,534],{},"마우스로 클릭하면 둘 다 잘 동작한다. 그런데 ",[524,525,526,527,530],"strong",{},"미리보기 안을 한 번 클릭하고 ",[19,528,529],{},"Tab"," 키를 눌러보자."," 포커스는 두 번째 카드의 버튼으로만 간다. ",[19,533,21],{},"로 만든 버튼은 키보드로는 아예 닿을 수 없다.",[536,537,538],"blockquote",{},[15,539,540],{},"시맨틱 HTML(Semantic HTML)은 \"어떻게 보이는지\"가 아니라 \"무엇인지\"를 기준으로 태그를 고르는 것이다. 모양은 CSS가 담당하고, 태그는 의미를 담당한다.",[15,542,543,544,547],{},"화면을 눈으로 보는 사람에게는 차이가 없지만, HTML을 ",[524,545,546],{},"읽는"," 쪽에게는 차이가 크다.",[549,550,551,564],"table",{},[552,553,554],"thead",{},[555,556,557,561],"tr",{},[558,559,560],"th",{},"누가 HTML을 읽나",[558,562,563],{},"의미 있는 태그를 쓰면",[565,566,567,578,586,594,602],"tbody",{},[555,568,569,573],{},[570,571,572],"td",{},"키보드 사용자",[570,574,575,577],{},[19,576,529],{},"으로 버튼, 링크, 입력칸을 오갈 수 있다",[555,579,580,583],{},[570,581,582],{},"스크린 리더(Screen Reader)",[570,584,585],{},"\"버튼\", \"제목 2단계\", \"탐색 영역\"처럼 역할을 읽어준다",[555,587,588,591],{},[570,589,590],{},"검색 엔진",[570,592,593],{},"본문, 제목, 내비게이션을 구분해서 핵심 내용을 파악한다",[555,595,596,599],{},[570,597,598],{},"브라우저",[570,600,601],{},"읽기 모드, 자동 번역, 자동완성이 더 정확해진다",[555,603,604,607],{},[570,605,606],{},"다음에 코드를 볼 개발자",[570,608,609,612,613,616],{},[19,610,611],{},"div class=\"header\"","보다 ",[19,614,615],{},"header","가 한눈에 읽힌다",[15,618,619],{},"이제 실무에서 정말 자주 보이는 실수들을 하나씩 보자.",[621,622],"hr",{},[10,624,626,627],{"id":625},"실수-1-클릭되는-div","실수 1. 클릭되는 ",[19,628,21],{},[15,630,631],{},"가장 흔하고, 가장 영향이 큰 실수다.",[31,633,635],{"className":33,"code":634,"language":25,"meta":35,"style":35},"\u003C!-- ❌ -->\n\u003Cdiv class=\"btn\" onclick=\"save()\">저장\u003C\u002Fdiv>\n\n\u003C!-- ✅ -->\n\u003Cbutton type=\"button\" onclick=\"save()\">저장\u003C\u002Fbutton>\n",[19,636,637,643,674,678,683],{"__ignoreMap":35},[39,638,639],{"class":41,"line":42},[39,640,642],{"class":641},"sJ8bj","\u003C!-- ❌ -->\n",[39,644,645,647,649,651,653,655,657,659,661,664,667,670,672],{"class":41,"line":66},[39,646,46],{"class":45},[39,648,21],{"class":49},[39,650,53],{"class":52},[39,652,56],{"class":45},[39,654,120],{"class":59},[39,656,123],{"class":52},[39,658,56],{"class":45},[39,660,128],{"class":59},[39,662,663],{"class":52},"save",[39,665,666],{"class":59},"()\"",[39,668,669],{"class":45},">저장\u003C\u002F",[39,671,21],{"class":49},[39,673,63],{"class":45},[39,675,676],{"class":41,"line":88},[39,677,158],{"emptyLinePlaceholder":157},[39,679,680],{"class":41,"line":109},[39,681,682],{"class":641},"\u003C!-- ✅ -->\n",[39,684,685,687,689,692,694,697,699,701,703,705,707,709,711],{"class":41,"line":144},[39,686,46],{"class":45},[39,688,222],{"class":49},[39,690,691],{"class":52}," type",[39,693,56],{"class":45},[39,695,696],{"class":59},"\"button\"",[39,698,123],{"class":52},[39,700,56],{"class":45},[39,702,128],{"class":59},[39,704,663],{"class":52},[39,706,666],{"class":59},[39,708,669],{"class":45},[39,710,222],{"class":49},[39,712,63],{"class":45},[15,714,715,717],{},[19,716,21],{},"로 버튼을 제대로 흉내 내려면 이만큼이 필요하다.",[719,720,721,728,734,744],"ul",{},[722,723,724,727],"li",{},[19,725,726],{},"tabindex=\"0\"","을 붙여 키보드 포커스를 받게 하고",[722,729,730,733],{},[19,731,732],{},"role=\"button\"","으로 스크린 리더에 버튼이라고 알리고",[722,735,736,739,740,743],{},[19,737,738],{},"Enter","와 ",[19,741,742],{},"Space"," 키 이벤트를 직접 처리하고",[722,745,746,747,750],{},"비활성화 상태(",[19,748,749],{},"disabled",")도 직접 구현한다",[15,752,753,755,756,758,759,761],{},[19,754,222],{}," 태그 하나면 이 모든 게 기본으로 따라온다. 아래 미리보기 안을 클릭한 다음 ",[19,757,529],{},"으로 포커스를 옮기고 ",[19,760,738],{},"를 눌러보자.",[28,763,764,830,994],{},[31,765,767],{"className":33,"code":766,"language":25,"meta":35,"style":35},"\u003Cdiv class=\"fake\">div 버튼\u003C\u002Fdiv>\n\u003Cbutton class=\"real\">진짜 버튼\u003C\u002Fbutton>\n\u003Cp id=\"out\">미리보기 안을 클릭한 뒤 Tab → Enter를 눌러보세요.\u003C\u002Fp>\n",[19,768,769,789,809],{"__ignoreMap":35},[39,770,771,773,775,777,779,782,785,787],{"class":41,"line":42},[39,772,46],{"class":45},[39,774,21],{"class":49},[39,776,53],{"class":52},[39,778,56],{"class":45},[39,780,781],{"class":59},"\"fake\"",[39,783,784],{"class":45},">div 버튼\u003C\u002F",[39,786,21],{"class":49},[39,788,63],{"class":45},[39,790,791,793,795,797,799,802,805,807],{"class":41,"line":66},[39,792,46],{"class":45},[39,794,222],{"class":49},[39,796,53],{"class":52},[39,798,56],{"class":45},[39,800,801],{"class":59},"\"real\"",[39,803,804],{"class":45},">진짜 버튼\u003C\u002F",[39,806,222],{"class":49},[39,808,63],{"class":45},[39,810,811,813,815,818,820,823,826,828],{"class":41,"line":88},[39,812,46],{"class":45},[39,814,15],{"class":49},[39,816,817],{"class":52}," id",[39,819,56],{"class":45},[39,821,822],{"class":59},"\"out\"",[39,824,825],{"class":45},">미리보기 안을 클릭한 뒤 Tab → Enter를 눌러보세요.\u003C\u002F",[39,827,15],{"class":49},[39,829,63],{"class":45},[31,831,833],{"className":256,"code":832,"language":258,"meta":35,"style":35},".fake, .real { font: inherit; padding: 8px 14px; margin-right: 8px; border-radius: 8px; border: 1px solid #999; background: #f4f4f5; cursor: pointer; display: inline-block; }\n.real:focus-visible { outline: 3px solid #f59e0b; outline-offset: 2px; }\n#out { margin-top: 16px; color: #555; }\n",[19,834,835,932,968],{"__ignoreMap":35},[39,836,837,840,843,846,848,850,852,854,856,858,860,862,864,867,869,871,874,876,878,880,882,884,886,888,890,892,894,896,898,900,902,905,907,909,911,914,916,918,920,922,924,926,928,930],{"class":41,"line":42},[39,838,839],{"class":52},".fake",[39,841,842],{"class":45},", ",[39,844,845],{"class":52},".real",[39,847,268],{"class":45},[39,849,438],{"class":271},[39,851,275],{"class":45},[39,853,443],{"class":271},[39,855,291],{"class":45},[39,857,306],{"class":271},[39,859,275],{"class":45},[39,861,486],{"class":271},[39,863,282],{"class":281},[39,865,866],{"class":271}," 14",[39,868,282],{"class":281},[39,870,291],{"class":45},[39,872,873],{"class":271},"margin-right",[39,875,275],{"class":45},[39,877,486],{"class":271},[39,879,282],{"class":281},[39,881,291],{"class":45},[39,883,294],{"class":271},[39,885,275],{"class":45},[39,887,486],{"class":271},[39,889,282],{"class":281},[39,891,291],{"class":45},[39,893,272],{"class":271},[39,895,275],{"class":45},[39,897,278],{"class":271},[39,899,282],{"class":281},[39,901,285],{"class":271},[39,903,904],{"class":271}," #999",[39,906,291],{"class":45},[39,908,493],{"class":271},[39,910,275],{"class":45},[39,912,913],{"class":271},"#f4f4f5",[39,915,291],{"class":45},[39,917,512],{"class":271},[39,919,275],{"class":45},[39,921,517],{"class":271},[39,923,291],{"class":45},[39,925,428],{"class":271},[39,927,275],{"class":45},[39,929,433],{"class":271},[39,931,339],{"class":45},[39,933,934,937,939,942,944,947,949,951,954,956,959,961,964,966],{"class":41,"line":66},[39,935,936],{"class":52},".real:focus-visible",[39,938,268],{"class":45},[39,940,941],{"class":271},"outline",[39,943,275],{"class":45},[39,945,946],{"class":271},"3",[39,948,282],{"class":281},[39,950,285],{"class":271},[39,952,953],{"class":271}," #f59e0b",[39,955,291],{"class":45},[39,957,958],{"class":271},"outline-offset",[39,960,275],{"class":45},[39,962,963],{"class":271},"2",[39,965,282],{"class":281},[39,967,339],{"class":45},[39,969,970,973,975,978,980,982,984,986,988,990,992],{"class":41,"line":88},[39,971,972],{"class":52},"#out",[39,974,268],{"class":45},[39,976,977],{"class":271},"margin-top",[39,979,275],{"class":45},[39,981,311],{"class":271},[39,983,282],{"class":281},[39,985,291],{"class":45},[39,987,396],{"class":271},[39,989,275],{"class":45},[39,991,401],{"class":271},[39,993,339],{"class":45},[31,995,999],{"className":996,"code":997,"language":998,"meta":35,"style":35},"language-js shiki shiki-themes github-light github-dark","const out = (msg) => (document.getElementById(\"out\").textContent = msg);\ndocument.querySelector(\".fake\").addEventListener(\"click\", () => out(\"div 버튼 클릭됨 (마우스로만 가능)\"));\ndocument.querySelector(\".real\").addEventListener(\"click\", () => out(\"진짜 버튼 클릭됨 (키보드로도 가능)\"));\n","js",[19,1000,1001,1044,1083],{"__ignoreMap":35},[39,1002,1003,1006,1009,1012,1015,1019,1022,1025,1028,1031,1034,1036,1039,1041],{"class":41,"line":42},[39,1004,1005],{"class":281},"const",[39,1007,1008],{"class":52}," out",[39,1010,1011],{"class":281}," =",[39,1013,1014],{"class":45}," (",[39,1016,1018],{"class":1017},"s4XuR","msg",[39,1020,1021],{"class":45},") ",[39,1023,1024],{"class":281},"=>",[39,1026,1027],{"class":45}," (document.",[39,1029,1030],{"class":52},"getElementById",[39,1032,1033],{"class":45},"(",[39,1035,822],{"class":59},[39,1037,1038],{"class":45},").textContent ",[39,1040,56],{"class":281},[39,1042,1043],{"class":45}," msg);\n",[39,1045,1046,1049,1052,1054,1057,1060,1063,1065,1068,1071,1073,1075,1077,1080],{"class":41,"line":66},[39,1047,1048],{"class":45},"document.",[39,1050,1051],{"class":52},"querySelector",[39,1053,1033],{"class":45},[39,1055,1056],{"class":59},"\".fake\"",[39,1058,1059],{"class":45},").",[39,1061,1062],{"class":52},"addEventListener",[39,1064,1033],{"class":45},[39,1066,1067],{"class":59},"\"click\"",[39,1069,1070],{"class":45},", () ",[39,1072,1024],{"class":281},[39,1074,1008],{"class":52},[39,1076,1033],{"class":45},[39,1078,1079],{"class":59},"\"div 버튼 클릭됨 (마우스로만 가능)\"",[39,1081,1082],{"class":45},"));\n",[39,1084,1085,1087,1089,1091,1094,1096,1098,1100,1102,1104,1106,1108,1110,1113],{"class":41,"line":88},[39,1086,1048],{"class":45},[39,1088,1051],{"class":52},[39,1090,1033],{"class":45},[39,1092,1093],{"class":59},"\".real\"",[39,1095,1059],{"class":45},[39,1097,1062],{"class":52},[39,1099,1033],{"class":45},[39,1101,1067],{"class":59},[39,1103,1070],{"class":45},[39,1105,1024],{"class":281},[39,1107,1008],{"class":52},[39,1109,1033],{"class":45},[39,1111,1112],{"class":59},"\"진짜 버튼 클릭됨 (키보드로도 가능)\"",[39,1114,1082],{"class":45},[1116,1117,1118],"tip",{},[536,1119,1120],{},[15,1121,1122,1125,1126,1128,1129,1132,1133,1136,1137,1140],{},[19,1123,1124],{},"form"," 안의 ",[19,1127,222],{},"은 기본 ",[19,1130,1131],{},"type","이 ",[19,1134,1135],{},"submit","이다. 폼을 제출하지 않는 버튼이라면 ",[19,1138,1139],{},"type=\"button\"","을 꼭 적어주자. 그렇지 않으면 누를 때마다 폼이 제출된다.",[621,1142],{},[10,1144,1146],{"id":1145},"실수-2-링크와-버튼을-섞어-쓰기","실수 2. 링크와 버튼을 섞어 쓰기",[15,1148,1149,739,1152,1154],{},[19,1150,1151],{},"a",[19,1153,222],{},"은 둘 다 \"누르는 것\"이라 헷갈리기 쉽지만, 기준은 간단하다.",[536,1156,1157],{},[15,1158,1159],{},[524,1160,1161,1162,1164,1165,1167],{},"다른 곳으로 이동하면 ",[19,1163,1151],{},", 현재 화면에서 무언가를 실행하면 ",[19,1166,222],{},".",[31,1169,1171],{"className":33,"code":1170,"language":25,"meta":35,"style":35},"\u003C!-- ❌ 이동하지 않는데 링크를 씀 -->\n\u003Ca href=\"#\" onclick=\"openModal()\">로그인\u003C\u002Fa>\n\n\u003C!-- ✅ 화면 안에서 동작하니 버튼 -->\n\u003Cbutton type=\"button\" onclick=\"openModal()\">로그인\u003C\u002Fbutton>\n\n\u003C!-- ❌ 페이지 이동인데 버튼을 씀 -->\n\u003Cbutton onclick=\"location.href='\u002Fpricing'\">요금제 보기\u003C\u002Fbutton>\n\n\u003C!-- ✅ 이동이니 링크 -->\n\u003Ca href=\"\u002Fpricing\">요금제 보기\u003C\u002Fa>\n",[19,1172,1173,1178,1210,1214,1219,1247,1251,1256,1288,1292,1297],{"__ignoreMap":35},[39,1174,1175],{"class":41,"line":42},[39,1176,1177],{"class":641},"\u003C!-- ❌ 이동하지 않는데 링크를 씀 -->\n",[39,1179,1180,1182,1184,1187,1189,1192,1194,1196,1198,1201,1203,1206,1208],{"class":41,"line":66},[39,1181,46],{"class":45},[39,1183,1151],{"class":49},[39,1185,1186],{"class":52}," href",[39,1188,56],{"class":45},[39,1190,1191],{"class":59},"\"#\"",[39,1193,123],{"class":52},[39,1195,56],{"class":45},[39,1197,128],{"class":59},[39,1199,1200],{"class":52},"openModal",[39,1202,666],{"class":59},[39,1204,1205],{"class":45},">로그인\u003C\u002F",[39,1207,1151],{"class":49},[39,1209,63],{"class":45},[39,1211,1212],{"class":41,"line":88},[39,1213,158],{"emptyLinePlaceholder":157},[39,1215,1216],{"class":41,"line":109},[39,1217,1218],{"class":641},"\u003C!-- ✅ 화면 안에서 동작하니 버튼 -->\n",[39,1220,1221,1223,1225,1227,1229,1231,1233,1235,1237,1239,1241,1243,1245],{"class":41,"line":144},[39,1222,46],{"class":45},[39,1224,222],{"class":49},[39,1226,691],{"class":52},[39,1228,56],{"class":45},[39,1230,696],{"class":59},[39,1232,123],{"class":52},[39,1234,56],{"class":45},[39,1236,128],{"class":59},[39,1238,1200],{"class":52},[39,1240,666],{"class":59},[39,1242,1205],{"class":45},[39,1244,222],{"class":49},[39,1246,63],{"class":45},[39,1248,1249],{"class":41,"line":154},[39,1250,158],{"emptyLinePlaceholder":157},[39,1252,1253],{"class":41,"line":161},[39,1254,1255],{"class":641},"\u003C!-- ❌ 페이지 이동인데 버튼을 씀 -->\n",[39,1257,1258,1260,1262,1264,1266,1268,1271,1273,1276,1278,1281,1284,1286],{"class":41,"line":177},[39,1259,46],{"class":45},[39,1261,222],{"class":49},[39,1263,123],{"class":52},[39,1265,56],{"class":45},[39,1267,128],{"class":59},[39,1269,1270],{"class":45},"location",[39,1272,1167],{"class":59},[39,1274,1275],{"class":45},"href",[39,1277,56],{"class":281},[39,1279,1280],{"class":59},"'\u002Fpricing'\"",[39,1282,1283],{"class":45},">요금제 보기\u003C\u002F",[39,1285,222],{"class":49},[39,1287,63],{"class":45},[39,1289,1290],{"class":41,"line":197},[39,1291,158],{"emptyLinePlaceholder":157},[39,1293,1294],{"class":41,"line":217},[39,1295,1296],{"class":641},"\u003C!-- ✅ 이동이니 링크 -->\n",[39,1298,1299,1301,1303,1305,1307,1310,1312,1314],{"class":41,"line":247},[39,1300,46],{"class":45},[39,1302,1151],{"class":49},[39,1304,1186],{"class":52},[39,1306,56],{"class":45},[39,1308,1309],{"class":59},"\"\u002Fpricing\"",[39,1311,1283],{"class":45},[39,1313,1151],{"class":49},[39,1315,63],{"class":45},[15,1317,1318,1319,1322,1323,1326,1327,1330],{},"링크를 버튼으로 만들면 ",[524,1320,1321],{},"새 탭에서 열기, 주소 복사, 검색 엔진의 링크 수집","이 모두 안 된다. 반대로 ",[19,1324,1325],{},"href=\"#\""," 링크를 버튼처럼 쓰면 누를 때 페이지가 맨 위로 튀거나 주소에 ",[19,1328,1329],{},"#","이 붙는다.",[621,1332],{},[10,1334,1336],{"id":1335},"실수-3-글자-크기로-제목-태그-고르기","실수 3. 글자 크기로 제목 태그 고르기",[15,1338,1339,1340,1343,1344,1347,1348,1351,1352,1355],{},"\"여기는 글씨가 작아야 하니까 ",[19,1341,1342],{},"h4","\"처럼 크기로 고르는 경우가 많다. 하지만 ",[19,1345,1346],{},"h1","~",[19,1349,1350],{},"h6","은 ",[524,1353,1354],{},"문서의 목차(Outline)"," 를 만드는 태그다. 스크린 리더 사용자는 제목만 골라 듣는 기능으로 페이지를 훑어본다.",[31,1357,1359],{"className":33,"code":1358,"language":25,"meta":35,"style":35},"\u003C!-- ❌ 크기에 맞춰 고르다 보니 단계가 뒤죽박죽 -->\n\u003Ch1>쇼핑몰\u003C\u002Fh1>\n\u003Ch4>오늘의 추천\u003C\u002Fh4>\n\u003Ch2>상품 이름\u003C\u002Fh2>\n\n\u003C!-- ✅ 구조대로 쓰고, 크기는 CSS로 -->\n\u003Ch1>쇼핑몰\u003C\u002Fh1>\n\u003Ch2 class=\"section-title\">오늘의 추천\u003C\u002Fh2>\n\u003Ch3>상품 이름\u003C\u002Fh3>\n",[19,1360,1361,1366,1379,1392,1405,1409,1414,1426,1445],{"__ignoreMap":35},[39,1362,1363],{"class":41,"line":42},[39,1364,1365],{"class":641},"\u003C!-- ❌ 크기에 맞춰 고르다 보니 단계가 뒤죽박죽 -->\n",[39,1367,1368,1370,1372,1375,1377],{"class":41,"line":66},[39,1369,46],{"class":45},[39,1371,1346],{"class":49},[39,1373,1374],{"class":45},">쇼핑몰\u003C\u002F",[39,1376,1346],{"class":49},[39,1378,63],{"class":45},[39,1380,1381,1383,1385,1388,1390],{"class":41,"line":88},[39,1382,46],{"class":45},[39,1384,1342],{"class":49},[39,1386,1387],{"class":45},">오늘의 추천\u003C\u002F",[39,1389,1342],{"class":49},[39,1391,63],{"class":45},[39,1393,1394,1396,1398,1401,1403],{"class":41,"line":109},[39,1395,46],{"class":45},[39,1397,10],{"class":49},[39,1399,1400],{"class":45},">상품 이름\u003C\u002F",[39,1402,10],{"class":49},[39,1404,63],{"class":45},[39,1406,1407],{"class":41,"line":144},[39,1408,158],{"emptyLinePlaceholder":157},[39,1410,1411],{"class":41,"line":154},[39,1412,1413],{"class":641},"\u003C!-- ✅ 구조대로 쓰고, 크기는 CSS로 -->\n",[39,1415,1416,1418,1420,1422,1424],{"class":41,"line":161},[39,1417,46],{"class":45},[39,1419,1346],{"class":49},[39,1421,1374],{"class":45},[39,1423,1346],{"class":49},[39,1425,63],{"class":45},[39,1427,1428,1430,1432,1434,1436,1439,1441,1443],{"class":41,"line":177},[39,1429,46],{"class":45},[39,1431,10],{"class":49},[39,1433,53],{"class":52},[39,1435,56],{"class":45},[39,1437,1438],{"class":59},"\"section-title\"",[39,1440,1387],{"class":45},[39,1442,10],{"class":49},[39,1444,63],{"class":45},[39,1446,1447,1449,1452,1454,1456],{"class":41,"line":197},[39,1448,46],{"class":45},[39,1450,1451],{"class":49},"h3",[39,1453,1400],{"class":45},[39,1455,1451],{"class":49},[39,1457,63],{"class":45},[719,1459,1460,1466,1475],{},[722,1461,1462,1463,1465],{},"페이지의 주제를 나타내는 ",[19,1464,1346],{},"은 하나만 두는 것이 무난하다.",[722,1467,1468,1469,1471,1472,1474],{},"단계는 건너뛰지 않는다 (",[19,1470,10],{}," 다음에 바로 ",[19,1473,1342],{}," ❌).",[722,1476,1477],{},"크기를 바꾸고 싶으면 태그가 아니라 CSS를 바꾼다.",[621,1479],{},[10,1481,1483,1484,1487],{"id":1482},"실수-4-label-없는-입력칸","실수 4. ",[19,1485,1486],{},"label"," 없는 입력칸",[15,1489,1490,1491,1494,1495,1497,1498,1501],{},"디자인이 깔끔해 보인다는 이유로 ",[19,1492,1493],{},"placeholder","만 쓰고 ",[19,1496,1486],{},"을 빼는 경우가 많다. 미리보기에서 위아래 체크박스의 ",[524,1499,1500],{},"글자 부분","을 클릭해보자.",[28,1503,1504,1646],{},[31,1505,1507],{"className":33,"code":1506,"language":25,"meta":35,"style":35},"\u003Cp>\u003Cinput type=\"checkbox\" \u002F> 약관에 동의합니다 (label 없음)\u003C\u002Fp>\n\n\u003Cp>\u003Clabel>\u003Cinput type=\"checkbox\" \u002F> 약관에 동의합니다 (label 있음)\u003C\u002Flabel>\u003C\u002Fp>\n\n\u003Cp>\n  \u003Clabel for=\"email\">이메일\u003C\u002Flabel>\u003Cbr \u002F>\n  \u003Cinput id=\"email\" type=\"email\" placeholder=\"you@example.com\" \u002F>\n\u003C\u002Fp>\n",[19,1508,1509,1535,1539,1571,1575,1583,1610,1638],{"__ignoreMap":35},[39,1510,1511,1513,1515,1518,1521,1523,1525,1528,1531,1533],{"class":41,"line":42},[39,1512,46],{"class":45},[39,1514,15],{"class":49},[39,1516,1517],{"class":45},">\u003C",[39,1519,1520],{"class":49},"input",[39,1522,691],{"class":52},[39,1524,56],{"class":45},[39,1526,1527],{"class":59},"\"checkbox\"",[39,1529,1530],{"class":45}," \u002F> 약관에 동의합니다 (label 없음)\u003C\u002F",[39,1532,15],{"class":49},[39,1534,63],{"class":45},[39,1536,1537],{"class":41,"line":66},[39,1538,158],{"emptyLinePlaceholder":157},[39,1540,1541,1543,1545,1547,1549,1551,1553,1555,1557,1559,1562,1564,1567,1569],{"class":41,"line":88},[39,1542,46],{"class":45},[39,1544,15],{"class":49},[39,1546,1517],{"class":45},[39,1548,1486],{"class":49},[39,1550,1517],{"class":45},[39,1552,1520],{"class":49},[39,1554,691],{"class":52},[39,1556,56],{"class":45},[39,1558,1527],{"class":59},[39,1560,1561],{"class":45}," \u002F> 약관에 동의합니다 (label 있음)\u003C\u002F",[39,1563,1486],{"class":49},[39,1565,1566],{"class":45},">\u003C\u002F",[39,1568,15],{"class":49},[39,1570,63],{"class":45},[39,1572,1573],{"class":41,"line":109},[39,1574,158],{"emptyLinePlaceholder":157},[39,1576,1577,1579,1581],{"class":41,"line":144},[39,1578,46],{"class":45},[39,1580,15],{"class":49},[39,1582,63],{"class":45},[39,1584,1585,1587,1589,1592,1594,1597,1600,1602,1604,1607],{"class":41,"line":154},[39,1586,69],{"class":45},[39,1588,1486],{"class":49},[39,1590,1591],{"class":52}," for",[39,1593,56],{"class":45},[39,1595,1596],{"class":59},"\"email\"",[39,1598,1599],{"class":45},">이메일\u003C\u002F",[39,1601,1486],{"class":49},[39,1603,1517],{"class":45},[39,1605,1606],{"class":49},"br",[39,1608,1609],{"class":45}," \u002F>\n",[39,1611,1612,1614,1616,1618,1620,1622,1624,1626,1628,1631,1633,1636],{"class":41,"line":161},[39,1613,69],{"class":45},[39,1615,1520],{"class":49},[39,1617,817],{"class":52},[39,1619,56],{"class":45},[39,1621,1596],{"class":59},[39,1623,691],{"class":52},[39,1625,56],{"class":45},[39,1627,1596],{"class":59},[39,1629,1630],{"class":52}," placeholder",[39,1632,56],{"class":45},[39,1634,1635],{"class":59},"\"you@example.com\"",[39,1637,1609],{"class":45},[39,1639,1640,1642,1644],{"class":41,"line":177},[39,1641,147],{"class":45},[39,1643,15],{"class":49},[39,1645,63],{"class":45},[31,1647,1649],{"className":256,"code":1648,"language":258,"meta":35,"style":35},"p { margin: 0 0 14px; }\ninput[type=\"email\"] { font: inherit; padding: 6px 8px; margin-top: 4px; }\n",[19,1650,1651,1671],{"__ignoreMap":35},[39,1652,1653,1655,1657,1659,1661,1663,1665,1667,1669],{"class":41,"line":42},[39,1654,15],{"class":49},[39,1656,268],{"class":45},[39,1658,371],{"class":271},[39,1660,275],{"class":45},[39,1662,376],{"class":271},[39,1664,379],{"class":271},[39,1666,866],{"class":271},[39,1668,282],{"class":281},[39,1670,339],{"class":45},[39,1672,1673,1675,1678,1680,1682,1684,1687,1689,1691,1693,1695,1697,1699,1701,1703,1706,1708,1710,1712,1714,1717,1719],{"class":41,"line":66},[39,1674,1520],{"class":49},[39,1676,1677],{"class":45},"[",[39,1679,1131],{"class":52},[39,1681,56],{"class":281},[39,1683,1596],{"class":59},[39,1685,1686],{"class":45},"] { ",[39,1688,438],{"class":271},[39,1690,275],{"class":45},[39,1692,443],{"class":271},[39,1694,291],{"class":45},[39,1696,306],{"class":271},[39,1698,275],{"class":45},[39,1700,463],{"class":271},[39,1702,282],{"class":281},[39,1704,1705],{"class":271}," 8",[39,1707,282],{"class":281},[39,1709,291],{"class":45},[39,1711,977],{"class":271},[39,1713,275],{"class":45},[39,1715,1716],{"class":271},"4",[39,1718,282],{"class":281},[39,1720,339],{"class":45},[15,1722,1723,1725,1726,1728,1729,1732],{},[19,1724,1486],{},"이 없는 첫 번째 체크박스는 작은 네모를 정확히 눌러야만 체크된다. ",[19,1727,1486],{},"이 있으면 글자를 눌러도 체크되고, ",[19,1730,1731],{},"이메일","이라는 글자를 누르면 입력칸에 바로 포커스가 간다. 모바일에서는 이 차이가 특히 크다.",[15,1734,1735,1737],{},[19,1736,1493],{},"만으로 안 되는 이유는 이렇다.",[719,1739,1740,1743,1746],{},[722,1741,1742],{},"입력을 시작하면 사라져서, 무엇을 입력하던 칸인지 잊어버린다.",[722,1744,1745],{},"글자색이 흐려서 잘 안 읽힌다.",[722,1747,1748],{},"스크린 리더가 칸의 이름으로 제대로 읽지 못하는 경우가 있다.",[1750,1751,1752],"note",{},[536,1753,1754],{},[15,1755,1756,1757,1759,1760,1763],{},"디자인상 ",[19,1758,1486],{},"을 보이고 싶지 않다면 지우지 말고 화면에서만 숨기는 CSS(흔히 ",[19,1761,1762],{},"sr-only","라는 클래스 이름을 쓴다)를 적용하자. 눈에는 안 보여도 스크린 리더는 읽을 수 있다.",[621,1765],{},[10,1767,1769,1770,1773],{"id":1768},"실수-5-이미지-alt를-빼먹거나-의미-없이-채우기","실수 5. 이미지 ",[19,1771,1772],{},"alt","를 빼먹거나 의미 없이 채우기",[15,1775,1776,1778],{},[19,1777,1772],{},"는 이미지가 보이지 않을 때(스크린 리더, 이미지 로딩 실패, 검색 엔진) 그 자리를 대신하는 텍스트다.",[549,1780,1781,1791],{},[552,1782,1783],{},[555,1784,1785,1788],{},[558,1786,1787],{},"상황",[558,1789,1790],{},"이렇게 쓴다",[565,1792,1793,1804,1816],{},[555,1794,1795,1798],{},[570,1796,1797],{},"내용을 전달하는 이미지",[570,1799,1800,1801],{},"이미지가 전하는 내용을 문장으로: ",[19,1802,1803],{},"alt=\"3분기 매출이 20% 늘어난 막대그래프\"",[555,1805,1806,1809],{},[570,1807,1808],{},"장식용 이미지 (배경 무늬, 아이콘 옆 장식)",[570,1810,1811,1812,1815],{},"빈 값: ",[19,1813,1814],{},"alt=\"\""," (스크린 리더가 건너뜀)",[555,1817,1818,1821],{},[570,1819,1820],{},"링크나 버튼 안의 아이콘",[570,1822,1823,1824],{},"동작을 설명: ",[19,1825,1826],{},"alt=\"장바구니로 이동\"",[31,1828,1830],{"className":33,"code":1829,"language":25,"meta":35,"style":35},"\u003C!-- ❌ alt가 없으면 스크린 리더가 파일 이름을 읽기도 한다 (\"아이엠지 공일이삼 점 피엔지\") -->\n\u003Cimg src=\"img_0123.png\" \u002F>\n\n\u003C!-- ❌ 의미 없는 alt -->\n\u003Cimg src=\"chart.png\" alt=\"이미지\" \u002F>\n\n\u003C!-- ✅ -->\n\u003Cimg src=\"chart.png\" alt=\"3분기 매출이 20% 늘어난 막대그래프\" \u002F>\n\u003Cimg src=\"divider.svg\" alt=\"\" \u002F>\n",[19,1831,1832,1837,1854,1858,1863,1886,1890,1894,1915],{"__ignoreMap":35},[39,1833,1834],{"class":41,"line":42},[39,1835,1836],{"class":641},"\u003C!-- ❌ alt가 없으면 스크린 리더가 파일 이름을 읽기도 한다 (\"아이엠지 공일이삼 점 피엔지\") -->\n",[39,1838,1839,1841,1844,1847,1849,1852],{"class":41,"line":66},[39,1840,46],{"class":45},[39,1842,1843],{"class":49},"img",[39,1845,1846],{"class":52}," src",[39,1848,56],{"class":45},[39,1850,1851],{"class":59},"\"img_0123.png\"",[39,1853,1609],{"class":45},[39,1855,1856],{"class":41,"line":88},[39,1857,158],{"emptyLinePlaceholder":157},[39,1859,1860],{"class":41,"line":109},[39,1861,1862],{"class":641},"\u003C!-- ❌ 의미 없는 alt -->\n",[39,1864,1865,1867,1869,1871,1873,1876,1879,1881,1884],{"class":41,"line":144},[39,1866,46],{"class":45},[39,1868,1843],{"class":49},[39,1870,1846],{"class":52},[39,1872,56],{"class":45},[39,1874,1875],{"class":59},"\"chart.png\"",[39,1877,1878],{"class":52}," alt",[39,1880,56],{"class":45},[39,1882,1883],{"class":59},"\"이미지\"",[39,1885,1609],{"class":45},[39,1887,1888],{"class":41,"line":154},[39,1889,158],{"emptyLinePlaceholder":157},[39,1891,1892],{"class":41,"line":161},[39,1893,682],{"class":641},[39,1895,1896,1898,1900,1902,1904,1906,1908,1910,1913],{"class":41,"line":177},[39,1897,46],{"class":45},[39,1899,1843],{"class":49},[39,1901,1846],{"class":52},[39,1903,56],{"class":45},[39,1905,1875],{"class":59},[39,1907,1878],{"class":52},[39,1909,56],{"class":45},[39,1911,1912],{"class":59},"\"3분기 매출이 20% 늘어난 막대그래프\"",[39,1914,1609],{"class":45},[39,1916,1917,1919,1921,1923,1925,1928,1930,1932,1935],{"class":41,"line":197},[39,1918,46],{"class":45},[39,1920,1843],{"class":49},[39,1922,1846],{"class":52},[39,1924,56],{"class":45},[39,1926,1927],{"class":59},"\"divider.svg\"",[39,1929,1878],{"class":52},[39,1931,56],{"class":45},[39,1933,1934],{"class":59},"\"\"",[39,1936,1609],{"class":45},[15,1938,1939,1941,1942,1945,1946,1952],{},[19,1940,1772],{}," 속성을 ",[524,1943,1944],{},"아예 빼는 것","과 ",[524,1947,1948,1949,1951],{},"빈 값(",[19,1950,1814],{},")으로 두는 것","은 다르다. 빈 값은 \"장식이니 건너뛰어도 된다\"는 뜻이고, 빠진 건 \"깜빡했다\"는 뜻이다.",[621,1954],{},[10,1956,1958,1959,1961],{"id":1957},"실수-6-목록을-div로-나열하기","실수 6. 목록을 ",[19,1960,21],{},"로 나열하기",[15,1963,1964,1965,1968],{},"메뉴, 태그 목록, 검색 결과처럼 ",[524,1966,1967],{},"같은 종류가 반복되면 목록","이다.",[31,1970,1972],{"className":33,"code":1971,"language":25,"meta":35,"style":35},"\u003C!-- ❌ -->\n\u003Cdiv class=\"menu\">\n  \u003Cdiv>\u003Ca href=\"\u002F\">홈\u003C\u002Fa>\u003C\u002Fdiv>\n  \u003Cdiv>\u003Ca href=\"\u002Fblog\">블로그\u003C\u002Fa>\u003C\u002Fdiv>\n  \u003Cdiv>\u003Ca href=\"\u002Fabout\">소개\u003C\u002Fa>\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\u003C!-- ✅ -->\n\u003Cnav aria-label=\"주요 메뉴\">\n  \u003Cul>\n    \u003Cli>\u003Ca href=\"\u002F\">홈\u003C\u002Fa>\u003C\u002Fli>\n    \u003Cli>\u003Ca href=\"\u002Fblog\">블로그\u003C\u002Fa>\u003C\u002Fli>\n    \u003Cli>\u003Ca href=\"\u002Fabout\">소개\u003C\u002Fa>\u003C\u002Fli>\n  \u003C\u002Ful>\n\u003C\u002Fnav>\n",[19,1973,1974,1978,1993,2021,2049,2077,2085,2089,2093,2110,2118,2145,2172,2199,2209],{"__ignoreMap":35},[39,1975,1976],{"class":41,"line":42},[39,1977,642],{"class":641},[39,1979,1980,1982,1984,1986,1988,1991],{"class":41,"line":66},[39,1981,46],{"class":45},[39,1983,21],{"class":49},[39,1985,53],{"class":52},[39,1987,56],{"class":45},[39,1989,1990],{"class":59},"\"menu\"",[39,1992,63],{"class":45},[39,1994,1995,1997,1999,2001,2003,2005,2007,2010,2013,2015,2017,2019],{"class":41,"line":88},[39,1996,69],{"class":45},[39,1998,21],{"class":49},[39,2000,1517],{"class":45},[39,2002,1151],{"class":49},[39,2004,1186],{"class":52},[39,2006,56],{"class":45},[39,2008,2009],{"class":59},"\"\u002F\"",[39,2011,2012],{"class":45},">홈\u003C\u002F",[39,2014,1151],{"class":49},[39,2016,1566],{"class":45},[39,2018,21],{"class":49},[39,2020,63],{"class":45},[39,2022,2023,2025,2027,2029,2031,2033,2035,2038,2041,2043,2045,2047],{"class":41,"line":109},[39,2024,69],{"class":45},[39,2026,21],{"class":49},[39,2028,1517],{"class":45},[39,2030,1151],{"class":49},[39,2032,1186],{"class":52},[39,2034,56],{"class":45},[39,2036,2037],{"class":59},"\"\u002Fblog\"",[39,2039,2040],{"class":45},">블로그\u003C\u002F",[39,2042,1151],{"class":49},[39,2044,1566],{"class":45},[39,2046,21],{"class":49},[39,2048,63],{"class":45},[39,2050,2051,2053,2055,2057,2059,2061,2063,2066,2069,2071,2073,2075],{"class":41,"line":144},[39,2052,69],{"class":45},[39,2054,21],{"class":49},[39,2056,1517],{"class":45},[39,2058,1151],{"class":49},[39,2060,1186],{"class":52},[39,2062,56],{"class":45},[39,2064,2065],{"class":59},"\"\u002Fabout\"",[39,2067,2068],{"class":45},">소개\u003C\u002F",[39,2070,1151],{"class":49},[39,2072,1566],{"class":45},[39,2074,21],{"class":49},[39,2076,63],{"class":45},[39,2078,2079,2081,2083],{"class":41,"line":154},[39,2080,147],{"class":45},[39,2082,21],{"class":49},[39,2084,63],{"class":45},[39,2086,2087],{"class":41,"line":161},[39,2088,158],{"emptyLinePlaceholder":157},[39,2090,2091],{"class":41,"line":177},[39,2092,682],{"class":641},[39,2094,2095,2097,2100,2103,2105,2108],{"class":41,"line":197},[39,2096,46],{"class":45},[39,2098,2099],{"class":49},"nav",[39,2101,2102],{"class":52}," aria-label",[39,2104,56],{"class":45},[39,2106,2107],{"class":59},"\"주요 메뉴\"",[39,2109,63],{"class":45},[39,2111,2112,2114,2116],{"class":41,"line":217},[39,2113,69],{"class":45},[39,2115,719],{"class":49},[39,2117,63],{"class":45},[39,2119,2120,2123,2125,2127,2129,2131,2133,2135,2137,2139,2141,2143],{"class":41,"line":247},[39,2121,2122],{"class":45},"    \u003C",[39,2124,722],{"class":49},[39,2126,1517],{"class":45},[39,2128,1151],{"class":49},[39,2130,1186],{"class":52},[39,2132,56],{"class":45},[39,2134,2009],{"class":59},[39,2136,2012],{"class":45},[39,2138,1151],{"class":49},[39,2140,1566],{"class":45},[39,2142,722],{"class":49},[39,2144,63],{"class":45},[39,2146,2148,2150,2152,2154,2156,2158,2160,2162,2164,2166,2168,2170],{"class":41,"line":2147},12,[39,2149,2122],{"class":45},[39,2151,722],{"class":49},[39,2153,1517],{"class":45},[39,2155,1151],{"class":49},[39,2157,1186],{"class":52},[39,2159,56],{"class":45},[39,2161,2037],{"class":59},[39,2163,2040],{"class":45},[39,2165,1151],{"class":49},[39,2167,1566],{"class":45},[39,2169,722],{"class":49},[39,2171,63],{"class":45},[39,2173,2175,2177,2179,2181,2183,2185,2187,2189,2191,2193,2195,2197],{"class":41,"line":2174},13,[39,2176,2122],{"class":45},[39,2178,722],{"class":49},[39,2180,1517],{"class":45},[39,2182,1151],{"class":49},[39,2184,1186],{"class":52},[39,2186,56],{"class":45},[39,2188,2065],{"class":59},[39,2190,2068],{"class":45},[39,2192,1151],{"class":49},[39,2194,1566],{"class":45},[39,2196,722],{"class":49},[39,2198,63],{"class":45},[39,2200,2202,2205,2207],{"class":41,"line":2201},14,[39,2203,2204],{"class":45},"  \u003C\u002F",[39,2206,719],{"class":49},[39,2208,63],{"class":45},[39,2210,2212,2214,2216],{"class":41,"line":2211},15,[39,2213,147],{"class":45},[39,2215,2099],{"class":49},[39,2217,63],{"class":45},[15,2219,2220,2221,2224],{},"목록 태그를 쓰면 스크린 리더가 \"목록, 항목 3개\"라고 먼저 알려줘서, 사용자가 얼마나 긴 목록인지 미리 알 수 있다. 순서가 중요하면(설치 단계, 순위) ",[19,2222,2223],{},"ol","을 쓴다.",[621,2226],{},[10,2228,2230,2231,2233],{"id":2229},"실수-7-페이지-뼈대를-전부-div로-만들기","실수 7. 페이지 뼈대를 전부 ",[19,2232,21],{},"로 만들기",[15,2235,2236,842,2238,842,2240,842,2243,2246],{},[19,2237,615],{},[19,2239,2099],{},[19,2241,2242],{},"main",[19,2244,2245],{},"footer"," 같은 태그는 랜드마크(Landmark)라고 불린다. 스크린 리더 사용자는 이걸로 \"본문으로 바로 이동\", \"메뉴로 이동\" 같은 점프를 한다. 지하철역 출구 번호 같은 역할이다.",[549,2248,2249,2262],{},[552,2250,2251],{},[555,2252,2253,2256,2259],{},[558,2254,2255],{},"이렇게 쓰고 있다면",[558,2257,2258],{},"이렇게 바꾸자",[558,2260,2261],{},"의미",[565,2263,2264,2279,2294,2309,2324,2339,2354],{},[555,2265,2266,2271,2276],{},[570,2267,2268],{},[19,2269,2270],{},"\u003Cdiv class=\"header\">",[570,2272,2273],{},[19,2274,2275],{},"\u003Cheader>",[570,2277,2278],{},"사이트 로고, 상단 영역",[555,2280,2281,2286,2291],{},[570,2282,2283],{},[19,2284,2285],{},"\u003Cdiv class=\"nav\">",[570,2287,2288],{},[19,2289,2290],{},"\u003Cnav>",[570,2292,2293],{},"주요 메뉴, 이동 링크 묶음",[555,2295,2296,2301,2306],{},[570,2297,2298],{},[19,2299,2300],{},"\u003Cdiv class=\"main\">",[570,2302,2303],{},[19,2304,2305],{},"\u003Cmain>",[570,2307,2308],{},"페이지의 핵심 내용 (페이지당 하나)",[555,2310,2311,2316,2321],{},[570,2312,2313],{},[19,2314,2315],{},"\u003Cdiv class=\"post\">",[570,2317,2318],{},[19,2319,2320],{},"\u003Carticle>",[570,2322,2323],{},"그 자체로 완결된 콘텐츠 (글, 댓글, 상품 카드)",[555,2325,2326,2331,2336],{},[570,2327,2328],{},[19,2329,2330],{},"\u003Cdiv class=\"section\">",[570,2332,2333],{},[19,2334,2335],{},"\u003Csection>",[570,2337,2338],{},"제목이 있는 주제별 묶음",[555,2340,2341,2346,2351],{},[570,2342,2343],{},[19,2344,2345],{},"\u003Cdiv class=\"sidebar\">",[570,2347,2348],{},[19,2349,2350],{},"\u003Caside>",[570,2352,2353],{},"본문과 관련은 있지만 부가적인 내용",[555,2355,2356,2361,2366],{},[570,2357,2358],{},[19,2359,2360],{},"\u003Cdiv class=\"footer\">",[570,2362,2363],{},[19,2364,2365],{},"\u003Cfooter>",[570,2367,2368],{},"저작권, 연락처 등 하단 정보",[31,2370,2372],{"className":33,"code":2371,"language":25,"meta":35,"style":35},"\u003Cbody>\n  \u003Cheader>\n    \u003Ca href=\"\u002F\">로고\u003C\u002Fa>\n    \u003Cnav aria-label=\"주요 메뉴\">...\u003C\u002Fnav>\n  \u003C\u002Fheader>\n\n  \u003Cmain>\n    \u003Carticle>\n      \u003Ch1>글 제목\u003C\u002Fh1>\n      \u003Csection>\n        \u003Ch2>첫 번째 소주제\u003C\u002Fh2>\n        \u003Cp>...\u003C\u002Fp>\n      \u003C\u002Fsection>\n    \u003C\u002Farticle>\n    \u003Caside>관련 글\u003C\u002Faside>\n  \u003C\u002Fmain>\n\n  \u003Cfooter>© 2026\u003C\u002Ffooter>\n\u003C\u002Fbody>\n",[19,2373,2374,2383,2391,2410,2429,2437,2441,2449,2457,2471,2480,2494,2506,2515,2524,2538,2547,2552,2566],{"__ignoreMap":35},[39,2375,2376,2378,2381],{"class":41,"line":42},[39,2377,46],{"class":45},[39,2379,2380],{"class":49},"body",[39,2382,63],{"class":45},[39,2384,2385,2387,2389],{"class":41,"line":66},[39,2386,69],{"class":45},[39,2388,615],{"class":49},[39,2390,63],{"class":45},[39,2392,2393,2395,2397,2399,2401,2403,2406,2408],{"class":41,"line":88},[39,2394,2122],{"class":45},[39,2396,1151],{"class":49},[39,2398,1186],{"class":52},[39,2400,56],{"class":45},[39,2402,2009],{"class":59},[39,2404,2405],{"class":45},">로고\u003C\u002F",[39,2407,1151],{"class":49},[39,2409,63],{"class":45},[39,2411,2412,2414,2416,2418,2420,2422,2425,2427],{"class":41,"line":109},[39,2413,2122],{"class":45},[39,2415,2099],{"class":49},[39,2417,2102],{"class":52},[39,2419,56],{"class":45},[39,2421,2107],{"class":59},[39,2423,2424],{"class":45},">...\u003C\u002F",[39,2426,2099],{"class":49},[39,2428,63],{"class":45},[39,2430,2431,2433,2435],{"class":41,"line":144},[39,2432,2204],{"class":45},[39,2434,615],{"class":49},[39,2436,63],{"class":45},[39,2438,2439],{"class":41,"line":154},[39,2440,158],{"emptyLinePlaceholder":157},[39,2442,2443,2445,2447],{"class":41,"line":161},[39,2444,69],{"class":45},[39,2446,2242],{"class":49},[39,2448,63],{"class":45},[39,2450,2451,2453,2455],{"class":41,"line":177},[39,2452,2122],{"class":45},[39,2454,166],{"class":49},[39,2456,63],{"class":45},[39,2458,2459,2462,2464,2467,2469],{"class":41,"line":197},[39,2460,2461],{"class":45},"      \u003C",[39,2463,1346],{"class":49},[39,2465,2466],{"class":45},">글 제목\u003C\u002F",[39,2468,1346],{"class":49},[39,2470,63],{"class":45},[39,2472,2473,2475,2478],{"class":41,"line":217},[39,2474,2461],{"class":45},[39,2476,2477],{"class":49},"section",[39,2479,63],{"class":45},[39,2481,2482,2485,2487,2490,2492],{"class":41,"line":247},[39,2483,2484],{"class":45},"        \u003C",[39,2486,10],{"class":49},[39,2488,2489],{"class":45},">첫 번째 소주제\u003C\u002F",[39,2491,10],{"class":49},[39,2493,63],{"class":45},[39,2495,2496,2498,2500,2502,2504],{"class":41,"line":2147},[39,2497,2484],{"class":45},[39,2499,15],{"class":49},[39,2501,2424],{"class":45},[39,2503,15],{"class":49},[39,2505,63],{"class":45},[39,2507,2508,2511,2513],{"class":41,"line":2174},[39,2509,2510],{"class":45},"      \u003C\u002F",[39,2512,2477],{"class":49},[39,2514,63],{"class":45},[39,2516,2517,2520,2522],{"class":41,"line":2201},[39,2518,2519],{"class":45},"    \u003C\u002F",[39,2521,166],{"class":49},[39,2523,63],{"class":45},[39,2525,2526,2528,2531,2534,2536],{"class":41,"line":2211},[39,2527,2122],{"class":45},[39,2529,2530],{"class":49},"aside",[39,2532,2533],{"class":45},">관련 글\u003C\u002F",[39,2535,2530],{"class":49},[39,2537,63],{"class":45},[39,2539,2541,2543,2545],{"class":41,"line":2540},16,[39,2542,2204],{"class":45},[39,2544,2242],{"class":49},[39,2546,63],{"class":45},[39,2548,2550],{"class":41,"line":2549},17,[39,2551,158],{"emptyLinePlaceholder":157},[39,2553,2555,2557,2559,2562,2564],{"class":41,"line":2554},18,[39,2556,69],{"class":45},[39,2558,2245],{"class":49},[39,2560,2561],{"class":45},">© 2026\u003C\u002F",[39,2563,2245],{"class":49},[39,2565,63],{"class":45},[39,2567,2569,2571,2573],{"class":41,"line":2568},19,[39,2570,147],{"class":45},[39,2572,2380],{"class":49},[39,2574,63],{"class":45},[2576,2577,2578],"warning",{},[536,2579,2580],{},[15,2581,2582,2583,2592,2593,2595,2596,2598,2599,2601],{},"반대로 ",[524,2584,2585,2586,2588,2589,2591],{},"모든 ",[19,2587,21],{},"를 ",[19,2590,2477],{},"으로 바꾸는 것","도 실수다. ",[19,2594,2477],{},"은 제목이 있는 의미 단위일 때만 쓴다. 그냥 스타일을 위해 감싸는 상자라면 ",[19,2597,21],{},"가 맞다. ",[19,2600,21],{},"는 나쁜 태그가 아니라 \"특별한 의미가 없는 상자\"라는 뜻이다.",[621,2603],{},[10,2605,2607],{"id":2606},"aria는-마지막-수단이다","ARIA는 마지막 수단이다",[15,2609,2610,2611,842,2614,2617],{},"접근성을 챙기다 보면 ",[19,2612,2613],{},"role",[19,2615,2616],{},"aria-label"," 같은 ARIA 속성을 만나게 된다. 강력하지만 첫 번째 규칙이 있다.",[536,2619,2620],{},[15,2621,2622],{},"네이티브 HTML 요소로 해결된다면, ARIA를 쓰지 말고 그 요소를 써라.",[15,2624,2625,612,2628,2631,2632,612,2635,2637,2638,2641],{},[19,2626,2627],{},"\u003Cdiv role=\"button\" tabindex=\"0\">",[19,2629,2630],{},"\u003Cbutton>","이, ",[19,2633,2634],{},"\u003Cdiv role=\"navigation\">",[19,2636,2290],{},"가 낫다. ARIA는 \"이건 버튼이에요\"라고 ",[524,2639,2640],{},"말만"," 해줄 뿐, 키보드 동작은 하나도 만들어주지 않는다. 잘못 쓴 ARIA는 안 쓴 것보다 더 혼란스럽다.",[621,2643],{},[10,2645,2647],{"id":2646},"내-페이지는-괜찮을까-3분-점검법","내 페이지는 괜찮을까? 3분 점검법",[549,2649,2650,2660],{},[552,2651,2652],{},[555,2653,2654,2657],{},[558,2655,2656],{},"방법",[558,2658,2659],{},"확인할 것",[565,2661,2662,2673,2686,2694],{},[555,2663,2664,2670],{},[570,2665,2666,2667,2669],{},"마우스를 내려놓고 ",[19,2668,529],{}," 키로만 사용해보기",[570,2671,2672],{},"모든 버튼과 링크에 닿는지, 포커스 테두리가 보이는지",[555,2674,2675,2678],{},[570,2676,2677],{},"개발자 도구 → Lighthouse → 접근성(Accessibility) 검사",[570,2679,2680,2682,2683,2685],{},[19,2681,1772],{}," 누락, ",[19,2684,1486],{}," 누락, 색 대비 문제",[555,2687,2688,2691],{},[570,2689,2690],{},"개발자 도구 → Elements → Accessibility 탭",[570,2692,2693],{},"각 요소가 어떤 역할(role)과 이름으로 읽히는지",[555,2695,2696,2699],{},[570,2697,2698],{},"제목만 뽑아보기 (콘솔에서 아래 코드 실행)",[570,2700,2701],{},"제목 단계가 건너뛰지 않는지",[31,2703,2705],{"className":996,"code":2704,"language":998,"meta":35,"style":35},"\u002F\u002F 콘솔에 붙여넣으면 페이지의 제목 구조가 들여쓰기로 출력된다\ndocument.querySelectorAll(\"h1,h2,h3,h4,h5,h6\").forEach((h) =>\n  console.log(\" \".repeat((h.tagName[1] - 1) * 2) + h.tagName + \" \" + h.textContent.trim())\n);\n",[19,2706,2707,2712,2740,2805],{"__ignoreMap":35},[39,2708,2709],{"class":41,"line":42},[39,2710,2711],{"class":641},"\u002F\u002F 콘솔에 붙여넣으면 페이지의 제목 구조가 들여쓰기로 출력된다\n",[39,2713,2714,2716,2719,2721,2724,2726,2729,2732,2735,2737],{"class":41,"line":66},[39,2715,1048],{"class":45},[39,2717,2718],{"class":52},"querySelectorAll",[39,2720,1033],{"class":45},[39,2722,2723],{"class":59},"\"h1,h2,h3,h4,h5,h6\"",[39,2725,1059],{"class":45},[39,2727,2728],{"class":52},"forEach",[39,2730,2731],{"class":45},"((",[39,2733,2734],{"class":1017},"h",[39,2736,1021],{"class":45},[39,2738,2739],{"class":281},"=>\n",[39,2741,2742,2745,2748,2750,2753,2755,2758,2761,2763,2766,2769,2772,2774,2777,2780,2782,2785,2788,2790,2793,2796,2799,2802],{"class":41,"line":88},[39,2743,2744],{"class":45},"  console.",[39,2746,2747],{"class":52},"log",[39,2749,1033],{"class":45},[39,2751,2752],{"class":59},"\" \"",[39,2754,1167],{"class":45},[39,2756,2757],{"class":52},"repeat",[39,2759,2760],{"class":45},"((h.tagName[",[39,2762,278],{"class":271},[39,2764,2765],{"class":45},"] ",[39,2767,2768],{"class":281},"-",[39,2770,2771],{"class":271}," 1",[39,2773,1021],{"class":45},[39,2775,2776],{"class":281},"*",[39,2778,2779],{"class":271}," 2",[39,2781,1021],{"class":45},[39,2783,2784],{"class":281},"+",[39,2786,2787],{"class":45}," h.tagName ",[39,2789,2784],{"class":281},[39,2791,2792],{"class":59}," \" \"",[39,2794,2795],{"class":281}," +",[39,2797,2798],{"class":45}," h.textContent.",[39,2800,2801],{"class":52},"trim",[39,2803,2804],{"class":45},"())\n",[39,2806,2807],{"class":41,"line":109},[39,2808,2809],{"class":45},");\n",[621,2811],{},[10,2813,2815],{"id":2814},"정리-왜-알아두면-좋은가","정리: 왜 알아두면 좋은가",[549,2817,2818,2828],{},[552,2819,2820],{},[555,2821,2822,2825],{},[558,2823,2824],{},"실수",[558,2826,2827],{},"고치는 법",[565,2829,2830,2841,2856,2872,2884,2896,2913],{},[555,2831,2832,2837],{},[570,2833,2834,2835],{},"클릭되는 ",[19,2836,21],{},[570,2838,2839],{},[19,2840,222],{},[555,2842,2843,2848],{},[570,2844,2845,2847],{},[19,2846,1325],{}," 링크로 동작 실행",[570,2849,2850,2851,2853,2854],{},"이동은 ",[19,2852,1151],{},", 동작은 ",[19,2855,222],{},[555,2857,2858,2861],{},[570,2859,2860],{},"크기로 고른 제목 태그",[570,2862,2863,2864,2866,2867,2866,2869,2871],{},"구조대로 ",[19,2865,1346],{},"→",[19,2868,10],{},[19,2870,1451],{},", 크기는 CSS",[555,2873,2874,2879],{},[570,2875,2876,2878],{},[19,2877,1493],{},"만 있는 입력칸",[570,2880,2881,2883],{},[19,2882,1486],{}," 연결",[555,2885,2886,2891],{},[570,2887,2888,2889],{},"없거나 의미 없는 ",[19,2890,1772],{},[570,2892,2893,2894],{},"내용 설명, 장식이면 ",[19,2895,1814],{},[555,2897,2898,2903],{},[570,2899,2900,2902],{},[19,2901,21],{},"로 나열한 목록",[570,2904,2905,2907,2908,2910,2911],{},[19,2906,719],{},"\u002F",[19,2909,2223],{}," + ",[19,2912,722],{},[555,2914,2915,2920],{},[570,2916,2917,2919],{},[19,2918,21],{},"로만 만든 페이지 뼈대",[570,2921,2922,842,2924,842,2926,842,2928,842,2930],{},[19,2923,615],{},[19,2925,2099],{},[19,2927,2242],{},[19,2929,166],{},[19,2931,2245],{},[15,2933,2934,2935,2938,2939,2941],{},"시맨틱 HTML은 따로 시간을 내서 하는 \"접근성 작업\"이 아니다. ",[524,2936,2937],{},"처음 태그를 고를 때 한 번 더 생각하는 습관","이다. 그 습관 하나로 키보드 사용자와 스크린 리더 사용자는 사이트를 쓸 수 있게 되고, 검색 엔진은 내용을 더 잘 이해하고, 나중에 코드를 읽는 동료는 구조를 한눈에 파악한다. 다음에 ",[19,2940,21],{},"를 쓰려는 순간, \"이게 정말 의미 없는 상자인가?\"부터 물어보자.",[2943,2944,2945],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":35,"searchDepth":66,"depth":66,"links":2947},[2948,2949,2951,2952,2953,2955,2957,2959,2961,2962,2963],{"id":12,"depth":66,"text":13},{"id":625,"depth":66,"text":2950},"실수 1. 클릭되는 div",{"id":1145,"depth":66,"text":1146},{"id":1335,"depth":66,"text":1336},{"id":1482,"depth":66,"text":2954},"실수 4. label 없는 입력칸",{"id":1768,"depth":66,"text":2956},"실수 5. 이미지 alt를 빼먹거나 의미 없이 채우기",{"id":1957,"depth":66,"text":2958},"실수 6. 목록을 div로 나열하기",{"id":2229,"depth":66,"text":2960},"실수 7. 페이지 뼈대를 전부 div로 만들기",{"id":2606,"depth":66,"text":2607},{"id":2646,"depth":66,"text":2647},{"id":2814,"depth":66,"text":2815},"화면에서는 똑같아 보여도 div로 만든 버튼, label 없는 입력칸, 크기로 고른 제목 태그는 키보드 사용자와 스크린 리더, 검색 엔진에게 전혀 다르게 보인다. 직접 눌러볼 수 있는 예제로 흔한 시맨틱 HTML 실수와 고치는 법을 정리했다.","md",{"date":2967,"field":2968,"tags":2969},"2026.10.08","frontend",[25],"\u002Fko\u002Fsemantic-html-common-mistakes",{"title":5,"description":2964},{"loc":2970},"ko\u002Fsemantic-html-common-mistakes","XkeJHt5s1pbAXuJygfpwhaAQVpZzRVtaTYkNYLWEIYg",[2976,2987,2993,3001,3008,3016,3023,3034,3042,3050,3062,3070,3079,3085,3091,3098,3105,3112,3119,3125,3134,3143,3149,3156,3162,3169,3176,3184,3191,3198,3207,3214,3221,3228,3231,3239,3246,3254,3260],{"path":2977,"title":2978,"description":2979,"meta":2980},"\u002Fko\u002Fadsense-ads-txt-and-seo-indexing-bug","애드센스 ads.txt 경고를 받고 파헤치다가 찾은 진짜 색인 버그","구글 애드센스가 ads.txt 문제를 알려왔는데, 확인해보니 파일은 멀쩡했다. 대신 서치콘솔 색인 수가 적었던 진짜 원인을 Nuxt Content 슬러그 불일치 버그에서 찾은 과정을 정리한다.",{"date":2981,"field":2982,"tags":2983},"2026.09.17","blog",[2984,2985,2986],"seo","adsense","nuxt-content",{"path":2988,"title":2989,"description":2990,"meta":2991},"\u002Fko\u002Fcss-has-selector","CSS :has() 선택자 실전 가이드: 자바스크립트 없이 부모를 선택하는 법","체크하면 카드가 강조되고, 입력이 틀리면 폼 전체가 반응하고, 별점에 마우스를 올리면 앞의 별까지 칠해진다. 예전엔 자바스크립트가 필요했던 일을 CSS :has() 한 줄로 해결하는 실전 예제를 직접 눌러보며 정리했다.",{"date":2967,"field":2968,"tags":2992},[258],{"path":2994,"title":2995,"description":2996,"meta":2997},"\u002Fko\u002Fcss-layouts","CSS Flexbox 완전 정복 가이드","Flexbox를 활용한 반응형 레이아웃 구현 방법과 실전 예제. 수직 정렬, 네비게이션 바, 카드 레이아웃까지 완벽 정리!",{"date":2998,"image":2999,"field":2968,"tags":3000},"2025.01.25","css.jpg",[258],{"path":3002,"title":3003,"description":3004,"meta":3005},"\u002Fko\u002Fcss-login-form","로그인","로그인 UI를 그려보자",{"date":3006,"field":2968,"tags":3007},"2025.03.29",[25,258],{"path":3009,"title":3010,"description":3011,"meta":3012},"\u002Fko\u002Fcsv-parser-cleaning","복잡한 CSV 데이터를 안전하게 파싱하는 방법","JavaScript에서 큰따옴표, 줄바꿈, 쉼표 등 복잡한 CSV 데이터를 안전하게 객체로 변환하는 전체 과정 설명",{"date":3013,"field":2968,"tags":3014},"2025.06.19",[3015],"javascript",{"path":3017,"title":3018,"description":3019,"meta":3020},"\u002Fko\u002Fdebounce-guide","debounce와 throttle이란??","반복되는 함수 호출을 제어하는 기술인 디바운스(debounce)와 쓰로틀(throttle)을 알아보자.",{"date":3021,"field":2968,"tags":3022},"2025.03.26",[3015],{"path":3024,"title":3025,"description":3026,"meta":3027},"\u002Fko\u002Fdeclarative-vs-procedural-programming","선언적 프로그래밍 vs 절차형 프로그래밍","선언적 프로그래밍과 절차형 프로그래밍은 서로 대비되는 대표적인 패러다임이다. 두 패러다임의 차이를 알아보고, 각 패러다임에 해당하는 언어와 Vue\u002FReact의 특징을 살펴보자.",{"date":3028,"field":3029,"tags":3030},"2025.05.24","concepts",[3031,3032,3033],"paradigm","vue","react",{"path":3035,"title":3036,"description":3037,"meta":3038},"\u002Fko\u002Fdesign-guide","Design-Guide","A comprehensive guide on design principles and best practices for developers.",{"date":3039,"field":2968,"tags":3040},"2025.01.19",[3041],"design-system",{"path":3043,"title":3044,"description":3045,"meta":3046},"\u002Fko\u002Fdikw-pyramid","DIKW 피라미드 정리: 데이터가 지혜가 되기까지","Data, Information, Knowledge, Wisdom 4단계로 구성된 DIKW 피라미드 개념을 로그\u002F분석 데이터 같은 실제 개발 사례에 대입해서 정리한다.",{"date":3047,"field":3029,"tags":3048},"2026.09.18",[3049],"data",{"path":3051,"title":3052,"description":3053,"meta":3054},"\u002Fko\u002Fdisplaying-commits-with-github-actions","깃허브 액션으로 커밋 로그를 블로그에 띄우기: Nuxt와 Vercel 활용법","깃허브 액션을 통해 커밋 데이터를 자동으로 수집하고, Nuxt와 Vercel로 UI에 노출하는 방법을 소개합니다.",{"date":3055,"image":3056,"field":3057,"tags":3058},"2025.02.28","github-commits.jpg","infra",[3059,3060,3061],"github-actions","vercel","nuxt",{"path":3063,"title":3064,"description":3065,"meta":3066},"\u002Fko\u002Fdocker-auto-build-run","로컬에서 커밋 시 도커 빌드 후 컨테이너 시작하기","로컬에서 커밋 시 도커 빌드 후 컨테이너 시작하기.",{"date":3067,"field":3057,"tags":3068},"2025.03.10",[3069],"docker",{"path":3071,"title":3072,"description":3073,"meta":3074},"\u002Fko\u002Fhow-to-mount-storage","라즈베리파이4에 저장장치 마운트 시키기","라즈베리파이에 저장장치를 연결하고 파티션 생성부터 포맷, 마운트까지의 전체 과정을 정리한 기록입니다.",{"date":3075,"field":3057,"tags":3076},"2025.07.11",[3077,3078],"raspberry-pi","linux",{"path":3080,"title":3081,"description":3081,"meta":3082},"\u002Fko\u002Fhtml","HTML이란 무엇인가",{"date":2998,"image":3083,"field":2968,"tags":3084},"html.jpg",[25],{"path":3086,"title":3087,"description":3088,"meta":3089},"\u002Fko\u002Fhtml-features-without-javascript","자바스크립트 없이 HTML만으로 되는 것들: 아직도 div로 다 만들고 있다면","아코디언, 팝오버, 모달, 자동완성, 폼 검증, 이미지 지연 로딩까지. 라이브러리 없이 HTML 태그와 속성만으로 해결되는 기능을 예제와 함께 정리했다. 코드는 줄고 접근성은 덤으로 따라온다.",{"date":2967,"field":2968,"tags":3090},[25],{"path":3092,"title":3093,"description":3094,"meta":3095},"\u002Fko\u002Fhtml2","미치광이 카드 컴포넌트","미치광이 카드 컴포넌트는 어떤 느낌일까",{"date":3096,"field":2968,"tags":3097},"2025.03.28",[25,258],{"path":3099,"title":3100,"description":3100,"meta":3101},"\u002Fko\u002Fhttps-guide","Let's Encrypt를 이용해서 HTTPS 적용하기",{"date":3102,"field":3057,"tags":3103},"2025.03.11",[3104],"https",{"path":3106,"title":3107,"description":3108,"meta":3109},"\u002Fko\u002Fjavascript-event-loop","자바스크립트 이벤트 루프 완전 정복: 마이크로태스크와 매크로태스크의 실행 순서","setTimeout(0)보다 Promise.then이 먼저 실행되는 이유는? 콜 스택, 태스크 큐, 마이크로태스크 큐가 어떤 순서로 돌아가는지 예제로 정리하고, 브라우저와 Node.js의 차이, 실무에서 UI 멈춤을 피하는 방법까지 알아보자.",{"date":2967,"field":3029,"tags":3110},[3015,3111],"nodejs",{"path":3113,"title":3114,"description":3115,"meta":3116},"\u002Fko\u002Fjs-data-01","JavaScript 데이터01","JavaScript 데이터 다루는 문제를 풀어보자",{"date":3117,"field":2968,"tags":3118},"2025.03.08",[3015],{"path":3120,"title":3121,"description":3122,"meta":3123},"\u002Fko\u002Fjs-data-02","JavaScript 데이터02","복잡한 데이터 구조를 다루는 실전 문제를 해결해보자.",{"date":3117,"field":2968,"tags":3124},[3015],{"path":3126,"title":3127,"description":3128,"meta":3129},"\u002Fko\u002Fmarkdown-guid","마크다운 문법","마크다운 문법을 알아보자",{"date":3130,"image":3131,"field":2982,"tags":3132},"2025.03.02","markdown.webp",[3133],"markdown",{"path":3135,"title":3136,"description":3137,"meta":3138},"\u002Fko\u002Fminio-guide","MinIO 완벽 가이드: 설치부터 Node.js 연동까지","MinIO는 오픈소스 기반의 고성능 객체 스토리지 서버입니다. AWS S3와 호환되는 API를 제공하여 클라우드 네이티브 애플리케이션을 위한 완벽한 스토리지 솔루션으로 자리잡고 있습니다.",{"date":3139,"field":3140,"tags":3141},"2025.11.23","backend",[3142,3111],"minio",{"path":3144,"title":3145,"description":3146,"meta":3147},"\u002Fko\u002Fnitro-wildcard-redirect-url-migration","글 주소 프리픽스를 통째로 바꿔야 할 때: Nitro wildcard 리다이렉트로 안전하게 옮기기","\u002Fblog\u002F[슬러그]로 쓰던 글 주소를 \u002Fko\u002F[슬러그]로 옮기면서, 기존 링크\u002F북마크를 하나도 안 깨뜨리고 처리한 방법. Nitro routeRules의 와일드카드 리다이렉트 패턴과 실제로 같이 바꿔야 했던 범위를 정리한다.",{"date":2967,"field":2982,"tags":3148},[3061,2984],{"path":3150,"title":3151,"description":3152,"meta":3153},"\u002Fko\u002Fnode-simple-server","Node.js 간단한 서버 만들기","Node.js로 간단한 HTTP 서버를 만드는 방법",{"date":3154,"field":3140,"tags":3155},"2025.01.30",[3111],{"path":3157,"title":3158,"description":3159,"meta":3160},"\u002Fko\u002Fnuxt-colormode","Nuxt3 다크모드 적용하기","Nuxt3에 다크모드 적용하여 관리하기",{"date":3006,"field":2968,"tags":3161},[3061],{"path":3163,"title":3164,"description":3165,"meta":3166},"\u002Fko\u002Fnuxt-content-vercel-empty-query-sqlite","배포만 하면 블로그 글이 하나도 안 보이던 버그: Nuxt Content와 Vercel의 \u002Ftmp 문제","로컬에서는 멀쩡한데 Vercel에 올리면 queryCollection()이 빈 배열만 반환하던 버그를 추적한 과정. 원인은 @nuxt\u002Fcontent가 Vercel의 읽기 전용 파일시스템을 지원하기 전 버전에 고정돼 있었던 것.",{"date":3167,"field":2982,"tags":3168},"2026.10.07",[2986,3060],{"path":3170,"title":3171,"description":3172,"meta":3173},"\u002Fko\u002Fnuxt-runtimeconfig-appconfig","Nuxt 설정 runtimeConfig vs app.config 완전 정복","Nuxt3에서 전역 설정을 어떻게 관리하고, 어떤 기준으로 나누어야 할까? 다크모드 예시부터 실무 기준 설정 전략까지 총정리",{"date":3174,"field":2968,"tags":3175},"2025.06.16",[3061],{"path":3177,"title":3178,"description":3179,"meta":3180},"\u002Fko\u002Fnuxt-useasyncdata-cache-error","useAsyncData 캐싱 문제와 Key 동적 설정으로 해결하기","이전 포스트의 데이터가 계속 출력되는 캐싱 관련 문제를 해결하는 방법",{"date":3181,"field":2968,"tags":3182,"image":3183},"2025.01.24",[3061],"cache.jpg",{"path":3185,"title":3186,"description":3187,"meta":3188},"\u002Fko\u002Fnuxt-vercel-sql-error","Nuxt 3에서 Vercel 배포 시 발생한 md 파일 로딩 문제 해결기","Nuxt 3 웹 어플리케이션에서 Vercel 배포 환경에서 발생한 md 파일 로딩 문제를 분석하고 해결한 방법에 대해 공유합니다.",{"date":3181,"image":3189,"field":2968,"tags":3190},"ssg.jpg",[3061,2986,3060],{"path":3192,"title":3193,"description":3194,"meta":3195},"\u002Fko\u002Fnuxt3-pinia-guide","nuxt3 Pinia 적용하기","Nuxt3 프로젝트에서 Pinia를 적용해보자 @pinia\u002Fnuxt",{"date":3006,"field":2968,"tags":3196},[3061,3197],"pinia",{"path":3199,"title":3200,"description":3201,"meta":3202},"\u002Fko\u002Fnuxt3-unit-test","Nuxt 프로젝트에 유닛 테스트 코드 추가하기","Nuxt 3 프로젝트에서 Vitest를 활용한 테스트 환경 설정과 유틸리티 함수 테스트 방법",{"date":3203,"image":3204,"field":2968,"tags":3205},"2025.03.07","unit-test.jpg",[3061,3206],"vitest",{"path":3208,"title":3209,"description":3210,"meta":3211},"\u002Fko\u002Fpm2-guide","프로세스 매니저 PM2","배포환경에서 유용하게 사용할 수 있는 프로세스 매니저를 알아보자.",{"date":3067,"field":3057,"tags":3212},[3213,3111],"pm2",{"path":3215,"title":3216,"description":3217,"meta":3218},"\u002Fko\u002Freact-createportal","React createPortal 완벽 가이드","React의 `createPortal`을 활용한 UI 구현법, 활용 사례, 장단점 및 코드 예제를 소개합니다.",{"date":3219,"field":2968,"tags":3220},"2025.01.27",[3033],{"path":3222,"title":3223,"description":3224,"meta":3225},"\u002Fko\u002Frouting","Routing","Nuxt file-system routing creates a route for every file in the pages\u002F directory.",{"date":3226,"field":2968,"tags":3227},"2025.01.22",[3061],{"path":2970,"title":5,"description":2964,"meta":3229},{"date":2967,"field":2968,"tags":3230},[25],{"path":3232,"title":3233,"description":3234,"meta":3235},"\u002Fko\u002Ftanstack-query-guide","TanStack Query란 무엇인가?","TanStack Query가 웹 애플리케이션에서 데이터 가져오기, 캐싱, 상태 관리를 어떻게 개선하는지 알아본다.",{"date":3236,"field":2968,"tags":3237},"2025.04.15",[3033,3238],"tanstack-query",{"path":3240,"title":3241,"description":3242,"meta":3243},"\u002Fko\u002Fuse-context","리엑트 상태관리 useContext()","React에서 `useContext`를 사용하면 컴포넌트 트리에 깊이 중첩된 컴포넌트에서도 prop drilling 없이 상태를 공유할 수 있습니다. 이 글에서는 `useContext`의 개념, 사용 방법, 장단점, 그리고 실전 예제를 함께 알아보겠습니다.",{"date":3244,"field":2968,"tags":3245},"2025.02.03",[3033],{"path":3247,"title":3248,"description":3249,"meta":3250},"\u002Fko\u002Fvite-plugin-style-inject","리엑티 컴포넌트를 패키지 빌드 시 CSS 같이 적용시키기","dist에 css에 파일이 생성되었으나, 적용 안 되는 이유를 알아보고 에러를 처리하자",{"date":3251,"field":2968,"tags":3252},"2025.04.06",[3253,3033],"vite",{"path":3255,"title":3256,"description":3257,"meta":3258},"\u002Fko\u002Fvue-component-guide","Vue의 \u003Ccomponent :is \u002F> 완벽 정리: 동적 렌더링의 모든 것","Vue에서 \u003Ccomponent :is \u002F>를 활용한 동적 컴포넌트 렌더링 방법과 VNode, 컴포넌트 객체의 차이를 실전 예제로 이해하기",{"date":2998,"field":2968,"tags":3259},[3032],{"path":3261,"title":3262,"description":3263,"meta":3264},"\u002Fko\u002Fvue-query-ref-value-trap-nuxt3","Vue Query에서 데이터가 안 보이는 이유? Nuxt 3와 Ref 구조의 함정","Nuxt 3 + vue-query를 사용할 때 API 데이터가 `v-if` 조건문에서 제대로 표시되지 않는 현상을 해결한 경험을 바탕으로, Ref 구조와 template 디렉티브에서의 차이를 자세히 설명합니다.",{"date":3265,"field":2968,"tags":3266},"2025.06.08",[3061,3032,3238],1791459768246]