<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>reina.log</title>
        <link>https://velog.io/</link>
        <description>호기심 많은 프론트엔드 개발자</description>
        <lastBuildDate>Sun, 11 Feb 2024 01:05:16 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>reina.log</title>
            <url>https://velog.velcdn.com/images/reina__/profile/8c4a1b59-3189-4b83-b044-882513b9c6c1/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. reina.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/reina__" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[부트캠프 후기가 궁금한가요? (feat. 제로베이스 프론트엔드 취업 스쿨)]]></title>
            <link>https://velog.io/@reina__/%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%9B%84%EA%B8%B0%EA%B0%80-%EA%B6%81%EA%B8%88%ED%95%9C%EA%B0%80%EC%9A%94-feat.-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%B7%A8%EC%97%85-%EC%8A%A4%EC%BF%A8</link>
            <guid>https://velog.io/@reina__/%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%9B%84%EA%B8%B0%EA%B0%80-%EA%B6%81%EA%B8%88%ED%95%9C%EA%B0%80%EC%9A%94-feat.-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%B7%A8%EC%97%85-%EC%8A%A4%EC%BF%A8</guid>
            <pubDate>Sun, 11 Feb 2024 01:05:16 GMT</pubDate>
            <description><![CDATA[<p>오늘은 평소와 달리 제가 현재 수강 중인 제로베이스 프론트엔드 취업 스쿨에 대한 후기를 들고 왔습니다. 개발자를 선택하게 된 계기부터 제로베이스에 대한 간단한 소개와 후기까지 말씀드릴게요. </p>
<p>부트캠프를 고민하고 계신 분들이 참고하기 좋은 글이 되었으면 좋겠네요 😃 (쓰다보니 말이 조금 많아요)</p>
<br>

<hr>
<h3 id="어쩌다가-개발자를">어쩌다가 개발자를...</h3>
<p>모든 이야기를 시작하기에 앞서 저는 현재 대학생입니다! (그러나 경력을 곁들인...) 이런 제가 왜 많고 많은 직업 중 개발자를 선택하게 되었을까요? </p>
<p>저는 회계세무와 관련된 특성화 고등학교를 진학해서 바로 관련 분야로 취업을 했습니다. 그러나 다양한 이유로 인해 저는 회계와 맞지 않음을 깨달았고, 진로에 대해 다시 한 번 고민했습니다.</p>
<p>원래 디자인이 관심이 너무너무 많았기에 디자이너로 전향할까 고민하다가 웹 퍼블리셔와 UIUX 라는 것을 접하게 되었습니다. 이후 <strong>프론트엔드 개발자</strong>라는 직업까지 알게 되었어요. 앱이나 웹을 디자인하는 것에 그치지 않고 실제로 구현해서 사람들이 경험해볼 수 있게 만드는 이 직업이 <u>너무 매력적으로 다가와서</u> 선택하게 되었습니다. 그렇게 저는 프론트엔드 개발자라는 직업을 머리 속에 담아둔 채로 재직자 전형을 통해 공학과 관련된 학과로 입학했습니다. </p>
<p>물론 학교에서 배우는 것으로는 부족하다는 걸 알았기에 유튜브나 온라인 강의를 통해 다양한 강의를 수강해봤습니다. 그러나 <u>정해진 커리큘럼도 없고, 제대로 지식을 쌓고 있는 게 맞는지</u> 의심이 생기게 되었습니다. 그러던 중 코딩을 전문적으로 진행하는 부트캠프에 대해 알게 되었습니다.</p>
<br>

<hr>
<h3 id="왜-제로베이스야">왜 제로베이스야?</h3>
<p>그러나 부트캠프를 알게 되고도 쉽사리 신청을 하지 못했는데요. 그 이유는 학생이기 때문에 학교와 병행하려면 실제로 모여서 하는 부트캠프의 경우 현실적으로 참여하기가 어려웠기 때문입니다. 이로 인해 &#39;아... 비대면으로 하는 건 없을까?&#39; 했던 찰나에 인스타그램 광고를 통해 <u>비대면 부트캠프인 제로베이스</u>를 알게 되었습니다. </p>
<p>여담으로 저는 배움에 있어 <code>백문불여일견</code> 이 좌우명인 사람인데요. 뭔가를 배움에 있어 실제로 적용해보는 것만큼 확실히 이해하고 느끼는 방법이 없다고 생각하기 때문입니다. 그렇게 제로베이스의 커리큘럼을 살펴보았는데, 아래와 같이 <u>많은 실습양과 프로젝트의 개수</u> 등이 구미를 당기게 했습니다.
<img src="https://velog.velcdn.com/images/reina__/post/e2a0af46-4d99-488e-a54c-5e1504049ba7/image.png" alt=""></p>
<p>더불어서 제가 처음 알게 된 부트캠프는 가격이 7-800만원에 달했던 걸로 기억해서 쉽사리 도전하기가 어려웠는데요! (어디인지는 잘 기억이 나지 않습니다.) 제로베이스는 그 가격의 절반정도에 해당하는 가격으로 진행되었기에 도전 장벽이 좀 더 낮았다고 느껴졌어요.</p>
<p>+ 어떤 부트캠프들은 인원을 선발하는 과정이 있기도 하더라구요? 제로베이스는 아래와 같이 어떠한 선발 절차도 없이 신청하시면 바로 학습할 수 있습니다!
<img src="https://velog.velcdn.com/images/reina__/post/c78e06d5-ef9f-47a1-b8f4-6c042c6e1d84/image.png" alt=""></p>
<p>제가 제로베이스를 선택하게 된 가장 큰 계기를 정리해보자면 다음과 같습니다! 만약 저와 같은 고민을 하고 계신 분이 있다면 저는 제로베이스를 추천하고 싶어요 😊</p>
<blockquote>
<ol>
<li><strong>비대면</strong> 진행</li>
<li><strong>많은 양의 프로젝트</strong> (토이 포함)</li>
<li>상대적으로 <strong>부담이 덜되는 가격</strong></li>
</ol>
</blockquote>
<br>

<hr>
<h3 id="지금까지-제로베이스에서-뭐-배웠어">지금까지 제로베이스에서 뭐 배웠어?</h3>
<p>이번 달이 벌써 4개월차더라구요. (<del>시간 파사삭</del>) 저는 현재 리액트 강의를 수강 중이고, 지금까지 HTML, CSS, JavaScript, CS이론, Github에 대해서 쭉 배웠어요. </p>
<p>아래는 제 옵시디언 폴더인데요. 정말 많은 내용들이 정리 돼 있답니다 😊
<img src="https://velog.velcdn.com/images/reina__/post/24d05df2-f81e-43f0-8f3a-b3cd7db0377f/image.png" alt=""></p>
<p>정말 기본적인 HTML 요소(<code>&lt;a&gt;</code>, <code>&lt;div&gt;</code>, <code>&lt;input&gt;</code>, <code>sementic tag</code>, ...), CSS 스타일(<code>border</code>, <code>background</code>, <code>display</code>, <code>position</code>, ...)에 대한 개념 이해부터 시작해서 이들을 어떻게 조합해서 <strong>HTML 구조</strong>를 어떻게 짤 수 있는지, 어떤 <strong>CSS 스타일</strong>을 적용했을 때 <strong>어떤 디자인을 기대</strong>할 수 있는지에 대해서 학습할 수 있었습니다!</p>
<p>그리고 웹 페이지는 정말 동적이잖아요? 이런 동적인 움직임을 위해 <strong>JavaScript 코드를 어떻게 구현</strong>하는지 (JavaScript를 통해 HTML과 CSS를 구현할 수 있어요!) 등에 대해 학습했습니다.</p>
<p>뿐만 아니라 개발자라면 상식으로 알아두면 좋을 법한 <strong>컴퓨터 지식(CS이론)</strong>들에 대해서도 배울 수 있었어요. <code>이론 + a</code> 의 <strong>CS 퀴즈</strong>까지 진행하기 때문에 지식을 좀 더 머리 속에 담을 수 있던 것 같아요. 혼자서 공부했더라면 이런 점까지는 신경쓰지 못 했을 것 같은데 정말 <u>비전공자들을 챙겨준다</u>는 느낌이 드는 부분이었습니다.</p>
<p>더불어 <strong>Github</strong>라는 저희가 구현해 둔 코드들을 보관하는 일종의 저장소(?)가 있습니다. 더 자세한 내용은 강의를 수강하면 알 수 있는데요. 현업에서 실제로 어떻게 활용하고 있는지에 대해 학습하고, 실습도 해 보면서 활용법에 대해 더 익힐 수 있어요. 강의를 진행하면서 구현한 또 다른 코드들도 git 하면 좀 더 자연스럽게 사용하고 있는 제 모습을 발견할 때도 있답니다.</p>
<p><strong>코딩테스트</strong>도 매주 1회씩 진행하며 점수를 메기고 있으므로, &#39;아 코딩테스트 준비도 해야 하는데...&#39; 하면서 개인적으로 계획한 건 미루더라도 적어도 매주 5개의 문제는 풀이할 수 있다는 장점도 있습니다. 이를 위한 <strong>알고리즘 강의</strong>도 준비돼 있으니 정말 열심히만 한다면 많은 걸 얻어갈 수 있는 커리큘럼이라고 생각해요.</p>
<br>

<hr>
<h3 id="프로젝트도-궁금해">프로젝트도 궁금해!</h3>
<p>프로젝트는 크게 강의, 미션, 개인, 팀으로 나눌 수 있는 것 같아요. 미션은 HTML/CSS, JavaScript, Framework 로 총 3가지가 있으며 각각 3주? 정도의 시간을 갖고 5가지의 미션을 수행하게 됩니다! 미션은 아무래도 공개 불가 사항이라 말씀드리지 못하고, 개인과 팀 프로젝트도 아직 진행 전인 상태라 더 자세한 설명은 못 드릴 것 같아요.</p>
<p>강의를 진행하면서는 클론 코딩부터 토이 프로젝트까지 다양한 실습들이 존재합니다. </p>
<p><img src="https://velog.velcdn.com/images/reina__/post/c14c890e-4a94-4c15-ba05-b1aa66b07b87/image.png" alt=""></p>
<p>최근에 전 20개의 토이프로젝트를 진행했는데요. <code>TODO List</code>, <code>프로그래스 바</code>, <code>무한스크롤</code>, <code>캐러셀</code>, <code>유튜브 화면</code>, <code>계산기</code>, <code>2D 벽돌 깨기 게임</code>, <code>카카오 지도를 연동한 지도 서비스</code>, ... 뭔가 실무적으로 정말 도움이 될 것 같은 토이 프로젝트들을 많이 진행했어요! </p>
<p>이때까지 배워 온 HTML, CSS, JavaScript를 총 집합시켜서 프로젝트를 진행했습니다. 몇 가지 제가 구현한 화면을 구경해보실까요?</p>
<p><code>TODO List</code>
<img src="https://velog.velcdn.com/images/reina__/post/0684aaa3-919b-44c6-8da2-e76f6fde38e5/image.gif" alt=""></p>
<p><code>프로그래스 바</code>
<img src="https://velog.velcdn.com/images/reina__/post/0e66b356-1d17-4b8e-b6ca-2f6c1fd44745/image.gif" alt=""></p>
<p><code>3D 캐러셀</code>
<img src="https://velog.velcdn.com/images/reina__/post/c14919f8-450e-40f3-a146-b933998327a6/image.gif" alt=""></p>
<p><code>카카오 지도를 연동한 지도 서비스</code>
저는 크롬에 위치 허용을 안 해놨지만 &#39;현 위치 조회하기&#39; 버튼을 클릭하면 제 위치로 지도가 이동합니다!
<img src="https://velog.velcdn.com/images/reina__/post/d7af051b-3e58-439c-833d-c65f9d535d31/image.gif" alt=""></p>
<p>등등 정말 다양하고 재밌었습니다 ㅎㅎ 개인 포트폴리오용 사이트를 만들 때도 도움이 될 만한 기능들을 많이 배웠어요. </p>
<p>이렇게 다시 보니 다른 실습들도 보여드리고 싶어서 더 찾아왔어요! (?)</p>
<br>

<p><code>네이버 주문 클론코딩</code>
HTML과 CSS, 아주 약간의 JavaScript만 사용해서 만든 페이지입니다. 그때 구현할 땐 잘됐다고 생각했는데 지금 다시 보니 많이 허접하네요
<img src="https://velog.velcdn.com/images/reina__/post/22ba2f0e-95dc-47a7-857a-000dd752be00/image.gif" alt=""></p>
<p><code>인스타그램 클론코딩</code>
이게 제일 처음 해본 클론코딩인 것 같아요. 기능이 엄청 없네요 ㅎㅎ
<img src="https://velog.velcdn.com/images/reina__/post/d58abac7-42e8-4f3e-8219-c9333d0c72c8/image.gif" alt=""></p>
<p>아직까지도 많은 실습들과 프로젝트가 남아있어요. 앞으로 또 어떤 프로젝트를 진행하게 될지 너무 기대됩니다!</p>
<br>

<hr>
<h3 id="진행하다가-막히면-어떡해">진행하다가 막히면 어떡해?</h3>
<p>제로베이스를 신청하면 슬랙에도 가입하는데요. 여기에 #질의응답 채널이 존재합니다! 저는 이 채널에 지박령(?) 마냥 자주 방문하는 사람입니다. 대부분의 질문은 <code>김영민 강사님</code> 이 대답해주시구요. JavaScript 스터디에 참여하게 되면 <code>이웅모 강사님</code> (모던 자바스크립트 Deep Dive 저자)이 전담적으로 답변해주시는 것 같아요.</p>
<p>저는 정말 다양한 질문들에 대해 <code>김영민 강사님</code>께 도움을 많이 얻었어요! 그 중에 기억에 남는 건 json-server 관련해서 정말 하루종일 이것저것 해봐도 해결이 안 되던 게 있어서 질문을 한 적이 있었습니다. 그때 슬랙 기능 중에 <code>허들</code> 이라고 줌처럼 화면 공유, 음성, 채팅, ... 이 가능한 기능이 있는데 이걸 통해 무려 2시간 동안 도움을 주셨습니다. 🥹🥹 (주말이었어요) </p>
<p>이때 정말 감사했고, 이외에도 개념적인 것에 질문을 드리면 그 부분에 대한 <u>접근 방법과 응용 방법</u> 등에 대한 설명을 굉장히 친절하고 자세하게 설명해주십니다. 예를 들어서 말씀드리고 싶었는데 제가 정말 질문을 많이 드려서 말씀드리기가 어렵네요 😅</p>
<p>그리고 가끔은 질문하지 않아도 궁금했을 법한 토픽들을 가져와서 설명해주실 때도 있어요! 또 JavaScript 미션을 진행하다가 난이도가 너무 어려워서 자괴감이 들었을 때, 강사님께 고민 상담을 한 적도 있어요. <u>공감과 응원</u>도 많이 해주시고, 현재 상황에 대한 <u>해결 방법</u>도 말씀해주셔서 아주 잠깐이지만 번아웃을 벗어날 수 있었어요. </p>
<p><strong>질의응답</strong> 말고도 <strong>멘탈적인 부분</strong>도 케어해주셔서 저에게는 굉장히 힘이 되는 분이세요!</p>
<br>

<hr>
<h3 id="제로베이스-추천해">제로베이스 추천해?</h3>
<p>여담이지만 저는 실제로 제 주위에 프론트엔드 개발자를 희망하는 분이 계셔서 저는 제로베이스를 추천했어요! 실제로 지금 23기에서 수강 중이세요. (제로베이스에서도 몰랐을 거예요)</p>
<p>아무래도 저와 같은 상황에 처해 있기 때문에 만족할 거라고 생각해서 추천했는데, 아직까지는 만족하는 것 같더라구요. 다시 한 번 말씀드리자면, 저는 다음과 같은 조건을 토대로 제로베이스를 선택했어요.</p>
<blockquote>
<ol>
<li><strong>비대면</strong> 진행</li>
<li><strong>많은 양의 프로젝트</strong> (토이 포함)</li>
<li>상대적으로 <strong>부담이 덜되는 가격</strong></li>
</ol>
</blockquote>
<p>그리고 아래는 제가 직접 수강하면서 느낀 장점들입니다.</p>
<blockquote>
<ol>
<li><strong>CS이론</strong>과 <strong>알고리즘</strong>을 별도로 챙기지 않아도 공부할 수 있다.
(코딩테스트까지 준비할 수 있어요)</li>
<li>궁금점이 생기면 바로바로 여쭤볼 수 있는 <strong>멘토</strong>분이 계신다. 
(멘탈 관리도 해주세요) </li>
<li><strong>실습이 정말 많다.</strong> 
(생각했던 것보다 정말 많고, 그만큼 뿌듯함도 많이 느낄 수 있어요)</li>
</ol>
</blockquote>
<br>

<p>저는 제로베이스를 선택한 것에 후회하지 않아요. 커리큘럼이 정말 잘 짜여져 있고, 강의들도 평생 수강할 수 있어서 만약 입사 이후 다시 공부하고 싶을 때 <strong>언제든지 강의를 볼 수 있기</strong> 때문이에요.</p>
<p>앞으로 남은 3달도 열심히 달릴 예정입니다. 정말정말 쉽지는 않지만 제 실력이 늘어가는 걸 느낄 때의 뿌듯함 덕분에 계속 진행하고 있는 것 같아요.</p>
<p>다른 분들도 파이팅하셨으면 좋겠고, 고민 중이신 분들은 후회없는 선택하셨으면 좋겠습니다! 👊🏻👊🏻</p>
<br>

<hr>
<h3 id="아직도-고민이-된다면">아직도 고민이 된다면</h3>
<blockquote>
<p>프론트엔드 취업 스쿨의 <a href="https://zero-base.co.kr/category_dev_camp/school_FE"><strong>상세 페이지</strong></a>를 통해 조금 더 정보를 얻어보세요!</p>
</blockquote>
<p>처음이라 막막하거나, 어떤 부트캠프를 선택할지 고민이신 분들은 위의 <strong>상세 페이지</strong>에서 정보를 얻고 좋은 선택하셨으면 좋겠습니다! </p>
<p>또한, 오픈카톡도 존재하고, 고민 중이신 분들을 위한 강의도 존재하는 걸로 알고 있어요! 이러한 부분들도 참고하신다면 조금 더 도움이 되실 거라고 생각해요.</p>
<br>
<br>

<p><code>해당 게시글은 소정의 원고료를 받아 작성되었습니다</code> </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DOM API]]></title>
            <link>https://velog.io/@reina__/DOM-API</link>
            <guid>https://velog.io/@reina__/DOM-API</guid>
            <pubDate>Fri, 12 Jan 2024 02:38:48 GMT</pubDate>
            <description><![CDATA[<p>동적인 웹 사이트를 만들기 위해 필요한 언어인 <code>JavaScript</code> 는 어떻게 웹을 동적으로 만들어줄 수 있는 걸까?</p>
<p>우선 웹을 동적으로 변환시키기 전에 HTML과 CSS의 요소를 받아와야 하는데, 이때 필요한 게 <code>DOM</code>이다. <code>DOM</code> 을 통해 HTML/CSS의 요소에 접근한 <code>JavaScript</code> 는 다양한 프로퍼티와 메소드를 활용해 요소를 수정하며 웹 페이지를 동적으로 동작하게 만든다. <code>DOM</code> 에 대한 자세한 설명은 아래를 참고하자.</p>
<br>

<hr>
<h2 id="dom">DOM</h2>
<p>&#39;Document Object Model&#39; 의 약자인 <code>DOM</code> 은 직역하자면 <code>문서 객체 모델</code>이다. 문서 객체란 <code>&lt;html&gt;</code> 이나 <code>&lt;body&gt;</code> 같은 HTML 요소들이 자바스크립트가 이용할 수 있는 객체로 만들어진 것을 말한다. 
<img src="https://velog.velcdn.com/images/reina__/post/512f9f73-5194-4e83-b6a5-4a9791383a84/image.png" alt=""></p>
<p>이 DOM은 자바스크립트 명령에 의해 속성이나 디자인, 배치 등이 제어될 수 있다. </p>
<p>웹 페이지를 만들 때 자바스크립트와 DOM이 한 몸처럼 사용되다보니, 자바스크립트 안에 DOM이 있다거나 DOM을 자바스크립트로만 다룰 수 있다는 오해를 빚기도 한다. (나다) 그 이유는 <strong>현재 웹 브라우저에서 DOM을 조작하는 언어는 자바스크립트 뿐</strong>이기 때문이다. </p>
<p>그러나 파이썬에서도 <code>BeautifulSoup</code> 라는 대표적인 DOM 트리 파싱 라이브러리가 있듯이 자바스크립트로만 DOM을 다룰 수 있는 것은 아니고, 자바스크립트와 DOM은 엄밀히 다른 개념이다. 왜냐하면, <code>DOM API</code> 는 JavaScript API가 아닌 <code>Web API</code> 이기 때문이다. </p>
<p>이로 인해 만약 브라우저가 자바스크립트 외에 다른 언어를 지원하게 된다면 그 언어를 통해 DOM을 사용하여 동일한 방식으로 HTML 문서를 조작하고 화면을 렌더링할 수 있을 것이다.</p>
<br>

<hr>
<h2 id="dom-api">DOM API</h2>
<p>프로그래밍 언어가 문서 구조, 스타일, 내용 등을 변경할 수 있게 하는 인터페이스이다.</p>
<p>브라우저에서 제공하는 Web API* 중 하나로, 이 API를 통해 원하는 대로 DOM을 찾고 조작할 수 있다. 정적인 웹 페이지에 접근하여 동적으로 웹 페이지를 변경하기 위해서는 메모리 상에 존재하는 DOM을 변경해야 하고, 이때 필요한 것이 DOM 요소들을 변경하는 프로퍼티와 메서드 집합인 DOM API인 것이다. 대표적으로는 노드를 취득하는 API (ex. document.querySelector), 그리고 노드를 추가 또는 조작하는 API (ex. Node.appendChild) 등이 있다.</p>
<p><strong>*API</strong> (Application Programming Interface)
: 어떤 어플리케이션이나 웹 페이지의 동작을 위해 입력하는 프로그래밍 명령이라고 생각하면 쉽다. </p>
<br>

<p><strong>자주 쓰는 HTML DOM Methods에는 다음과 같은 것들이 있다.</strong>  </p>
<blockquote>
<p><strong>1. 선택 메소드</strong>: HTML의 요소에 접근하고 싶을 때 사용  </p>
</blockquote>
<pre><code class="language-js">/* id 속성으로 선택 */
document.getElementById(&#39;this-is-id&#39;);
document.querySelector(&#39;#this-is-id&#39;);
document.querySelectorAll(&#39;#this-is-id&#39;);
&gt;
/* class 속성으로 선택 */
document.getElementsByClassName(&#39;this-is-class&#39;);
document.querySelector(&#39;.this-is-class&#39;);
document.querySelectorAll(&#39;.this-is-class&#39;);
&gt;
/* tag 속성으로 선택 */
document.getElementsByTagName(&#39;input&#39;);
document.querySelector(&#39;input&#39;);
document.querySelectorAll(&#39;input&#39;);</code></pre>
<p>나는 <code>querySelector(All)</code> 로 요소를 많이 선택하는데, 그 이유는 편하기 때문이다. 물론 속도적인 측면에서는 <code>getElement(s)By</code> 가 더 빠르지만, 아직은 연습 중이기도 하고 <code>querySelector(All)</code> 도 초당 약 7백만건의 작업을 처리해 느린 속도가 전혀 아니기 때문이다. </p>
<blockquote>
<p>만약 이 둘 중 무얼 사용해야 할지 모르겠다면?</p>
</blockquote>
<ol>
<li>runtime 감소 목적 ⇒ <code>getElement(s)By</code></li>
<li>개발의 편함 목적 ⇒ <code>querySelector(All)</code></li>
</ol>
<br>

<blockquote>
<p><strong>2. 기타 메소드</strong></p>
<pre><code class="language-HTML">&lt;div id=&quot;this-is-id&quot;&gt;&lt;/div&gt;</code></pre>
<pre><code class="language-js">const $id = document.querySelector(&#39;#this-is-id&#39;);
</code></pre>
</blockquote>
<p>/* HTML 요소를 생성 */
const divDOM = document.createElement(&#39;div&#39;);</p>
<blockquote>
</blockquote>
<p>/* 생성된 요소에 class 추가 */
divDOM.className = &#39;this-is-class&#39;;
divDOM.classList.add(&#39;class2&#39;);</p>
<blockquote>
</blockquote>
<p>/* HTML 요소에 텍스트 추가 */
$id.innerHTML = &#39;this is id&#39;;
divDOM.innerHTML = &#39;this is class&#39;;</p>
<blockquote>
</blockquote>
<p>/* HTML 요소에 추가 */
$id.append(divDOM);</p>
<blockquote>
</blockquote>
<p>/* 텍스트를 출력 */
document.write(&#39;document write&#39;);</p>
<pre><code>&gt;
![](https://velog.velcdn.com/images/reina__/post/867dfbd8-a354-43b7-b49d-0aa2d47e13c6/image.png)

방금 알아낸 사실이 하나 있는데, append() 이후 부모 노드(`$id`)의 innerHTML을 수정하니 append 된 애들이 사라진다... 

&gt;```js
/* HTML 요소에 추가 */
$id.append(divDOM);
&gt;
/* HTML 요소에 텍스트 추가 */
$id.innerHTML = &#39;this is id&#39;;
divDOM.innerHTML = &#39;this is class&#39;;</code></pre><p><img src="https://velog.velcdn.com/images/reina__/post/7365859e-68cc-4180-83a6-bae263d08595/image.png" alt=""></p>
<p>여기서 잠깐 <code>append()</code> 메소드와 <code>innerHTML</code> 을 <strong>혼용할 때 주의점</strong>을 설명해주겠다. (빠른 도움 주신 김영민 강사님 감사합니다!)</p>
<p>innerHTML 속성을 수정하면 브라우저는 해당 DOM 요소의 내부 HTML(모든 자식 요소)을 새로운 값으로 완전히 재구성한다. 이 과정에서  <code>append()</code> 메소드로 추가된 요소들은 새로운 HTML 구조에 포함되어 있지 않은 요소들이므로 사라지게 된다.</p>
<p>반면, 부모 요소가 아닌 자식 요소의 innerHTML을 변경할 시 부모 요소에 append된 요소들은 영향을 받지 않는다. 이는 innerHTML 속성이 특정 요소에만 영향을 미치고 그 요소의 자식들만 재구성하기 때문이다. (만약 자식 요소에 append를 하고 innerHTML을 변경하면 해당 요소의 자식들이 사라지는 것은 동일)</p>
<p>이로 인해 append와 innerHTML 수정을 혼합해서 사용할 때는 이 점을 주의해서 사용해야 한다.</p>
<br>

<blockquote>
<p><strong>3. 이벤트 메소드</strong>: 요소의 이벤트에 대한 반응을 연결할 때 사용</p>
</blockquote>
<pre><code class="language-js">/* 요소의 onclick 속성에 함수를 준다. */
요소.onclick = function( ){ }
&gt;
/* 요소에 click이벤트가 발생했을 경우, 실행할 함수를 준다. */
요소.addEventListener( &#39;click&#39;, 실행할 함수 )</code></pre>
<p>이벤트 메소드에 대한 자세한 설명은 글을 새로 작성하겠다! (링크는 글 작성 이후 연결할 예정)</p>
<br>

<hr>
<p>이렇게 오늘은 DOM API에 대해 알아보았다. 이 글을 알면서 새롭게 알게 된 점이 3가지 있다. </p>
<ol>
<li><code>DOM API</code> 가 자바스크립트 소속이 아닌 <code>WEB API</code> 였다는 점</li>
<li><code>getElement(s)By</code> 가 <code>querySelector(All)</code> 보다 속도가 빠르다는 점</li>
<li><code>append()</code> 메소드와 <code>innerHTML</code> 을 혼용할 때의 주의점</li>
</ol>
<p>블로그 쓸 시간을 낼 수 없어 미루고 미루다 쓰고 있는 요즘인데 글을 작성하면서 더 깊게 검색하니까 강의를 들을 때보다 더 많은 걸 알아가게 되는 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTTP와 HTTPS]]></title>
            <link>https://velog.io/@reina__/HTTP%EC%99%80-HTTPS</link>
            <guid>https://velog.io/@reina__/HTTP%EC%99%80-HTTPS</guid>
            <pubDate>Thu, 11 Jan 2024 07:25:53 GMT</pubDate>
            <description><![CDATA[<p>이 URL은 왜 <code>HTTP</code> 로 시작하고 저 URL은 왜 <code>HTTPS</code> 로 시작하지... 개발자 준비를 하기 전에 갖고 있던 궁금증이었다. 공부를 시작한 지금은 이미 알게 된 개념이지만, 조금 더 깊게 알아보고자 글을 작성하게 됐다.</p>
<br>

<hr>
<h2 id="http">HTTP</h2>
<p><code>Hypertext Transfer Protocol</code> 의 약자로 <strong>서로 다른 시스템들 사이에 통신을 주고 받게 해주는 가장 기본적인 프로토콜</strong>이다. 웹 서핑 시 서버에서 브라우저로 데이터를 전송해주는 용도로 가장 많이 사용하며, 인터넷 초기 웹 사이트에서 기본적으로 사용했던 프로토콜이다.</p>
<p>이 HTTP는 암호화가 되지 않은 평문 데이터를 전송하는 프로토콜이므로, 민감한 정보를 주고 받으면 제 3자가 정보를 조회할 수 있다.</p>
<p>이러한 보안적 결함을 해결하기 위해 나온 게 <code>HTTPS</code> 이다.</p>
<br>

<hr>
<h2 id="https">HTTPS</h2>
<p><code>Hypertext Transfer Protocol Secure</code> 의 약자로 HTTP의 보안 문제를 해결하고자 SSL(보안 소켓 계층)을 사용해 보다 안전한 프로토콜이다. 서버와 브라우저가 통신하는 과정에서 SSL이 전송 내용을 암호화한다. 암호화를 통해 발신자와 수신자를 제외한 중간 매개체에서 통신 내용을 확인할 수 없기 때문에, 발신자가 전송한 암호 및 기밀 문서를 보호할 수 있다.</p>
<br>

<h3 id="🔗--대칭키-암호화와-비대칭키-암호화">🔗 &nbsp; 대칭키 암호화와 비대칭키 암호화</h3>
<p>HTTPS는 대칭키 암호화 방식과 비대칭키 암호화 방식을 모두 사용하고 있으며, 각각의 암호화 방식은 다음과 같다.</p>
<blockquote>
<p><strong>대칭키 암호화</strong>
대칭키는 비교적 쉬운 개념으로, 클라이언트와 서버가 동일한 키를 사용해 암호화 및 복호화를 진행한다. 키가 노출되면 위험하지만 연산 속도가 빠르다는 특징이 있다.</p>
</blockquote>
<blockquote>
<p><strong>비대칭키 암호화</strong>
비대칭키 암호화는 공개키/개인키 암호화 방식을 이용해 데이터를 암호화하고 있다. 공개키와 개인키는 서로를 위한 1쌍의 키이다. 키가 노출되어도 비교적 안전하지만 연산 속도가 느리다는 특징이 있다.
<br></p>
<p>암호화를 공개키로 하느냐 개인키로 하느냐에 따라 얻는 효과가 다르다.</p>
<p><code>공개키(Public Key)</code> 로 암호화하면 <strong>데이터 보안</strong>에 중점을 두고,
<code>개인키(Private Key)</code> 로 암호화하면 <strong>인증 과정</strong>에 중점을 둔다.  </p>
<ul>
<li><strong>공개키</strong>: 모두에게 공개하는 키  <strong>[<font color="blue">공개키</font> (암호화) → <font color="purple">개인키</font> (복호화)]</strong>    <ul>
<li><code>A Key</code> (암호화) → <code>B Key</code> (복호화) :: <code>B Key</code> (암호화) → <code>A Key</code> (복호화)</li>
<li>공개키는 널리 배포될 수 있기 때문에 많은 사람들이 한 명의 개인키 소유자에게 데이터를 보낼 수 있다. </li>
</ul>
</li>
</ul>
<ul>
<li><strong>개인키</strong>: 나만 소유하고 알고 있는 키  <strong>[<font color="purple">개인키</font> (암호화) → <font color="blue">공개키</font> (복호화)]</strong><ul>
<li>암호화된 데이터가 공개키로 복호화된다는 것은 공개키와 쌍을 이루는 개인키에 의해서 암호화 되는 것이다. 이는 <strong>데이터 제공자의 신원 확인이 보장</strong>된다는 것을 의미한다.</li>
<li>이 방법은 공인인증체계의 기본 바탕이 되는 <strong>전자 서명</strong>이다.</li>
</ul>
</li>
</ul>
</blockquote>
<br>

<h3 id="🔗--https의-동작-과정">🔗 &nbsp; HTTPS의 동작 과정</h3>
<p>HTTPS 연결 과정에서 먼저 서버와 클라이언트 간에 연결을 성립하여 안전하게 세션키를 공유하는 과정에서 <code>비대칭키</code>를 사용하고, 이후에 데이터를 교환하는 과정에서 빠른 연산 속도를 위해 <code>대칭키</code>를 사용한다.</p>
<p><strong>HTTPS 연결 과정</strong></p>
<ol>
<li>클라이언트가 서버로 최초 연결 시도</li>
<li>서버는 공개키를 브라우저에게 전달</li>
<li>브라우저는 인증서의 유효성 검사 후 세션키 발급</li>
<li>브라우저는 세션키를 보관하고 서버의 공개키로 세션키를 암호화하여 서버로 전송</li>
<li>서버는 개인키로 암호화된 세션키를 복호화하여 세션키 획득</li>
<li>클라이언트와 서버는 동일한 세션키를 공유하므로 데이터를 전달할 때 세션키로 암호화/복호화 진행</li>
</ol>
<br>

<h3 id="🔗--웹사이트-https-설정-방법--출처">🔗 &nbsp; 웹사이트 HTTPS 설정 방법 &nbsp; (<a href="https://seo.tbwakorea.com/blog/https-http/">출처</a>)</h3>
<p><strong>서버 측 설정</strong></p>
<p>서버 엔진에 따라 설정 방법은 다르지만 기본적으로 HTTPS는 443번 포트를 통해 통신을 진행한다.
따라서 서버 측에서 코드를 통해 HTTP 통신 방식인 80번 포트를 막고 443번 포트를 열어야 한다. 또는 80 포트를 열어두지만 80번 → 443번 포트로 리디렉션 시켜 최종적으로 443번 포트에서 통신이 이루어지게 만들어야 한다.</p>
<p>간략하게 Node.js 기반 Express 프레임워크 서버를 사용하는 서버 엔진에서 443 포트를 오픈한 코드이다.</p>
<pre><code class="language-js">const https = require(&#39;https&#39;);
const fs = require(&#39;fs&#39;);
const express = require(&#39;express&#39;);

const privatekey = fs.readFileSync(__dirname + &#39;/sslkey/private.pem&#39;, &#39;utf8&#39;);
const certkey = fs.readFileSync(__dirname + &#39;/sslkey/cert.pem&#39;, &#39;utf8&#39;);
const csrkey = fs.readFileSync(__dirname + &#39;/sslkey/csr.pem&#39;, &#39;utf8&#39;);

const sslkey = {
    key: privatekey,
    cert: certkey,
    ca: csrkey
};

const app443 = express();
const httpsServer = https.createServer(sslkey, app443);

httpsServer.listen(443, () =&gt; {
    logger.info(`server start : 443 port`);
});</code></pre>
<p>Django, JSP 등 각각 서버단에서 코드 수정을 통해 443 포트로 통신해야 HTTPS를 시작할 수 있다.
<br></p>
<p><strong>SSL(TLS) 인증서 구매</strong></p>
<p>위 과정을 통해 443 포트를 오픈하면 HTTPS 통신을 할 수 있다.
하지만 SSL 인증서가 없어 신뢰할 수 없는 홈페이지라는 알림이 발생할 것이다. 이 문제를 해결하기 위해서 신뢰할 수 있는 SSL 인증서 판매 기관에 매년 일정 금액을 지불하고 SSL 인증서를 구매해 발급받아야 한다.</p>
<p>SSL 인증서를 발급받으면 3개의 파일이 주어진다. 각 파일은 <code>csr키</code>, <code>비밀키</code>, <code>인증키</code>로 서버 정보가 담긴 키와 인증서를 발급해 준 신뢰 기관 정보키들로 구성된다. 이 파일들을 운영하는 서버 환경에 맞게 업로드하고 적용해야 HTTPS 통신을 오류창 없이 완벽하게 진행할 수 있다.</p>
<br>

<h3 id="🔗--https는-보안만-잘하나요">🔗 &nbsp; HTTPS는 보안만 잘하나요?</h3>
<p>HTTPS의 장점은 보안 뿐만 아니라 검색엔진 최적화(SEO)에 있어서도 큰 혜택을 볼 수 있다. 
구글이 HTTPS 웹 사이트에 가산점을 준다는 점도 있지만, 사용자들이 안전하다고 생각하는 사이트를 더 많이 방문한다는 점도 있다.</p>
<p><strong>1. 더 나은 사용자 경험</strong>
사용자들이 사이트를 방문했을 때 지나친 광고들을 맞이한다면 사이트에 오래 머물지 않을 것이다. (나도 그렇다) 
또한, Google은 SSL 인증서가 없는 사이트에 <code>안전하지 않은 사이트</code> 라고 레이블을 지정해 사용자의 접속을 꺼리게 만들어 검색 엔진에서 낮은 우선순위를 담당하게 될 것이다.</p>
<p><strong>2. 사이트 체류 시간 증가</strong>
웹 사이트의 체류 시간이 낮다는 것은 사용자의 검색 의도와 일치하지 않는다는 것을 의미한다. 
<code>안전하지 않은 사이트</code> 라는 메시지를 직면한 사용자들의 체류 시간은 줄어들 수 있고, 이는 콘텐츠가 검색 의도와 최적화 돼 있더라도 검색 엔진에서의 낮은 우선순위를 담당하게 되는 원인이 될 수 있다.</p>
<p><strong>3. 사이트 로딩 속도 개선</strong>
페이지 로딩 시 3초 이상 소요되면 방문자의 대부분이 사이트를 이탈한다고 한다. HTTPS는 HTTP 보다 300% 이상 더 빠르게 로딩하므로 SEO적으로 유리하다.</p>
<p><strong>4. SEO 전략 확인 및 검증</strong>
사이트가 안전하지 않다고 판단되는 HTTP 사이트는 referral 정보가 제거되어 트래픽 소스를 확인할 수 없다. 이로 인해 자신의 웹 사이트의 들어온 방문자의 경로를 파악하기 어렵다. 
반면, HTTPS 사이트는 분석 대시보드에서 referral 정보를 보호하고 표시하므로, 최적의 트래픽 소스를 명확히 찾아내서 광고를 더욱 효과적으로 할 수 있을 것이다.</p>
<br>

<hr>
<h2 id="http와-https의-차이점-요약">HTTP와 HTTPS의 차이점 요약</h2>
<table>
<thead>
<tr>
<th align="center">-</th>
<th align="center">HTTP</th>
<th align="center">HTTPS</th>
</tr>
</thead>
<tbody><tr>
<td align="center">의미</td>
<td align="center">Hypertext Transfer Protocol</td>
<td align="center">Hypertext Transfer Protocol Secure</td>
</tr>
<tr>
<td align="center">포트</td>
<td align="center">기본 포트 80</td>
<td align="center">기본 포트 443</td>
</tr>
<tr>
<td align="center">용도</td>
<td align="center">이전 텍스트 기반 웹 사이트</td>
<td align="center">모든 최신 웹 사이트</td>
</tr>
<tr>
<td align="center">보안</td>
<td align="center">추가 보안 기능 없음</td>
<td align="center">퍼블릭 키 암호화에 SSL 인증서 사용</td>
</tr>
<tr>
<td align="center">이점</td>
<td align="center">인터넷을 통한 통신 지원</td>
<td align="center">웹 사이트에 대한 권위, 신뢰성 및 검색 엔진 순위 개선</td>
</tr>
</tbody></table>
<br>

<hr>
<p>오늘은 HTTP와 HTTPS의 차이점, HTTPS의 동작 과정, 설정 방법 등에 대해 알아보았다. 이론만 공부했을 때는 그냥 그 차이만 알고 있었는데, 이 글을 작성하면서 생각보다 HTTPS의 힘이 크다는 것을 알게 되었다. 만약 나중에 나의 사이트를 만들어 배포할 날이 온다면 HTTPS는 꼭 설정해야겠다고 느꼈다.</p>
<br>

<h3 id="참고">참고</h3>
<blockquote>
<p><a href="https://mangkyu.tistory.com/98">tistory :: [Web] HTTP와 HTTPS의 개념 및 차이점</a>
<a href="https://seo.tbwakorea.com/blog/https-http/">tbwakorea :: HTTPS란? – HTTP와의 차이점 및 전환의 중요성</a>
<a href="https://www.ascentkorea.com/difference-between-http-and-https/">ascent :: HTTP HTTPS 차이: 당신의 웹 사이트는 안전한가요?</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[브라우저 저장소]]></title>
            <link>https://velog.io/@reina__/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EC%A0%80%EC%9E%A5%EC%86%8C</link>
            <guid>https://velog.io/@reina__/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EC%A0%80%EC%9E%A5%EC%86%8C</guid>
            <pubDate>Thu, 11 Jan 2024 02:49:14 GMT</pubDate>
            <description><![CDATA[<p>브라우저에는 웹 사이트의 상태나 데이터 등을 저장하기 위한 저장소가 존재한다. 이를 활용해 웹 사이트는 소유자의 데이터를 장기적으로 저장하기 위해 <strong>유지</strong>하고, 오프라인 사용을 위해 <strong>콘텐츠나 문서를 저장</strong>하고, <strong>사용자 기본 설정을 저장</strong>하고, <strong>상태를 적용</strong>하는 등의 작업을 수행할 수 있다.</p>
<p>브라우저에 웹 사이트 데이터를 저장하는 저장소는 <code>localStorage</code>, <code>sessionStorage</code>, <code>IndexedDB</code> 로 세 가지가 있다. 이들은 사용자의 브라우저에 로컬 데이터를 저장한다는 점은 동일하지만 용도 및 용량, 성능이 다르다.</p>
<p>오늘은 이들의 차이점과 장단점에 대해 알아보자.</p>
<br>

<hr>
<h2 id="localstorage"><code>localStorage</code></h2>
<p><code>localStorage</code> 는 최대 5~10MB까지 저장할 수 있으며, 저장된 데이터의 경우 삭제하지 않는 이상 만료되지 않고 <strong>영구적으로 유지</strong>된다. 이로 인해 <strong>자동 로그인</strong>이나 <strong>다크 모드</strong> 등에 주로 사용한다.</p>
<p>페이지의 프로토콜별로 구분하여 저장되므로 <code>https://naver.com</code> 와 <code>http://naver.com</code> 의 <code>localStroage</code> 는 서로 공유가 되지 않는다.</p>
<p><code>key-value</code> 쌍을 저장할 수 있으며, key와 value의 경우 <code>문자열</code> 을 사용해야 한다. 만약 다른 값(배열, 객체 등)을 사용하고 싶다면, <code>JSON.stringify();</code> 메서드를 사용해 문자열로 변환 후 사용하면 된다.</p>
<pre><code class="language-js">localStorage.setItem(“name”, “reina”);
localStorage.getItem(“name”);     // &quot;reina&quot;
localStorage.removeItem(“name”);  // null

/* 객체 저장 시 */
localStorage.setItem(&quot;name&quot;, JSON.stringfy({ 1 : &quot;reina&quot; }));
JSON.parse(localStorage.getItem(&quot;name&quot;));   // { 1 : &quot;reina&quot; }</code></pre>
<blockquote>
<h4 id="장점">장점</h4>
<ul>
<li><strong>간편한 사용</strong>: 간단한 key-value 형식으로 데이터를 저장하고 검색할 수 있다. </li>
<li><strong>데이터의 영구성</strong>: 데이터가 영구적으로 보존되므로 사용자가 웹 사이트를 다시 방문할 때 이전에 저장한 데이터를 사용할 수 있다.</li>
<li><strong>동기 작업</strong>: <code>setItem</code> 이나 <code>getItem</code> 과 같은 데이터 읽기 및 쓰기를 위한 동기식 API를 수행하므로, 데이터에 대한 신뢰성과 안정성을 제공하며 비동기 처리로 인한 복잡성이 줄어든다.</li>
</ul>
</blockquote>
<blockquote>
<h4 id="단점">단점</h4>
<ul>
<li><strong>보안 위험</strong>: 클라이언트 측에 데이터를 저장하므로 보안에 주의해야 한다. 따라서 중요한 정보나 민감한 데이터를 저장하기엔 적합하지 않고, 꼭 해야 한다면 암호화를 고려해야 한다.</li>
<li><strong>불편한 데이터 관리</strong>: <code>localStorage</code> 는 JavaScript를 사용하여 데이터를 직접 관리해야 한다. 데이터의 추가, 수정, 삭제 등을 수동으로 처리해야 하며, 복잡한 데이터 관리 기능은 제공되지 않는다.</li>
<li><strong>제한된 도메인</strong>: 저장된 데이터는 도메인에 따라 다르므로 한 도메인에 저장된 데이터는 다른 도메인에서 접근할 수 없다. 이로 인해 다른 사용자의 컴퓨터와 결과가 다를 수 있다.</li>
</ul>
</blockquote>
<br>

<hr>
<h2 id="sessionstorage"><code>sessionStorage</code></h2>
<p><code>sessionStorage</code> 와 <code>localStorage</code> 의 가장 큰 차이점은 <strong>데이터의 영구성</strong>이다. <code>sessionStorage</code> 는  브라우저 세션이 종료될 때 저장된 데이터가 삭제되므로 데이터의 만료 기간이 존재한다. (새로고침은 해당 안 됨) <strong>비로그인 장바구니</strong>, <strong>글쓰기 내용 복구</strong>, <strong>입력 폼 정보 저장</strong>, <strong>사이트 언어 선택</strong> 등에 사용된다.</p>
<pre><code class="language-js">sessionStorage.setItem(“name”, “reina”);
sessionStorage.getItem(“name”);     // &quot;reina&quot;
sessionStorage.removeItem(“name”);  // null</code></pre>
<p><code>sessionStorage</code> 의 장단점은 <code>localStorage</code> 과 모두 동일하지만 데이터의 보안과 영구성에 대해 반대의 장단점을 가진다.</p>
<blockquote>
<h4 id="장점-1">장점</h4>
<ul>
<li><strong>데이터 보안</strong>: 데이터가 서버로 전송되지 않아 민감한 데이터를 임시로 저장하기에 적합하다. 하지만 클라이언트 측에 데이터를 저장하므로 이에 대한 위험은 여전히 존재한다.</li>
</ul>
</blockquote>
<blockquote>
<h4 id="단점-1">단점</h4>
<ul>
<li><strong>데이터의 일시성</strong>: 세션이 종료되면 데이터가 삭제되므로, 영구적인 저장이 필요한 데이터에는 적합하지 않다.</li>
</ul>
</blockquote>
<br>

<hr>
<h2 id="indexeddb"><code>indexedDB</code></h2>
<p>비교적 최근에 추가된 기술로 브라우저에 데이터를 영구적으로 저장할 수 있는 방법이다. 이는 구조화된 데이터를 저장하기 위한 <strong>객체 지향 데이터베이스</strong>로, 대량의 데이터를 처리하기에 적합하다는 특징을 가진다.</p>
<p><code>object</code>, <code>key-value</code> 모두 저장 가능하며, <code>IndexedDB</code> 작업은 <code>onsuccess</code>, <code>onerror</code>, <code>oncomplete</code> 등과 같이 다양한 이벤트에 의해 이벤트 구동된다.</p>
<blockquote>
<h4 id="장점-2">장점</h4>
<ul>
<li><strong>큰 용량</strong> : 큰 용량(최대 nGB)으로 인해 많은 양의 데이터를 저장할 수 있어 대용량 데이터 관리에 적합하다.</li>
<li><strong>구조화된 데이터</strong> : 데이터를 테이블 형식이 아닌 객체 저장소로 저장한다. 이로 인해 복잡한 데이터 유형(배열, 객체 등)을 처리할 수 있다.. 또한, 데이터베이스 스키마를 정의하고 쿼리를 실행하여 데이터를 효율적으로 저장하고 검색할 수 있다.</li>
<li><strong>오프라인 지원</strong> : 웹을 오프라인 환경에서 동작시킬 수 있는 기능을 제공한다. 이로 인해 데이터를 로컬에 저장해 오프라인 환경에서도 동작하며 지속적인 인터넷 연결이 필요하지 않은 애플리케이션에 유용하다.</li>
<li><strong>비동기 작업</strong>: 비동기식 API를 통해 대용량 데이터를 처리하는데 더 나은 성능을 제공하고, 응답 시간 또한 빠르다. </li>
</ul>
</blockquote>
<blockquote>
<h4 id="단점-2">단점</h4>
<ul>
<li><strong>복잡성</strong> : 다른 웹 스토리지 기술에 비해 사용법이 복잡하다. 데이터베이스 스키마를 정의하고 인덱스를 관리하는 등의 작업에 익숙해지는 데 시간이 걸릴 수 있다.</li>
<li><strong>제한적인 호환성</strong> : 모든 브라우저에서 완벽하게 지원되지 않을 수 있다. 비교적 최근 웹 브라우저에서만 지원하는 기능으로, 오래된 브라우저 버전에서는 호환성 문제가 발생할 수 있다.</li>
</ul>
</blockquote>
<br>

<hr>
<p><code>localStorage</code>, <code>sessionStorage</code> 및 <code>IndexedDB</code> 는 모두 장단점이 있다. </p>
<p><code>localStorage</code>, <code>sessionStorage</code>는 사용이 간단하고 쉽지만, 용량이 제한되어 있고 도메인에 따라 다르다.
<code>IndexedDB</code>는 구조화된 데이터를 저장하기 위한 강력한 기능을 제공하지만, 사용하기가 복잡하고 모든 브라우저에서 완벽히 지원되지 않는다. </p>
<p>이러한 점들을 참고해 스토리지를 선택할 때는 각각의 장단점을 잘 따져 현재 상황에 알맞은 스토리지를 선택해야 할 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모듈화]]></title>
            <link>https://velog.io/@reina__/%EB%AA%A8%EB%93%88%ED%99%94</link>
            <guid>https://velog.io/@reina__/%EB%AA%A8%EB%93%88%ED%99%94</guid>
            <pubDate>Thu, 11 Jan 2024 01:16:35 GMT</pubDate>
            <description><![CDATA[<p>JavaScript의 Class를 설명할 때 가장 많이 사용하는 예시로는 붕어빵 틀을 얘기한다. 붕어빵 틀(<code>클래스</code>)에 반죽과 소를 넣어 만든 붕어빵(<code>인스턴스</code>)처럼 우리는 클래스를 활용해 JavaScript의 객체나 메소드를 <strong>모듈화</strong> 해서 사용할 수 있다.</p>
<br>

<hr>
<h3 id="모듈화">모듈화?</h3>
<p>붕어빵을 만들 때 필요한 것은 바로 틀(<code>클래스</code>), 반죽과 소(<code>프로퍼티</code>), 그리고 만드는 방법(<code>메소드</code>)이다. 이 모든 게 준비되면 우리는 반죽과 소(<code>프로퍼티</code>)만 입맛에 맞게 넣어 만들면 된다. 이를 우리는 class를 활용해서 붕어빵을 만드는 방법을 <code>모듈화</code> 했다고 할 수 있다.</p>
<pre><code class="language-js">class Bungeoppang {
    constructor(dough, ingredient) {
        this.dough = dough;
        this.ingredient = ingredient;
    }    

    makeBungeo() {
          console.log(`붕어빵 틀에 ${this.dough}을 붓고, ${this.ingredient}을 넣어 적당히 굽는다.`);
    }
}

const 팥붕 = new Bungeoppang(&#39;반죽&#39;, &#39;팥&#39;);
팥붕.makeBungeo();

const 슈붕 = new Bungeoppang(&#39;반죽&#39;, &#39;슈크림&#39;);
슈붕.makeBungeo();

console.log(&#39;맛있는 붕어빵들이 완성되었다!&#39;);
/* 붕어빵 틀에 반죽을 붓고, 팥을 넣어 적당히 굽는다.
  붕어빵 틀에 반죽을 붓고, 슈크림을 넣어 적당히 굽는다.
  맛있는 붕어빵들이 완성되었다! */</code></pre>
<p>class 내부의 <code>constructor</code> 를 활용해 class를 생성할 때 필요한 값을 바로 전달해줄 수 있다. <code>constructor(param1, param2, ...) { ... }</code> 를 작성하고, 인스턴스* 시 <code>new Bungeoppang(arg1, arg2, ...)</code> 로 작성하면 된다. </p>
<p>인스턴스 시 인수로 입력한 값이 <code>constructor</code> 로 전달되고, class의 <code>프로퍼티(속성)</code> 로 인지해 클래스 내의 <code>메소드</code>에서 이 값을 활용할 수 있다. 이로 인해 <code>makeBungeo()</code> 메소드에서 <code>this.dough</code> 와 <code>this.ingredient</code> 도 활용해 값을 출력할 수 있게 된다.</p>
<p><strong>*인스턴스</strong>: 클래스를 객체화 하는 행위 (붕어빵 틀을 활용해 실제 붕어를 만듦)</p>
<br>

<p>constructor를 사용하지 않은 예시도 한 번 봐보도록 하자.</p>
<pre><code class="language-js">class Calculator {
    add(a, b) { return a + b; }
    subtract(a, b) { return a - b; }
    multiply(a, b) { return a * b; }
    divide(a, b) { return a / b; }
}

const calculator = new Calculator();
console.log(calculator.add(4, 2));       // 6
console.log(calculator.subtract(4, 2));  // 2
console.log(calculator.multiply(4, 2));  // 8
console.log(calculator.divide(4, 2));    // 2</code></pre>
<p>이처럼 인스턴스 시 프로퍼티를 따로 전달하지 않고, 클래스 내의 메소드를 사용할 때 바로 인수를 전달해서 메소드를 이용할 수도 있다.</p>
<br>

<p>마지막으로 class 이름은 다른 변수와 구분하기 위해 <code>대문자</code> 로 시작해주면 된다는 점까지 알아가면 된다.</p>
<br>


<hr>
<p>붕어빵을 많이 먹는 편은 아니지만 블로그를 작성하면서 먹고 싶어졌다... ໒꒰ྀི◜⤙◝ ꒱ྀི১ 🫘🫘</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[noreferrer, noopener, nofollow]]></title>
            <link>https://velog.io/@reina__/noreferrer-noopener-nofollow</link>
            <guid>https://velog.io/@reina__/noreferrer-noopener-nofollow</guid>
            <pubDate>Wed, 10 Jan 2024 03:56:36 GMT</pubDate>
            <description><![CDATA[<p>웹 페이지 간의 이동을 위해 사용되는 <code>&lt;a&gt;</code> 태그의 보안을 강화시키는 방법에 대해 알아보자.</p>
<br>

<hr>
<h3 id="a-태그"><code>&lt;a&gt;</code> 태그?</h3>
<p>는 주로 아래와 같은 상황에서 사용한다.</p>
<blockquote>
<ol>
<li>같은 URL에서 페이지 이동을 하거나 어떤 data가 있는 위치로 이동하는 경우</li>
<li>다른 URL로 페이지 이동을 하거나 현재 페이지에서 제공하지 않는 data를 링크로 제공하는 경우</li>
</ol>
</blockquote>
<p>이를 위해 <code>&lt;a&gt;</code> 요소 내부에는 기본적으로 <code>href</code> 라는 속성이 존재한다. 해당 속성에 이동하고자 하는 목적지를 적어서 그 위치 혹은 경로로 이동하게 된다.</p>
<p>이때, 2번 상황에서는 몇 가지 속성을 추가하여 사용할 수 있다.</p>
<br>

<h3 id="target"><code>target=&quot;&quot;</code></h3>
<p>이 속성에는 아래와 같은 값을 통해 연결된 웹 페이지를 표시하는 방법에 대해 설정할 수 있다.</p>
<p>⭐️ <code>_blank</code> : 연결된 페이지를 새로운 윈도우나 탭에서 열기
🔗 <code>_self</code> (기본값) : 연결된 페이지를 링크가 위치한 현재 프레임에서 열기
🔗 <code>_parent</code> : 연결된 페이지를 현재 프레임의 부모 프레임에서 열기
🔗 <code>_top</code> : 연결된 페이지를 현재 윈도우 전체에서 열기
🔗 <code>프레임 이름</code> : 연결된 페이지를 명시된 프레임에서 열기</p>
<p>이 중에서 가장 많이 사용하는 값은 <code>_blank</code>이다. 이는 다른 URL로 페이지 이동을 하는 경우, 새로운 탭을 열어 그 탭에서 연결된 페이지를 표시한다.</p>
<br>

<p>이 <code>target=&quot;_blank&quot;</code> 에는 2가지 문제점이 존재한다.</p>
<blockquote>
<p><strong>1. 보안상 취약점</strong></p>
</blockquote>
<p>웹 사이트에서 연결 중인 페이지는 <a href="https://developer.mozilla.org/ko/docs/Web/API/Window/opener"><code>window.opener</code></a> 객체를 통해 연결 페이지에 부분적으로 접근할 수 있다. 이는 연결 페이지에서 이전 페이지를 제어할 권한이 있음을 뜻한다.</p>
<p>만약 연결된 페이지에서 <code>window.opener</code> 를 통해 부모 윈도우(현재 페이지)에 접근해서 <code>window.opener.location = 새로운 URL</code> 로 부모 윈도우의 URL을 바꿔친다면 어떨까? </p>
<p>주식이나 코인과 같은 자산 거래소나, 로그인이 반드시 필요한 웹 페이지에서 최악의 경우 악의적인 URL로 접근시킬 수 있다. 이렇게 부모 윈도우의 정보를 사용하거나 조작하여 개인정보를 유출시키는 가짜 페이지로 부적절한 리다이렉션을 하는 등의 보안 상 심각한 문제가 발생할 수 있다.</p>
<blockquote>
<p><strong>2. 성능 저하</strong></p>
</blockquote>
<p>연결된 페이지는 링크를 건 페이지와 같은 프로세스를 통해서 실행된다. 만약 연결된 페이지에서 높은 부하를 유발하는 기능이 실행되고 있으면 링크를 건 페이지에도 영향을 미쳐 의도하지 않게 성능이 저하되는 문제가 발생할 수 있다.</p>
<p>이러한 문제점을 보완하기 위해 존재하는 기능이 있다.</p>
<br>

<hr>
<h3 id="🌟-relnoreferrer-noopener">🌟 <code>rel=&quot;noreferrer noopener&quot;</code></h3>
<p>결론부터 말하자면 <code>&lt;a&gt;</code> 태그에 <code>rel=&quot;noreferrer noopener&quot;</code> 를 추가하면 된다. 자세한 설명은 아래에서 확인하자.</p>
<pre><code class="language-HTML">&lt;a href=&quot;https://velog.io/@reina__/posts&quot; target=&quot;_blank&quot; rel=&quot;noreferrer noopener&quot;&gt;
    믿고 열어봐!
&lt;/a&gt;</code></pre>
<br>


<h3 id="rel"><code>rel</code></h3>
<p>해당 속성은 relation의 줄임말로, 링크 타입을 통해 연결된 URL과의 관계를 명시하는데 사용한다. 수많은 링크 타입이 있지만 그 중에서도 <code>target=&quot;_blank&quot;</code> 의 취약한 보안을 보완해줄 수 있는 타입을 살펴보자.</p>
<br>

<h3 id="noreferrer"><code>noreferrer</code></h3>
<p>: <code>referrer</code> (이전 페이지) 정보 삭제</p>
<p>다른 페이지로 이동하는 경우 HTTP 요청 헤더에 <code>referrer</code> 를 포함시키는데, <code>referrer</code> 에는 현재 요청된 페이지가 어디서 링크되었는지에 대한 정보를 나타낸다.</p>
<p>HTTP 요청 헤더에 <code>referrer</code> 가 노출될 때 <code>referral leakage</code> 가 발생할 수 있고, 이로 인해 개인 정보나 키, 값 등이 유출되어 보안에 위험을 초래할 수 있다.</p>
<p>이런 경우 <code>rel=&quot;noreferrer&quot;</code> 을 사용하면 다른 페이지로 이동할 때 브라우저가 <code>Referer: HTTP</code> 헤더를 통해 이 페이지의 주소나 값을 <code>referrer</code> 로 보내는 것을 방지해 보안을 강화할 수 있다.</p>
<br>

<h3 id="noopener"><code>noopener</code></h3>
<p>: <code>opener</code> (새 페이지를 연 사람의 정보) 삭제</p>
<p><code>norefferer</code> 와 비슷하게 보안 위험을 방지하는 속성이다.</p>
<p><code>noopener</code> 가 적용되지 않은 링크의 페이지로 이동하면 <code>window.opener</code> 에 이전 페이지의 경로를 담아주어, 이동한 페이지에서 이전 페이지를 참조할 수 있게 된다.</p>
<p>이때 <code>window tab nabbing</code> 이라는 악의적인 공격이 발생할 수 있는데, 이는 연결된 페이지로 이동할 때 새로 열릴 페이지의 URL을 조작하여 다른 웹사이트로 이동하게 만드는 공격이다. 
스미싱 페이지에서 로그인을 해 계정 정보가 해킹되는 등의 사례가 이에 해당된다.</p>
<p>이런 경우 <code>rel=&quot;noopener&quot;</code> 를 적용하면 브라우저 컨텍스트의 권한없이 연결된 페이지를 열어준다. 이는, 새 창에서 <code>window.opener</code> 속성이 <code>null</code> 이 반환되어 이전 페이지에 대한 참조를 불가능하게 하므로 보안을 강화할 수 있다.</p>
<br> 

<p>아래는 <code>noopener</code> 에 대한 참고 사항이다.</p>
<ul>
<li><code>noopener</code> 속성을 사용한다면, <code>target</code> 속성의 값으로 <code>_top</code>, <code>_self</code>, <code>_parent</code> 속성을 제외한 모든 속성은 <code>_blank</code> 로 적용된다.</li>
<li>최근 브라우저(Firefox 79+ 등)는 <code>target=&quot;_blank&quot;</code> 를 지정하면 임의로 <code>rel=&quot;noopener&quot;</code> 설정과 동일한 보호 수준을 적용해준다.</li>
</ul>
<br>

<p>이렇게 취약한 보안을 보완해줄 수 있는 속성뿐만 아니라 SEO에 최적화할 수 있는 속성도 존재하는데 마지막으로 이를 알아보며 글을 마무리하겠다.</p>
<br>

<hr>
<h3 id="nofollow"><code>nofollow</code></h3>
<p><code>nofollow</code> 는 검색 엔진 최적화(SEO)와 관련된 속성으로 링크된 문서가 이 문서의 작성자에 의해 보증되지 않았음을 나타낸다.</p>
<p>Google에서 내 사이트와 링크된 페이지를 연결하지 않기를 바라거나, 크롤러가 링크된 페이지를 크롤링*하지 않기를 바라는 경우 <code>rel=&quot;nofollow&quot;</code> 를 사용한다. </p>
<p>보통 스팸 댓글과 같은 경우에 이를 설정하여 해당 페이지로 이동하더라도 스팸 댓글의 링크에 검색 엔진 크롤러가 동작하지 못하여 검색 엔진에 영향을 주지 않게 할 수 있다.</p>
<p><a href="https://blog.hectodata.co.kr/crawling_vs_scraping/"><strong>*크롤링</strong></a>: 웹 크롤링이란 웹상의 정보들을 탐색하고 수집하는 작업</p>
<br>

<h3 id="sponsored"><code>sponsored</code></h3>
<p>연결된 URL이 광고 링크거나 유료 게재 링크(유료 링크)일 경우<code>rel=&quot;sponsored&quot;</code> 으로 표시한다. </p>
<p><a href="https://developers.google.com/search/docs/crawling-indexing/qualify-outbound-links?hl=ko#sponsored">구글</a>에서 2020년에 도입한 것으로, 이를 사용하여 검색 결과 랭킹에 해당 링크가 미치는 영향을 조절하고 사용자에게 보다 정확한 검색 결과를 제공할 수 있다.</p>
<br>

<h3 id="ugc"><code>ugc</code></h3>
<p>연결된 URL이 사용자 제작 콘텐츠(게시물, 댓글 등)일 경우 <code>rel=&quot;ugc&quot;</code> 로 표시한다.</p>
<p>이 또한 구글에서 2020년에 도입한 것으로 이를 통해 Google 검색 엔진이 링크를 보다 정확하게 해석하여 검색 엔진 최적화에 도움이 된다고 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Flex vs. Grid]]></title>
            <link>https://velog.io/@reina__/Flex-vs.-Grid</link>
            <guid>https://velog.io/@reina__/Flex-vs.-Grid</guid>
            <pubDate>Tue, 09 Jan 2024 21:09:11 GMT</pubDate>
            <description><![CDATA[<p>HTML 요소의 레이아웃을 정리하는 데 많이 사용되는 <code>flex</code>와 <code>grid</code> 이 둘의 차이를 알아보자.</p>
<br>

<hr>
<h3 id="flex와-grid의-가장-큰-차이는-무엇일까">flex와 grid의 가장 큰 차이는 무엇일까?</h3>
<p>바로 방향이다.</p>
<p><img src="https://velog.velcdn.com/images/reina__/post/dac7661c-4330-4962-89e1-f7635c94d0b7/image.png" alt=""></p>
<blockquote>
<p><code>flex</code> 는 1차원적인 <strong>1방향 레이아웃</strong> 시스템
<code>grid</code> 는 2차원적인 <strong>2방향 레이아웃</strong> 시스템</p>
</blockquote>
<p>flex 1차원으로 수평, 수직 영역 중 하나의 방향으로만 레이아웃을 구현할 수 있고, grid는 2차원으로 수평과 수직 레이아웃을 동시에 구현할 수 있다. 이로 인해 <code>flex</code>는 비교적 단순한 레이아웃을, <code>grid</code>는 비교적 복잡하고 정교한 레이아웃을 구현할 수 있다.</p>
<p>그렇다면 어느 상황에서 flex를, 어느 상황에서 grid를 사용하는지에 대해서도 알아보자.</p>
<br>

<hr>
<h2 id="flex">flex</h2>
<p><img src="https://velog.velcdn.com/images/reina__/post/97a9332c-660e-4fbe-881e-0235fc935ba2/image.png" alt=""></p>
<pre><code class="language-css">.container {
    display: flex;
    flex-direction: column;
    justify-content: space-evenly;
    align-items: center;
}

.text-container {
    display: flex;
    flex-direction: column;
}

.text-container .text {
      display: flex;
}

.text-container .text:nth-child(2) {
    display: flex;
    justify-content: flex-end;
}</code></pre>
<p>위의 이미지는 대충 이런 식으로 구현할 수 있을 것이다. (flex 관련 속성만 구현한 상태)</p>
<p>이처럼 웹 페이지 안의 각각의 콘텐츠를 정렬할 때 flex를 사용하는 것이 좋다. 예를 들어 상단의 메뉴바, 카테고리 메뉴, 카드 이미지와 상품 설명, ... 한 방향으로 이루어진 콘텐츠 요소들의 정렬은 grid보다 <code>flex</code> 를 사용하는 것이 더 적합하다.</p>
<p>➡️ <code>flex</code> 에 대한 더 자세한 설명이 궁금하다면? <a href="https://studiomeal.com/archives/197">1분 코딩</a></p>
<br>

<h2 id="grid">grid</h2>
<p><img src="https://velog.velcdn.com/images/reina__/post/e6fb646d-dff2-4024-99f0-1fba9fba0c98/image.png" alt=""></p>
<pre><code class="language-css">.container {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: 1fr 1.8fr 0.9fr;
    grid-template-areas: 
    &#39;ib ib ib&#39;
    &#39;tlb ic1 ic2&#39;
    &#39;tlb tbb tbb&#39;;
    gap: 20px;
}

.image-banner {
    grid-area: ib;
}

.text-left-banner {
     grid-area: tlb;
}

.text-bottom-banner {
      grid-area: tbb;
}

.image-card1 {
      grid-area: ic1;
}    

.image-card2 {
      grid-area: ic2;
}</code></pre>
<p>위의 이미지는 대충 이런 식으로 구현할 수 있을 것이다. (grid 관련 속성만 구현한 상태)</p>
<p>이처럼 웹 사이트의 전체적인 레이아웃 혹은 콘텐츠의 큰 틀을 구성할 때 <code>grid</code> 를 사용하는 것이 좋다. </p>
<p><code>flex</code> 또한 위와 같이 레이아웃을 구성할 수 있지만, 단방향 레이아웃 시스템이므로 각각의 섹션을 나누어 정렬해줘야 한다. 물론 섹션을 나눠서 웹 사이트의 큰 틀을 구성하는 것도 실제로 많이 사용되는 방법이지만, 전체적인 레이아웃을 파악하기엔 <code>grid</code>가 더 편하기 때문에 최근에는 grid를 통한 레이아웃 구현이 많아지는 추세다.</p>
<p>➡️ <code>grid</code> 에 대한 더 자세한 설명이 궁금하다면? <a href="https://studiomeal.com/archives/533">1분 코딩</a></p>
<br>

<hr>
<p>요즘 JavaScript 공부 때문에 HTML과 CSS에는 많이 신경을 못 쓰고 있었는데 오랜만에 다루니 새삼 또 재밌었고, 기능은 기억나는 데 사용법이 기억나지 않을 때는 역시 MDN 문서가 제일 좋은 것 같다.</p>
<p><a href="https://developer.mozilla.org/ko/docs/Web/CSS/flex">MDN - flex</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/grid">MDN - grid</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Responsive Web Design]]></title>
            <link>https://velog.io/@reina__/Responsive-Web-Design</link>
            <guid>https://velog.io/@reina__/Responsive-Web-Design</guid>
            <pubDate>Tue, 09 Jan 2024 11:16:46 GMT</pubDate>
            <description><![CDATA[<p>컴퓨터 그래픽스 디자인이라는 대학교 강의를 수강하며 피그마를 사용해 앱을 디자인하는 과제를 수행한 적이 있다. 이때 피그마의 &#39;오토 레이아웃&#39;이라는 기능을 알게 되었는데 정말 너무 좋더라... 🥲 </p>
<p>개발도 이렇게 쉽게 화면 크기에 따라 반응하도록 할 수 있으면 얼마나 좋을까 싶었고, HTML과 CSS를 처음 배울 시기의 나는 반응형 디자인 하면 미디어쿼리만 사용하려고 했는데 이 &#39;오토 레이아웃&#39;을 통해 <strong>반응형 웹의 상대길이</strong>에 대한 중요성을 깨달을 수 있었다.</p>
<p>그렇게 오늘은 반응형 웹 디자인을 위한 방법을 알아보려고 한다.</p>
<br>

<hr>
<h3 id="반응형-웹-디자인이-필요한-이유를-모르는-개발자는-없겠지">반응형 웹 디자인이 필요한 이유를 모르는 개발자는 없겠지?</h3>
<p><strong>반응형 웹 디자인(responsive web design, RWD)</strong> 이란 하나의 웹사이트에서 PC, 스마트폰, 태블릿 PC 등 접속하는 <strong>기기의 종류와 크기에 따라 사이트가 최적으로 보이고 작동</strong>하도록 만드는 데 초점을 맞춘 웹 개발 개념이다.</p>
<p>세상엔 정말 많은 전자기기가 존재하고, 그들의 크기는 너무 다양하다. 모든 사용자의 경험을 보장해줘야 할 개발자가 웹 브라우저 요소들의 크기를 절대 길이로 고정해놓는 무례한(?) 행동은 하지 않도록 하겠다.</p>
<p>앞서 말했던 것처럼 웹 개발을 처음 배울 때의 나는 이 반응형 웹 디자인을 위해서 미디어쿼리만 사용할 생각을 했는데,</p>
<br>

<h3 id="media">@media</h3>
<p>반응형 웹 디자인하면 자연스레 따라오는 미디어쿼리는 스크린 해상도 크기에 따라 CSS 스타일을 적용하도록 분기 처리해주는 모듈이다.</p>
<p>아래와 같이 <code>@media</code> 뒤에 <code>미디어 유형</code> 과 <code>미디어 특성</code> 으로 작성하면 된다. 미디어 유형과 미디어 특성에 대한 값들은 <a href="https://developer.mozilla.org/ko/docs/Web/CSS/CSS_media_queries/Using_media_queries">여기</a>를 참고하자. </p>
<pre><code class="language-css">/* Small devices (landscape phones, 576px and up) */
@media screen and (min-width: 576px) { ... }

/* Medium devices (tablets, 768px and up) */
@media screen and (min-width: 768px) { ... }

/* Large devices (desktops, 992px and up) */
@media screen and (min-width: 992px) { ... }

/* X-Large devices (large desktops, 1200px and up) */
@media screen and (min-width: 1200px) { ... }

/* XX-Large devices (larger desktops, 1400px and up) */
@media screen and (min-width: 1400px) { ... }</code></pre>
<p>예시는 화면 크기가 768px 이상 992px 이하일 때 body 요소의 폰트 크기는 14px로 설정되고, 992px 이상일 때는 16px로 설정된다.</p>
<pre><code class="language-css">@media screen and (min-width: 768px) {
  body {
    font-size: 14px;
  }
}

@media screen and (min-width: 992px) {
  body {
    font-size: 16px;
  }
}</code></pre>
<p>이런 미디어쿼리도 단점이 있는데,</p>
<p><strong>1. 로딩 시간</strong>
미디어쿼리는 브라우저의 렌더링 이후 동작하므로 초기 로딩 시간이 오래 걸릴 수 있어 사용자 경험을 저하시킬 수 있다.</p>
<p><strong>2. 성능 저하</strong>
미디어쿼리를 잘못 적용한 경우, 불필요한 스타일시트가 로드되거나 필요없는 DOM 요소가 생성될 수 있다.</p>
<p><strong>3. 유지보수</strong>
미디어쿼리를 상세하게 작성했다면, 점차 서비스해야 할 플랫폼이 늘어났을 때 이를 유지보수하기 어려울 수 있다.</p>
<p><strong>4. 브라우저 호환성</strong>
물론 소수겠지만, 일부 브라우저는 미디어쿼리를 지원하지 않을 수도 있다. 또한 미디어쿼리 문법 중 비교적 최근에 생성된 <code>range syntax</code> 의 경우 지원되지 않는 브라우저가 존재한다.</p>
<p>위와 같은 단점을 해결하기 위해 미디어쿼리를 최소화해서 사용하는 방법이 있다. 첫 번째는 바로 <strong>상대길이</strong>를 이용하는 것</p>
<br>

<h3 id="상대-길이">상대 길이</h3>
<p>상대 길이는 말 그대로 상대적인 길이이다. 부모 요소의 크기 변화에 따라 자식 요소의 크기도 맞게 변하는 것으로 모든 웹 브라우저의 최상위 부모는 브라우저이다. 결국 브라우저의 크기가 변경되면 그 하위 자식의 크기가, 또 그 하위 자식의 크기가, 또또 그 하위 자식의 크기, .... </p>
<p>상대 길이의 단위는 <code>em</code> <code>rem</code> <code>vw</code> <code>vh</code> 등이 있다.
<br></p>
<p><code>em</code></p>
<ul>
<li><p>부모의 font-size에 대한 상대길이 적용</p>
<ul>
<li>[부모] 1em(16px) → [자식] 0.5em (12px)</li>
<li>[부모] normal → [자식] 0.5em (10px)</li>
</ul>
</li>
<li><p>부모에 적용할 경우 기본값에 대한 상대길이 적용</p>
<ul>
<li>[부모] 2em (32px) → [자식] 0.5em (16px)</li>
</ul>
</li>
</ul>
<p><code>rem</code></p>
<ul>
<li>root의 font-size로, 페이지 전체에서 일관된 상대적인 크기를 가진다.<ul>
<li>root : 보통 HTML의 <code>font-size</code></li>
<li>부모 자식 상관없이 <code>1rem == 16px</code>, <code>2rem == 32px</code></li>
<li>부모를 찾아도 되지 않는다는 점에서 좀 더 용이<pre><code class="language-css">.parent {
color: cornflowerblue;
font-size: 2em;     // 32px
}
</code></pre>
</li>
</ul>
</li>
</ul>
<p>.child {
    color: indianred;
    font-size: 0.5rem;  // 8px
}</p>
<pre><code>
`vw`
    - 100vw : 뷰포트 가로의 100% 
    - 50vw : 뷰포트 가로의 50%

`vh`
     - 100vh : 뷰포트 세로의 100% 
     - 50vh : 뷰포트 세로의 50%
```css
.container {
    width: 50vw;
    hegith: 100vh;
}</code></pre><p><code>vmin</code>, <code>vmax</code>
    - 가로모드 (최대넓이)</p>
<pre><code class="language-css">.container {
    width: 100vmax;
    hegith: 100vmin;
}</code></pre>
<p><code>vmin</code>, <code>vmax</code>
    - 세로모드 (최대넓이)</p>
<pre><code class="language-css">.container {
    width: 100vmin;
    hegith: 100vmax;
}</code></pre>
<p>물론 이들은 부모 요소의 영향을 받기 때문에 사용할 때 주의가 필요하다. </p>
<p>상대길이를 통해 폰트 크기나, 화면의 넓이 등을 유연하게 바꿀 수 있는 방법에 대해 알아봤는데, 그렇다면 레이아웃을 미디어쿼리없이 유연하게 바꿀 수 있는 방법은 없을까?</p>
<br>

<h3 id="flex">flex</h3>
<p><code>display: flex;</code>를 통해 유연한 레이아웃을 생성할 수 있다.</p>
<pre><code class="language-css">.container {
    display: flex;
    flex-wrap: wrap;
}

.item {
    background-color: #ccc;
    padding: 10px;
    flex-basis: calc(50% - 10px);
    margin: 5px;
}</code></pre>
<p>이처럼 길이나 레이아웃을 미디어쿼리 없이 유연하게 변화시킬 수 있는 방법에 대해 알아봤다. </p>
<p>마지막으로 화면 크기 별로 색상이 바뀐다거나, 요소가 보이지 않는다거나 하는 경우는 미디어쿼리를 사용해야 하는데 이럴 때 미디어쿼리를 최소화해서 사용할 수 있는 방법에 대해 알아보자.</p>
<br>

<h3 id="미디어쿼리의-그룹화">미디어쿼리의 그룹화</h3>
<p>말 그대로 디바이스 크기별로 변해야 할 속성을 한 미디어쿼리 안에 작성해놓는 것이다. 여러 미디어쿼리를 하나로 그룹화하면 높은 가독성과 쉬운 유지보수를 기대할 수 있다. 중복 코드를 줄일 수 있고 변경이 필요한 경우 한 곳에서 수정할 수 있기 때문이다.</p>
<pre><code class="language-css">/* Small devices (landscape phones, 576px and up) */
@media screen and (min-width: 576px) { 
    .nav {
        display: none;
    }
    .body {
        background-color: #000000;
    }
}

/* Medium devices (tablets, 768px and up) */
@media screen and (min-width: 768px) {
    .body {
        background-color: #F2F2F2;
    }
}

/* Large devices (desktops, 992px and up) */
@media screen and (min-width: 992px) { 
    .body {
        background-color: #F4F4F4;
    }
}

/* X-Large devices (large desktops, 1200px and up) */
@media screen and (min-width: 1200px) { ... }

/* XX-Large devices (larger desktops, 1400px and up) */
@media screen and (min-width: 1400px) { ... }</code></pre>
<br>

<hr>
<p>이렇게 반응형 웹 디자인 구현하기 위한 미디어쿼리의 사용 방법과, 미디어쿼리를 최소화해서 사용하는 법에 대해 알아보았다. 앞으로의 개발도 파이팅이다 아자잣</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Animation]]></title>
            <link>https://velog.io/@reina__/Animation</link>
            <guid>https://velog.io/@reina__/Animation</guid>
            <pubDate>Tue, 09 Jan 2024 09:24:14 GMT</pubDate>
            <description><![CDATA[<p>페이지 스크롤링과 함께 애니메이션을 구현한 사이트를 보면 렉이 많이 걸려서 개발자들이 원하는 애니메이션 효과를 제대로 경험하지 못하는 것 같다는 느낌을 종종 받았다.</p>
<p>역동적인 느낌을 나 역시 좋아하기 때문에 이런 사이트를 볼 때마다 안타까움도 있었고, 해결할 방법이 없는 걸까? 라는 생각만 갖고 있었는데 드디어 대해 알아보게 되었다.</p>
<br>

<hr>
<h3 id="애니메이션이란-무엇인가">애니메이션이란 무엇인가?</h3>
<p>웹 페이지 내 요소들의 동작을 부드럽게 만들어주는 기능으로, 웹 페이지를 좀 더 생동감 있게 만들어준다. 애니메이션이 발생하는 CSS의 기능은 두 가지 정도 있는데, <code>transform</code>과 <code>animation</code>이 있다. 유저의 특정 액션이 트리거가 되어 전환을 발생시키는 <code>transform</code>과 달리, <code>animation</code>은 유저의 특정 액션없이 자동으로 진행된다.</p>
<p>이러한 애니메이션은 유저의 행동에 의해 움직이거나 변하는 등 간단한 인터렉션을 할 수 있지만, 많거나 복잡한 애니메이션을 적용하면 웹 페이지의 성능을 떨어뜨릴 수 있다</p>
<br>

<h3 id="성능은-왜-떨어지는-건데">성능은 왜 떨어지는 건데?</h3>
<p><strong>리플로우(reflow)와 리페인트(repaint)가 발생하기 때문이다.</strong></p>
<p>리플로우와 리페인트를 설명하기에 앞서, 우선 웹 브라우저의 UI 렌더링 과정은 아래와 같다.
<img src="https://velog.velcdn.com/images/reina__/post/be91bc27-36fd-4db2-af5b-627490aa471b/image.png" alt=""></p>
<ol>
<li><code>Styles</code> : 가장 먼저 객체에 적용할 스타일을 계산하거나 재계산한다.</li>
<li><code>Layout</code> : 요소의 레이아웃을 생성하고 위치를 설정한다.
&emsp;&emsp; → width, height, top, bottom, left, right 등</li>
<li><code>Paint</code> : Layout 단계를 통해서 생성된 각각의 레이아웃에 픽셀을 채운다.
&emsp;&emsp; → background, border, color 등</li>
<li><code>Composite</code> : 브라우저는 각각의 레이어 순서에 따라 화면에 객체를 그린다.
&emsp;&emsp; → transform, opacity</li>
</ol>
<blockquote>
<p><code>리플로우(reflow)</code> 란, 브라우저가 웹 페이지를 렌더링할 HTML 요소 노드의 추가 및 삭제, 요소의 크기 및 위치 변경, 윈도우 리사이징 등 <u>레이아웃에 영향</u>을 주는 변경이 발생했을 경우 레이아웃을 다시 계산하고 렌더링하는 과정이다. (<code>Layout → Paint → Composite</code>)</p>
<p><code>리페인트(repaint)</code> 는 재결합된 렌더트리를 기반으로 다시 렌더링하는 과정이다. (<code>Paint → Composite</code>)</p>
</blockquote>
<p>리플로우와 리페인트는 반드시 순차적으로 동시에 실행되진 않고, 레이아웃에 영향이 없는 변경은 리페인트만 실행된다. 이러한 <strong>리플로우, 리페인트</strong> 과정은 CPU의 자원을 많이 사용해 성능이 저하되므로 최적화를 위해 이 둘의 <strong>사용을 최소화</strong> 시켜야 한다.</p>
<br>

<p><strong>리플로우가 발생하는 속성 (참고)</strong> ▼
width, height, min-height / margin, padding / position / display, float / vertical-align / border, border-width / font-size, font-weight, font-family, text-align, line-height / overflow, overflow-y / top, bottom, left, right, clear / white-space / ...</p>
<p><strong>리페인트가 발생하는 속성 (참고)</strong> ▼
color border-style / visibility / background, background-image, background-position, background-repeat, background-size / outline, outline-color, outline-style, outline-width / border-radius / box-shadow / text-decoration / ...</p>
<br>

<hr>
<h3 id="이러한-애니메이션의-성능을-최적화하는-방법">이러한 애니메이션의 성능을 최적화하는 방법</h3>
<p>✔️ 리플로우를 발생시키는 속성 대신 <strong>transform 사용하기</strong> 
<code>top</code>, <code>left</code> 등의 속성을 통해 애니메이션 효과를 주는 경우와 <code>transform</code>의 <code>translate</code>를 통해 애니메이션 효과를 주는 경우로 나누어 비교할 수 있다.</p>
<p><code>top</code>, <code>left</code>, <code>bottom</code>, <code>right</code>과 같은 속성들로 애니메이션을 설정하면 <u>리플로우를 거쳐 브라우저를 다시 렌더링</u>을 하게 된다. 이와 달리, <code>transform</code> 속성을 이용해서 애니메이션을 설정하면 브라우저는 <u>Composite 단계</u>만 다시 거쳐서 렌더링을 하게 된다.</p>
<p>따라서, transform을 통해 애니메이션을 설정하면 다른 속성들과 비교했을 때 렌더링 단계를 최대한으로 줄일 수 있어 렌더링 부담이 줄어든다.</p>
<br>


<p>✔️ 2d 대신 <strong>3d transform 사용하기</strong> 
transform은 독자적으로 요소의 위치 및 확대, 축소, 회전이 가능한 css 요소이다. 이는 브라우저에서 GPU를 사용하므로 CPU의 부담을 덜어 성능 저하를 막아준다. </p>
<p>3d transform의 경우 x, y, z축으로 3차원 상에서 이동할 수 있기 때문에 2d transform보다 더 다양한 변환을 구현할 수 있고, 자연스러운 움직임을 구현할 수 있다.
예를 들어, 3d transform을 사용하면 객체를 회전시키거나 평면에 수직한 면에 글자를 새겨 넣는 등 다양한 변환을 구현할 수 있다. 또한 특정 객체가 다른 객체보다 더 앞쪽에 위치하도록 설정할 수 있어 더욱 다양한 시각적 효과를 구현할 수 있게 해주며, 더욱 부드러운 애니메이션을 구현할 수 있습니다.</p>
<br>

<p>✔️ <strong>will-change 사용하기</strong> 
will-change는 css의 속성으로, 미래에 값에 변화가 있을 것을 미리 알려줘서 최적화할 수 있도록 도와준다. 변화가 일어날 요소의 속성으로 넣어주면 되고, 값으로는 변화가 일어날 속성을 넣어주면 된다.</p>
<pre><code class="language-css">div {
    /* 키워드 값 */    
    will-change: auto;
    will-change: scroll-position;
    will-change: contents;
    will-change: transform;  /* Example of &lt;custom-ident&gt; */
    will-change: opacity;    /* Example of &lt;custom-ident&gt; */
    will-change: left, top;  /* Example of two &lt;animateable-feature&gt; */

    /* 전역 값 */
    will-change: inherit;
    will-change: initial;
    will-change: unset;
}</code></pre>
<p>MDN에서는 이 속성을 적당하게 사용할 것을 권장한다.</p>
<p>will-change는 성능 문제를 해결하기 위한 마지막 수단으로 계획된 것이기 때문에 페이지가 잘 작동한다면 추가하지 않는 것이 좋다. 또한, 브라우저는 최적화를 위해 가능한 모든 것을 시도하고 있으므로, will-change를 난무한다면 최적화하는 것에 과한 시간을 투자해 성능은 다시 저하될 수 있다.</p>
<br>

<hr>
<h3 id="참고">참고</h3>
<blockquote>
<ul>
<li><a href="https://coding-farmer.tistory.com/7">tistory :: will-change를 이용하여 웹사이트 성능 향상 시키기 (CSS)</a></li>
<li><a href="https://wit.nts-corp.com/2017/06/05/4571">wit blog :: CSS 애니메이션 성능 개선 방법 (reflow 최소화, will-change 사용)</a></li>
<li><a href="https://developer.mozilla.org/ko/docs/Web/CSS/will-change">MDN :: will-change</a></li>
</ul>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Font Preload]]></title>
            <link>https://velog.io/@reina__/Font-Preload-q43749bb</link>
            <guid>https://velog.io/@reina__/Font-Preload-q43749bb</guid>
            <pubDate>Thu, 30 Nov 2023 10:31:12 GMT</pubDate>
            <description><![CDATA[<p>웹 개발을 하다보면 빼 놓을 수 없는 요소 중 하나인 폰트에 대해 알아보자.</p>
<br>

<hr>
<h2 id="웹-폰트-vs-로컬-폰트">웹 폰트 vs 로컬 폰트</h2>
<p>폰트는 크게 웹 폰트와 로컬 폰트, 이 두 가지로 나눌 수 있다. </p>
<blockquote>
<p><strong>로컬 폰트</strong>
: 로컬 컴퓨터에 설치되어 있는 폰트</p>
</blockquote>
<blockquote>
<p><strong>로컬 폰트 적용 방법</strong>
<code>@font-face</code> 활용</p>
</blockquote>
<ul>
<li><code>&lt;a-remote-font-name&gt;</code>: 폰트명으로 지정될 이름</li>
<li><code>&lt;source&gt;</code>: 원격 폰트 파일의 위치를 나타내는 url 값을 지정하거나, 로컬 환경에 있는 폰트명을 <code>local(&quot;Font Name&quot;)</code> 형식으로 지정</li>
<li>만약 로컬 환경에 있는 폰트를 지정하려면 <code>src: local(&#39;Font Name&#39;)</code> 과 같은 형식으로 폰트 지정<pre><code>@font-face {
font-family: &lt;a-remote-font-name&gt;;
src: &lt;source&gt; [,&lt;source&gt;]*;
[font-weight: &lt;weight&gt;]; // font 굵기 값
[font-style: &lt;style&gt;]; // font 스타일 값
}</code></pre></li>
</ul>
<br>

<blockquote>
<p><strong>웹 폰트</strong>
: 로컬 폰트의 설치 여부와 상관없이 온라인의 특정 서버에 위치한 폰트 파일을 다운로드하여 화면에 표시해주는 웹 전용 폰트</p>
</blockquote>
<blockquote>
<p><strong>웹 폰트 적용 방법</strong>
대표적인 예시는 <strong>Google Font</strong>이다.</p>
</blockquote>
<p>① <code>&lt;link&gt;</code> 활용</p>
<pre><code>&lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot;&gt;
&lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin&gt;
&lt;link href=&quot;https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100&amp;family=Open+Sans:wght@400;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot;&gt;</code></pre><p>② <code>@import</code> 활용</p>
<pre><code>&lt;style&gt;
  @import url(&#39;https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100&amp;family=Open+Sans:wght@400;600;700&amp;display=swap&#39;);
&lt;/style&gt;</code></pre><p>이 둘은 로딩 속도에서 큰 차이를 보인다. 로컬 폰트는 이미 설치되어 있는 파일을 사용하기 때문에 속도가 빠르고, 웹 폰트는 새로 다운을 받아야 하기 때문에 로컬 폰트에 비해 느리다. 이로 해 웹 폰트를 사용하면 <strong>FOIT, FOUT 현상이 발생</strong>하기도 한다.</p>
<br>

<h3 id="foit-fout-현상">FOIT, FOUT 현상?</h3>
<blockquote>
<p><strong>FOIT</strong> (Flash Of Invisible Text)
: 브라우저가 폰트를 다운로드하기 전까지 <u>글자가 보이지 않는 것 </u>
&nbsp;&nbsp; ➜ 글자 자체가 보이지 않음</p>
</blockquote>
<blockquote>
<p><strong>FOUT</strong> (Flash Of Unstyled Text)
: 브라우저가 폰트를 다운로드하기 전까지 <u>폰트가 적용되지 않는 것</u>
&nbsp;&nbsp; ➜ 초기화된 폰트로 글자가 보임</p>
</blockquote>
<br>

<hr>
<p>그러나, <u>로컬 폰트</u>는 설치되어있지 않은 경우 디자인이 깨져 보일 수 있다는 치명적인 단점이 있다. </p>
<p>이로 인해 디자인이 깨질 염려는 없는 <u>웹 폰트</u>를 주로 사용하며, 느린 속도를 보완하기 위한 방법인 <strong>Preload</strong> 옵션을 활용한다.</p>
<h2 id="font-preload">Font Preload</h2>
<pre><code>&lt;link rel=&quot;preload&quot; href=&quot;./nanumGothic.woff2&quot; as=&quot;font&quot; type=&quot;font/woff2&quot; crossorigin=&quot;anonymous&quot;&gt;  </code></pre><p>위와 같이 <link>태그의 rel=&quot;preload&quot;을 사용하면 해당 리소스를 다른 리소스보다 빨리 로딩한다. 폰트 파일 이외에도 이미지 파일, 스크립트 파일, 비디오 파일 등 페이지에서 <u>중요도가 높은 자원을 의도적으로 먼저 로딩할 때 preload 옵션을 사용한다.</u></p>
<p>이는 미리 다운로드 해 놓음으로써, 사이트에 방문할 때마다 새로 렌더링하지 않아도 돼 속도를 향상시킬 수 있다.</p>
<p>그러나, preload 옵션으로 다운로드하는 리소스가 많아질수록 처음 렌더링 시간이 늦어진다는 문제가 있다. 그렇기 때문에 <strong>현재 페이지에서 중요도가 높고 먼저 렌더링되어야 하는 리소스만 preload 옵션으로 지정</strong>하는 것이 좋다.</p>
<p>더불어 이러한 preload 방식 말고도, 다양한 <u>웹 폰트 최적화</u> 방법을 사용해 웹 폰트의 용량과 텍스트가 보이지 않는 문제 등을 해결할 수 있다.</p>
<br>

<hr>
<h2 id="웹-폰트-최적화-방법">웹 폰트 최적화 방법</h2>
<h3 id="파일-용량-줄이기">파일 용량 줄이기</h3>
<blockquote>
<p><strong>1. 웹 폰트 형식 사용하기</strong>
아래와 같이 TTF/OTF, WOFF, WOFF2, SVG, EOT 형식이 있다. 브라우저 별로 지원하는 웹폰트가 다르니 확인 후 적용하면 된다.</p>
<p>WOFF과 WOFF2는 압축된 폰트 형식이다. 같은 계열에 속하는 WOFF 과 WOFF2 중, WOFF2가 30~50% 더 압축된 형식이다. </p>
<p>WOFF2는 IE 브라우저를 제외한 모든 브라우저에서 사용할 수 있는데, <del>IE 브라우저는 단종되었으니</del> 모든 브라우저에서 WOFF2 형식을 사용하도록 해서 폰트의 용량을 줄일 수 있다.
<br></p>
<p><img src="https://velog.velcdn.com/images/reina__/post/0aca8314-bd49-4791-9187-b045d4e47eba/image.png" alt=""></p>
<p>출처 : <a href="https://www.w3schools.com/cssref/css3_pr_font-face_rule.php">W3Schools</a></p>
</blockquote>
<blockquote>
<p><strong>2. 서브셋 폰트 사용하기</strong>
한글의 자음과 모음의 모든 경우를 조합하면 글자 수는 11,172자나 된다. 이로 인해 한글 폰트 파일은 영문 폰트 파일보다 용량이 크다.</p>
<p>그러나 갃, 갧, 냛, 춃, 뫭, ... 이런 조합들은 평소에 사용하지 않으니, 이런 글자들을 제거하고 <strong>사용할 글자만 남겨둔 폰트를 서브셋 폰트</strong>라고 한다. </p>
<p>최근에 출시되는 한글 웹 폰트의 대부분은 2,350자의 서브셋 폰트라고 한다.</p>
</blockquote>
<blockquote>
<p><strong>3. unicode-range 속성 사용하기</strong>
: 유니코드로 지정한 글자에만 웹 폰트를 적용하는 속성</p>
<p>등록된 글자가 텍스트에 없으면 웹 폰트 다운로드를 요청하지 않는다는 장점이 있다. 즉, 웹 폰트를 사용하지 않으면 불필요한 다운로드를 막을 수 있다.</p>
<pre><code>@font-face {
   font-family: NanumPenWeb;
   src: url(NanumPenWeb.woff2) format(&#39;woff2&#39;);
   unicodde-range: U+BC14, U+CC28;</code></pre><p>위 코드가 적용된 모습 ↓</p>
<p><img src="https://velog.velcdn.com/images/reina__/post/30c4dfca-3099-410a-b4ec-8aa472f9d4d1/image.png" alt=""></p>
<p>출처 : <a href="https://d2.naver.com/helloworld/4969726">Naver D2</a></p>
</blockquote>
<br>

<h3 id="폰트-항상-보이게-하기">폰트 항상 보이게 하기</h3>
<blockquote>
<p><strong>1. Font Face Observer 라이브러리 사용하기</strong>
: 웹 폰트의 로딩 상태를 추적할 수 있는 폰트 로더</p>
<p>파일 크기가 작고 실행 속도가 빠르다는 장점이 있다.</p>
<pre><code>/*CSS*/
// 로드 전
body {
   font-family: &#39;Apple SD Gothic Neo&#39;, sans-serif;
}
// 로드 후
body.font-loaded {
    font-family: &#39;Roboto&#39;, &#39;Apple SD Gothic Neo&#39;, sans-serif;
}</code></pre><p>CSS에 웹 폰트를 적용하지 않은 상태와 적용한 상태를 선언해 두고, 적용하지 않은 상태의 CSS가 먼저 적용되도록 한다.</p>
<pre><code>/*JS*/
// 사용할 웹 폰트 추적
var font = new FontFaceObserver(&#39;Roboto&#39;);
// 로드 후, 클래스 추가
font.load().then(funtion(){
   document.body.classList.add(&#39;fonts-loaded&#39;);
});</code></pre><p>JS에 사용할 웹 폰트의 이름을 파라미터로 하는 <strong>FontFaceObserver(웹 폰트의 로딩 상태를 추적하는) 객체</strong>를 생성한다. 그리고 load() 메서드를 사용해 웹 폰트의 로딩이 완료되면 CSS 클래스가 추가되도록 한다.</p>
<p>이렇게 설정하면 처음에는 폴백 폰트를 설정한 CSS가 적용된다. 그리고 웹 폰트의 로딩이 완료되면 웹 폰트를 설정한 CSS가 적용된다. 마치 <strong>FOUT 방식처럼 작동</strong>하는 것이다.</p>
<p>출처 : <a href="https://d2.naver.com/helloworld/4969726">Naver D2</a></p>
</blockquote>
<blockquote>
<p><strong>2. font-display 속성 사용하기</strong>
외부 라이브러리를 사용하지 않아도 웹 폰트의 로딩 상태에 따른 동작을 설정할 수 있다.</p>
<p>auto, block, swap, fallback, optional의 5가지 옵션이 있다. (자세한 설명은? <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display"><strong>MDN</strong></a>)</p>
<p>텍스트가 항상 보이게 하려면 FOUT와 동일하게 작동하는 <strong>swap 옵션</strong>을 사용한다. fallback 옵션과 optional 옵션을 사용하면 100ms 동안 텍스트가 보이지 않지만 매우 짧은 시간이어서 이 옵션들도 최적화에 사용할 수 있다.</p>
</blockquote>
<br>

<hr>
<h2 id="마치며">마치며</h2>
<p>font preload만 정리하려고 했던 글이 찾아볼수록 범위가 넓어져서 로컬 폰트와의 비교부터 preload 사용 방법, 그 외의 폰트 최적화 방법까지 정리하는 글이 되었다. 최적화 방법은 기재된 것 말고도 더 많은 방법이 있을 것으로 예상된다. 만약 알게 된다면 정리하기 위해 추가할 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[호환성 이슈와 크로스 브라우징]]></title>
            <link>https://velog.io/@reina__/%ED%98%B8%ED%99%98%EC%84%B1-%EC%9D%B4%EC%8A%88%EC%99%80-%ED%81%AC%EB%A1%9C%EC%8A%A4-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A7%95-2p6i6t43</link>
            <guid>https://velog.io/@reina__/%ED%98%B8%ED%99%98%EC%84%B1-%EC%9D%B4%EC%8A%88%EC%99%80-%ED%81%AC%EB%A1%9C%EC%8A%A4-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A7%95-2p6i6t43</guid>
            <pubDate>Thu, 30 Nov 2023 10:20:06 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/reina__/post/922f6ba9-a4ce-4c44-a57c-4da0afd43405/image.png" alt=""></p>
<p>웹을 개발하다보면 브라우저마다 기술이 구현되는 모습이 다르기 때문에 웹사이트가 브라우저마다 다르게 표시되는 문제가 생길 수 있고, 이를 <strong>호환성 이슈</strong>라고 한다.</p>
<p>오늘은 이러한 호환성 이슈를 해결하기 위한 방법인 크로스 브라우징과 safari에서 적용하는 방법에 대해 알아보기로 하자.</p>
<br>

<hr>
<p><img src="https://velog.velcdn.com/images/reina__/post/2e2eed6f-f6dc-4244-ba4a-e0a477e6bf6c/image.png" alt=""></p>
<h2 id="크로스-브라우징cross-browsing이란">크로스 브라우징(Cross Browsing)이란?</h2>
<p>서로 다른 브라우저에서 달리 <strong>구현되는 기술을 비슷하게 만듦</strong>과 동시에 어느 한쪽에 최적화되어 치우지지 않도록 <strong>공통 요소를 사용</strong>하여 웹페이지를 제작하는 기법</p>
<br>

<h3 id="어떻게-작업하면-돼">어떻게 작업하면 돼?</h3>
<blockquote>
<p><strong>1. MDN 활용</strong> \ <strong><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li">Click Here!</a></strong> 
하단의 Browser compatibility(브라우저 호환성)를 확인해보자
<img src="https://velog.velcdn.com/images/reina__/post/57654365-7f79-473a-a76b-e86a972710ad/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><strong>2. Can I Use 활용</strong> \ <strong><a href="https://caniuse.com/?search=color">Click Here!</a></strong>
<img src="https://velog.velcdn.com/images/reina__/post/3a5f60c8-2b6c-460e-b7ed-0dab82390e49/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><strong>3. 브라우저별 벤더 프리픽스 사용</strong> \ <strong><a href="https://caniuse.com/?search=color">Click Here!</a></strong></p>
</blockquote>
<ul>
<li><strong>벤더 프리픽스(Vendor Prefix)란?</strong><ul>
<li>주요 웹 브라우저 공급자가 새로운 실험적인 기능을 제공할 때 이전 버전의 웹 브라우저에 그 사실을 알려주기 위해 사용하는 접두사 
<img src="https://velog.velcdn.com/images/reina__/post/a45107fc-9545-4caf-b9c4-58d9d581d58c/image.png" alt=""></li>
</ul>
</li>
</ul>
<blockquote>
<p><strong>4. CSS 기본값 초기화 작업</strong></p>
</blockquote>
<ul>
<li><strong>Reset.css</strong><ul>
<li>HTML 요소에 내장된 고유 CSS 스타일 속성을 초기화 시켜서 브라우저 간의 차이를 최대한 없애 스타일이 0인 상태에서 디자인 진행<pre><code>/* reset.css */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: &#39;&#39;;
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}</code></pre></li>
</ul>
</li>
</ul>
<blockquote>
<p><strong>5. Metatag 활용</strong>
아래 코드를 활용하여 IE가 문서를 읽고 랜더링 할 때 원하는 모드로 랜더링
만약 content에 값이 &quot;IE=edge&quot;라면 브라우저가 할 수 있는 가장 최신의 모드로 랜더링</p>
</blockquote>
<pre><code>&lt;head&gt;
  // ...
  &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;
  //...
&lt;/head&gt;</code></pre><p>여기까지 크로스 브라우징에 대해 알아봤으니, safari 브라우저에 적용하는 방법에 대해 알아보자.
<br></p>
<hr>
<h2 id="safari에서-크로스-브라우징하는-방법">Safari에서 크로스 브라우징하는 방법</h2>
<p><a href="https://www.powermapper.com/products/sortsite/rules/bugsafari/">여길</a> 클릭하면 safari 브라우저에 다양한 호환성 이슈가 있다는 점을 알 수 있다. 이를 모두 기억하기엔 불가능하니, MDN을 최대한 활용하는 것이 좋다고 생각한다. </p>
<p>그렇다면, 많은 이슈 중 몇 개를 선택해 어떻게 해결할 수 있는지 확인해보자.</p>
<blockquote>
<p><strong>1. 높이 100% 맞추기</strong>
이전에는 <code>height = 100vh;</code> 를 통해 높이를 맞췄다는데, iOS safari에 하단바가 생기면서 이 부분이 정상적으로 작동하지 않아 아래처럼 <code>height = 100%;</code> 를 활용한다고 한다.</p>
</blockquote>
<pre><code>html, body {
    height = 100%;
}</code></pre><blockquote>
<p><strong>2. 호환성 검토하기</strong>
앞서 말한 방법처럼 MDN, Can I Use 등의 사이트를 참고해 호환성을 검토하자.
아래 사진처럼 같은 기능이어도 Safari 웹 브라우저와 모바일 브라우저에서 구현 가능한 범위와 버전이 다르므로 꼼꼼히 확인해야 한다.
<img src="https://velog.velcdn.com/images/reina__/post/cf7244c0-9aaa-40ad-afb7-b89f5e44f138/image.png" alt=""></p>
</blockquote>
<p><span style="color: gray">이외의 방법은 알게 되는대로 추가할 예정이다.</span></p>
<br>

<p>마지막으로, MAC이 없는데 <strong>Safari 환경을 테스트</strong> 해 보고 싶다면?</p>
<blockquote>
<p><strong><a href="https://appetize.io/">Appetize</a></strong> 라는 사이트에 접속하면 테스트 할 수 있다. 
무료 버전의 경우 60초 동안 가능하고, 개발자 도구는 사용할 수 없다고 하니 참고하자...</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[제로베이스 한 달 회고]]></title>
            <link>https://velog.io/@reina__/%EC%A0%9C%EB%A1%9C%EB%B2%A0%EC%9D%B4%EC%8A%A4-%ED%95%9C-%EB%8B%AC-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@reina__/%EC%A0%9C%EB%A1%9C%EB%B2%A0%EC%9D%B4%EC%8A%A4-%ED%95%9C-%EB%8B%AC-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Thu, 30 Nov 2023 10:14:32 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/reina__/post/e5b60ba0-7220-4104-8280-67c89acc336f/image.png" alt=""></p>
<p>어라... 부트캠프와 학교와 아르바이트를 병행하니까 시간이 신기루 같다 요즘 정말 너무 바빠서 이렇게 살아야 하나 싶은 생각이 한두 번 들면서 번아웃이 올랑말랑 했는데 희한하게 오지는 않았다 <del>(나름 강해졌나,,,)</del></p>
<p>매일 오전마다 하는 데일리 스크럼을 할 때마다 HTML/CSS 강의 총 정리본을 제작해 놓은 걸 자주 애용하는데, 자바스크립트도 그렇게 한 묶음 묶어놔야겠다고 생각했다. 물론 총 정리본을 그렇게 자주 보는 건 아니지만 정리하면서 내용이 다시 한 번 머리에 들어오고, 스크럼할 때 찾아보면서 다시 한 번 들어오고, ... 반복되면서 점점 그냥 상식처럼 머리에 남게 되는 것 같다. 종강하면 자바스크립트 총 정리본도 만들어 봐야겠다. </p>
<p><strong>파이팅 👊🏻</strong></p>
<br>

<hr>
<h2 id="11월-초에-어떤-허무맹랑한-소리를-했더라">11월 초에 어떤 허무맹랑한 소리를 했더라...</h2>
<blockquote>
<p>부지런히 공부해서 6개월 동안 부트캠프를 완주하는 것이다.</p>
</blockquote>
<p>나름 허무맹랑하지는 않을지도... 정말 부지런히 사는 요즘이기 때문인가 누워서 잘 수 있는 시간이 4~6시간 정도인 요즘 잠이 부족해서 대중교통에서도 자야겠다 싶은데 부트캠프와 학교 공부를 병행하려면 지하철에서 잘 수가 없다(지만 나도 모르게 자는 중) </p>
<p>CS 이론은 실무적으로 해볼 게 많지 않아서 이동 중에 보기 좋아서 주로 CS 이론 강의를 많이 보고, 강의가 끝나면 블로그 글이나 이동하면서 작성해야겠다고 생각했다. 최대한 집에서는 코드 구현에 시간을 더 많이 쏟기 위해 어떻게든 노력해보는 중이다 종강 얼른 와...</p>
<p>슬슬 코딩 테스트도 시작하고 있는데 모던 자바스크립트 Deep Dive를 공부하고 코딩 테스트를 하니까 뭔가 메소드 사용법을 더 확실히 익힐 수 있는 느낌이다 종강하면 슬슬 다른 코딩 테스트들도 연습을 해야겠다는 생각이 들었다. 종강 얼른 와...... 2</p>
<p>하여튼 아직 나의 목표는 건재하다 <strong>번아웃없이 부트캠프를 완주하자! 아자자</strong> </p>
<br>

<hr>
<h2 id="아직-5개월-남았다">아직 5개월 남았다!</h2>
<p>블로그를 작성하면서 들은 생각인데 대중교통 중에 자바스크립트 강의를 들어도 될 것 같다. 사실 강의를 들으면서 코드를 따라 입력하면 머리에 잘 안 들어오는 느낌인데 차라리 강의를 후다닥 끝내고 남는 시간은 코딩 테스트를 하며 몸에 익히는 게 더 좋을지도?</p>
<p>요즘 내 인스타 피드엔 JS와 CSS 관련된 게시글이 많이 뜨는데 그런 거 볼 때마 얼른 토이 프로젝트로 여러 개 만들어보고 싶고, 뭔가 빨리 취업해서 실무에서 경험할 수 있는 다양한 문제 상황을 해결해보고 싶다. 어려운 문제를 고민하고 해결해 냈을 때만큼 성취감을 느낄 수 있는 일은 없다고 생각하기 때문에 성취감을 느끼고 싶은 건가 싶기도 하다.... (?)</p>
<p>그래서 지금 나는 하고 싶은 게 너무너무너무 많지만 조급해하지 않고 천천히 나아가고자 한다. 하지만 조급해지는 마음을 잠재우기란 쉽지 않으니 이걸 어떻게 잠재울지도 고민해봐야 할 것 같다</p>
<p>글이 왜 이렇게 엉망진창이지 싶을 수도 있지만 지금 내 머릿속이 엉망진창이라 그렇다 🫨 🫥 🫠 ☠️ 😵‍💫 👻 😵</p>
<br>

<p>여하간 결론은 <strong>부지런히 익히자 익숙해지면 뭔들 괜찮으니까 자주 접하고 여러 번 생각하고 많이 시도하자 아자베이스!</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTML/CSS 미션을 끝마쳤다!]]></title>
            <link>https://velog.io/@reina__/HTMLCSS-%EB%AF%B8%EC%85%98%EC%9D%84-%EB%81%9D%EB%A7%88%EC%B3%A4%EB%8B%A4</link>
            <guid>https://velog.io/@reina__/HTMLCSS-%EB%AF%B8%EC%85%98%EC%9D%84-%EB%81%9D%EB%A7%88%EC%B3%A4%EB%8B%A4</guid>
            <pubDate>Mon, 27 Nov 2023 20:32:15 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/reina__/post/df764b50-9eec-442f-a626-4978d1639dc2/image.png" alt="">
할 일이 너무 많아서 일단 미션부터 해보면서 강의 내용을 복기해보자라는 마음에서 남들보다 빨리 진행하게 되었고, 빨리 마치게 되었다. (마감은 12월 13일이다)
<br></p>
<hr>
<h2 id="결론부터-말하자면-이정도면-괜찮다-라고-느꼈다">결론부터 말하자면 이정도면 괜찮다! 라고 느꼈다.</h2>
<p>사실 부트캠프를 시작하고 강의만 들을 땐 개념 위주의 수업이기도 하고, 테스트용으로 간단하게 코딩해서 꽤나 쉽다고 느껴졌다. </p>
<p>그러나 미션을 진행하면서 HTML 문서를 작성해 나갈 때 <code>&lt;div&gt;</code> 의 범위는 어디서부터 어디인 걸까, 여기엔 <code>&lt;p&gt;</code> 와 <code>&lt;span&gt;</code> 중 무엇을 적지? 하는 점과 클래스 이름은 어떻게 설정하는 것이 좋을까, ... (<del>그 외에도 너무 많은 고민이 존재하지만</del>) 하는 고민이 여럿 있었다. 미션은 강의와 달리 실무에서 실제로 사용되는 기능들을 요구했기 때문에 <code>지식 + a</code> 가 필요했기에 이 과정에서 굉장히 다양한 걸 배우고, 몸에 익히게 되었다. <strong>확실히 무언갈 직접 찾아보고 깨닫는 것만큼 몸에 익히기 좋은 공부 방법은 없다고 생각한다.</strong>
<br> </p>
<p>다양한 파비콘의 설정 방법, aria-hidden, role, ... 웹 페이지 하나를 만들 때 사용자의 접근성을 위해 다양한 기능들이 필요하다는 것도 알게 되었다. 이는 사실 강의로만 들어서는 접근성에 대해 잘 와 닿지 않아서 못 느꼈던 점들인데 미션을 통해 가장 크게 느끼고, 중요성을 깨달을 수 있게 된 점이라 좋은 경험으로 느껴졌다.</p>
<p>미션을 진행할 때 전체적인 문서를 아무런 도움없이 만드는 게 처음이다보니 정말 오랜 시간들이 걸렸다. MDN 문서의 사용도 익숙치 않았고, 그 외의 추가적인 사용 방법이 궁금할 땐 구글링을 해 보면서 다양한 예시를 참고해야 했기 때문이다. 그러나 미션을 진행할수록 코딩에 익숙해지며 반복되는 기능들을 입력하는 데는 점점 시간이 줄어들면서 <strong>실력과 지식이 늘어나는 게 느껴져 기분이 좋았다.</strong>
<br></p>
<p>나는 제로베이스 강의 중에선 HTML/CSS 장인의 핵심정리 &amp; 프로젝트가 가장 도움된다고 느꼈다. 나머지 강의도 물론 좋지만, 이론을 진행하고 간단한 실습 느낌이기 때문에 실질적으로 사용할 때 많이 까먹기도 하고, 다른 것들과 같이 사용할 때는 코드가 마음처럼 동작하지 않을 때도 많았다. 그러나 이 강의는 클론 코딩임에도 불구하고 다른 사이트의 코드를 읽는 법이나 코드들을 엮어서 어떻게 구현하는지 등의 감을 익히기에 굉장히 좋은 강의였다. 강의가 추가된다면 이런 <strong>실습 형식의 강의가 추가된다면 더 좋을 것 같다</strong>고 느꼈다.</p>
<br>

<hr>
<h2 id="htmlcss를-공부하면서-무엇이-어려웠을까">HTML/CSS를 공부하면서 무엇이 어려웠을까?</h2>
<p>앞서 말했다 싶이 HTML 문서를 작성할 때는 <code>&lt;div&gt;</code> 의 범위나, <code>&lt;p&gt;</code> 와 <code>&lt;span&gt;</code> 의 구분이 살짝 헷갈렸고, 그 외에 <code>&lt;figure&gt;</code> 의 사용 등 강의로는 다 배운 개념이지만 실제로 적용하려니 막상 <code>&lt;div&gt; 지옥</code> 을 나도 모르게 만들고 있는 모습을 발견했다. 또한 레이아웃을 구성하는 것만큼 시간을 오래 소모한 부분은 <code>클래스 이름</code> 을 설정하는 것이었다. </p>
<p>이는 아무래도 HTML 구조를 작성하는 것 자체가 어색해서인 것 같은 게 <code>&lt;div&gt;</code> 의 범위나 <code>클래스 이름</code> 등은 미션의 마지막에 다다를수록 점점 익숙해지는 게 느껴졌기 때문이다. 다른 HTML 요소들도 사용하다보면 점점 익숙해질 테니 <strong>많이 연습해보기로 다시 한 번 다짐했다!</strong>
<br></p>
<p>CSS는 사실 HTML 구조만 잘 잡아놓는다면 생각보다 어렵게 동작하는 건 아니라고 느꼈다. 그만큼 CSS는 의외로 금방 완성했기 때문이다. 원체 꾸미는 걸 좋아해서 그런지 <strong>CSS를 진행할 때는 오히려 힐링된다</strong> 느꼈다. (?) 구조가 맞아지고 점점 <strong>예쁘게 변해가는 문서들이 좋았다.</strong>
<br></p>
<p>아 이외에 미션을 진행하면서 신기했던 점과 어려웠던 점도 몇 가지 있다.</p>
<p>신기했던 점은 현재 학교에서 &#39;컴퓨터 그래픽스 디자인&#39;이라는 과목을 수강하는데 이 수업에서 모바일 앱을 디자인해야 해서 <strong>피그마를</strong> 사용하고 있는데 이 덕분에 미션할 때 익숙하게 다룰 수 있었고, <strong>정말 실무에서 많이 사용하고 있다는 것을 느꼈다.</strong></p>
<p>어려웠던 점은 미션 4와 5는 미리 작성된 JavaScript와 HTML 문서가 연결되어 있어 이에 맞게 HTML 구조를 작성해야 했던 점이 조금 어려웠다. 미션 4는 그래도 JavaScript 코드가 짧아서 어떻게 동작하는지 파악하고 이에 맞게 해결을 금방했는데, 미션 5는 JavaScript 파일들이 많고 길어서 HTML 구조를 하나씩 수정해가며 스크립트를 파악해 나가는 게 오래 걸렸다. 이를 통해 <strong>중첩되는 <code>&lt;ul&gt;</code> 의 작성 방법을 평생 잊지 않을 수 있게 되었다 ㅎㅎ......</strong></p>
<br>

<hr>
<h2 id="이들은-어떻게-공부하는-것이-좋을까">이들은 어떻게 공부하는 것이 좋을까</h2>
<p>일단 HTML의 전체적인 요소와 CSS의 속성을 알기 위해 유튜브나 부트캠프 등의 이론 강의를 한 번 돌려 보면서 감을 익히는 게 좋다고 느꼈다. MDN 사용은 이후인 것 같다. 이번 미션을 통해 MDN 문서를 정말 많이 열어봤지만, 무슨 요소가 있는지도 없는 상태에서 문서를 찾아보기엔 쉽지 않다고 생각하기 때문이다.</p>
<p>강의를 통해 요소들에 대해 익혔다면 이 다음은 클론 코딩을 바로 시작하는 게 좋을 것 같다. 아무래도 이론만 들을 때는 정말 뭐든 쉽고 뭐든 익숙해지는 것 같지만 실제로 하나의 클론 코딩만 진행해봐도 이렇게 멘붕이 올 수가 없다. 클론 코딩도 우선적으로 코드를 어느 정도 작성한 후 막히는 부분이 생겼을 때 사이트의 코드를 보는 것을 추천한다. <strong>나와는 아예 다르게 작성된 코드</strong>를 구경할 수도 있고, <strong>나와 완전 비슷하게 작성된 코드</strong>도 구경할 수 있어 정말 색다른 경험이 될 것이다.</p>
<p>미션을 진행할 때 이렇게 하는 게 맞을까? 하는 확신이 없어 굉장히 망설여지는 점들이 많았다. 그러나 한 강의에서 <strong>&#39;모든 사람의 코드가 정답은 아니며, 내가 작성한 코드도 정답이 될 수 있다.&#39;</strong> 라는 말에 굉장히 힘을 얻고, 자신감을 얻을 수 있었고 코딩을 일단은 할 수 있게 되었다. 이 점은 내 실력을 늘리기에 충분한 발단이 되었고, <strong>코딩을 익히고 싶다면 일단 해 보는 것이 가장 중요하다</strong>고 느꼈다.</p>
<blockquote>
<p>잊지 말자 코딩에 정답은 없다. 실력을 늘리고 싶다면 일단 시작하자!</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Web Standards]]></title>
            <link>https://velog.io/@reina__/Web-Standards</link>
            <guid>https://velog.io/@reina__/Web-Standards</guid>
            <pubDate>Thu, 16 Nov 2023 02:40:50 GMT</pubDate>
            <description><![CDATA[<h2 id="웹-표준">웹 표준</h2>
<blockquote>
<p>: 브라우저 종류 및 버전에 따른 기능 차이에 대하여 호환이 가능하도록 제시된 표준</p>
</blockquote>
<ul>
<li>다른 기종 혹은 플랫폼에 따라 달리 구현되는 기술을 동일하게 구현함과 동시에 어느 한쪽에 최적화되어 치우치지 않도록 공통요소를 사용하여 웹 페이지를 제작하는 기법을 의미</li>
</ul>
<p><img src="https://velog.velcdn.com/images/reina__/post/4b807402-ee45-49b7-a81a-6a27166dca41/image.png" alt=""></p>
<br>

<hr>
<h3 id="웹-표준의-목적">웹 표준의 목적</h3>
<blockquote>
<p>: 웹사이트에 접속한 사용자가 어떠한 운영체제나 브라우저를 사용하더라도 동일한 결과를 보이게 함</p>
</blockquote>
<ul>
<li>브라우저의 종류나 버전에 상관없이 모든 사용자들이 동일한 웹사이트를 볼 수 있도록 웹 표준기술 작업이 필요하며 웹 표준을 준수하는 것은 웹 접근성 준수를 위한 핵심</li>
</ul>
<br>

<hr>
<h3 id="웹-표준의-장점">웹 표준의 장점</h3>
<ul>
<li><strong>수정 및 운영 관리 용이</strong>
  : 콘텐츠의 올바른 구조화와 CSS로 시각표현을 통일하여 제어하게 되어 페이지 제작의 부담 감소 및 관리용이  <br></li>
<li><strong>접근성 향상</strong>
  : 웹 표준을 이용해 작성한 문서는 다양한 브라우징 환경에 대응이 가능하며 다양한 기기에서의 정상적인 작동 및 
  &nbsp; 장애인 지원용 프로그램에도 도움이 되므로 사용자나 접속 장치의 접근성이 용이  <br></li>
<li><strong>검색엔진 최적화 (SEO)</strong>
  : 구조화된 웹페이지는 검색 로봇 수집을 통해 검색엔진에 효율적으로 노출 될 수 있도록 검색엔진의 검색결과를 최적화  <br></li>
<li><strong>File Size 축소 및 서버 저장 공간 절약</strong>
  : 효율적인 소스 작성은 파일 사이즈와 서버공간을 절약할 수 있으며 동시에 화면표시에 소요되는 시간을 단축  <br></li>
<li><strong>효율적인 마크업</strong>
  : CSS와 HTML문서를 분리하여 제작할 경우 불필요한 마크업이 최소화되어 페이지 로딩속도 향상  <br></li>
<li><strong>호환성 가능</strong>
  : 기존 IE브라우저에서만 작동이 가능했던 요소들이 웹 표준을 준수함으로써 다양한 브라우저(크롬, 파이어폭스, 
  &nbsp; 사파리, 오페라 등)에서도 작동</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTML5 Semantic Tag]]></title>
            <link>https://velog.io/@reina__/HTML5-Semantic-Tag-w4rsb38g</link>
            <guid>https://velog.io/@reina__/HTML5-Semantic-Tag-w4rsb38g</guid>
            <pubDate>Thu, 16 Nov 2023 01:58:41 GMT</pubDate>
            <description><![CDATA[<h2 id="semantic-tag-≈-semantic-web">Semantic Tag? (≈ Semantic Web)</h2>
<h3 id="semantic--의미의-의미론적인-">Semantic [ 의미의, 의미론적인 ]</h3>
<blockquote>
<p>HTML5 에서 등장한 개념으로 의미를 갖고있는 요소를 뜻함
    → 요소의 의미를 고려하여, 구조를 설계하고 코드를 작성해야 함</p>
</blockquote>
<ul>
<li><code>&lt;div&gt;</code>와 <code>&lt;span&gt;</code>은 <strong>시맨틱 태그 (X)</strong>
  <code>&lt;h1&gt;</code>, <code>&lt;img&gt;</code>, <code>&lt;table&gt;</code>, <code>&lt;form&gt;</code>은 <strong>시맨틱 태그 (O)</strong></li>
</ul>
<p><img src="https://velog.velcdn.com/images/reina__/post/924743e9-a7ef-4867-a070-b945294fbc8d/image.png" alt=""></p>
<br>


<hr>
<h3 id="semantic-tag를-사용하는-목적">Semantic tag를 사용하는 목적</h3>
<blockquote>
<p>코드를 보는 개발자에게 명확하게 해당 요소의 의미와 목적을 전달하기 위함
    - 검색 엔진 최적화, 접근성 등에 이점</p>
</blockquote>
<ul>
<li>문법적으로 ‘반드시 이렇게 해야 동작한다’는 규칙은 없으니 Semantic tag의 의미를 이해하고, 각자 다양한 형태로 사용</li>
</ul>
<br>

<hr>
<h3 id="의미론적인-마크업의-사용-시-이점">의미론적인 마크업의 사용 시 이점</h3>
<ul>
<li>검색 엔진이 의미론적 마크업을 분석하여 페이지의 <strong>검색 랭킹에 영향을 줄 수 있는 중요한 키워드</strong>로 간주</li>
<li>시각 장애가 있는 사용자가 스크린리더로 페이지를 탐색할 때 <strong>의미론적 마크업을 푯말</strong>로 사용</li>
<li>의미가 없는 끊임없는 <strong><code>&lt;div&gt;</code></strong> 들을 탐색하는 것보다, <strong>의미있는 코드 블록</strong>을 찾는 게 훨씬 쉬움</li>
<li>개발자에게 태그 안에 채워질 데이터 유형을 제안</li>
<li>의미 있는 이름짓기는 적절한 사용자 정의(구성) 요소의 이름짓기를 반영</li>
</ul>
<p><img src="https://velog.velcdn.com/images/reina__/post/bb16e76b-176a-4e21-b2b5-34a63b4bc361/image.png" alt=""></p>
<br>

<hr>
<h3 id="semantic-tag의-구성">Semantic Tag의 구성</h3>
<ul>
<li><strong><code>&lt;header&gt;</code></strong> : 소개, 제목, 로고, ...</li>
<li><strong><code>&lt;nav&gt;</code></strong> : 네비게이션 영역. 링크, 메뉴, ...</li>
<li><strong><code>&lt;main&gt;</code></strong> : 메인 컨텐츠 영역. 전체 문서에서 단 하나<ul>
<li><strong><code>&lt;section&gt;</code></strong> : 일반적인 컨텐츠 영역. 여러개 가능</li>
<li><strong><code>&lt;article&gt;</code></strong> : 독립적인 컨텐츠를 구분</li>
<li><em><code>&lt;figure&gt;</code>*</em> : 비디오, 이미지, 코드 영역</li>
</ul>
</li>
<li><strong><code>&lt;aside&gt;</code></strong> : 메인 컨텐츠 이외의 사이드 컨텐츠. 별개 정보, 연관 정보</li>
<li><strong><code>&lt;footer&gt;</code></strong> : 저작권, 계약 정보, 사이트맵, 연락처, ...</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[함께 일하고 싶은 회사]]></title>
            <link>https://velog.io/@reina__/%ED%95%A8%EA%BB%98-%EC%9D%BC%ED%95%98%EA%B3%A0-%EC%8B%B6%EC%9D%80-%ED%9A%8C%EC%82%AC-ilzw0gdd</link>
            <guid>https://velog.io/@reina__/%ED%95%A8%EA%BB%98-%EC%9D%BC%ED%95%98%EA%B3%A0-%EC%8B%B6%EC%9D%80-%ED%9A%8C%EC%82%AC-ilzw0gdd</guid>
            <pubDate>Thu, 16 Nov 2023 01:47:23 GMT</pubDate>
            <description><![CDATA[<h2 id="회사를-선택하는-기준">회사를 선택하는 기준</h2>
<blockquote>
<p>딱 세 가지인 것 같다. 
<strong>복지, 자기계발, 분위기</strong>.........., <del>급여</del> </p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/reina__/post/f92904b8-f5d8-43ad-bdeb-541f16b1a7fa/image.png" alt=""></p>
<p>회사에서 오래 일할 수 있는 <strong>원동력</strong>이라고 생각한다. </p>
<p>복지의 종류는 다양하지만 <strong>나에게 좋은 영향이 있는 복지</strong> 또한 도움이 된다고 생각한다. 그리고 업무를 하면서 <strong>개발자로서의 역량</strong>도 키울 수 있었으면 좋겠다. 성장을 원하는 사람이기 때문에 성장없는 삶은 나를 지치게 만들 때도 있기 때문이다. 마지막으로 <strong>조직 내 분위기</strong>가 좋다면 업무가 아무리 힘들어도 조직원들과 얘기하며 스트레스를 해소하는 등 일을 유지할 수 있게 해준다. (+ 배울점 많은 사수가 있다면 더할 나위 없을 것 같다.)</p>
<br>

<hr>
<h2 id="가고-싶은-회사">가고 싶은 회사?</h2>
<blockquote>
<p>기업의 크기와 상관없이 일할 때만큼에 있어서는 열정적이고 <strong>다같이 모였을 때 더 시너지를 발산할 수 있는 조직</strong>에서 일하고 싶다.</p>
</blockquote>
<p>아직 나는 어디에 취업하고 싶다!를 확정한 곳은 없다. 마음 속에 담아둔 곳이 몇 곳 있기는 하지만 아직은 기업 정보를 모으는 중이다. 그럼에도 내가 제일 가고 싶은 회사는 일에 대해서 열정이 많은 사람들이 모여 있는 조직에 가고 싶다. 조직은 잘하는 사람 혼자서 이끌 수 있는 곳이 아니기 때문이다. 책임감 있는 사람 여럿이 모여 일했을 때 자기계발에도 도움이 되고 업무의 효율적인 측면에서도 가장 큰 시너지를 발생시킬 수 있기 때문에 다같이 으쌰으쌰 할 수 있는 분위기에서 일하고 싶다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트엔드와 백엔드의 차이점]]></title>
            <link>https://velog.io/@reina__/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C%EC%99%80-%EB%B0%B1%EC%97%94%EB%93%9C%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90</link>
            <guid>https://velog.io/@reina__/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C%EC%99%80-%EB%B0%B1%EC%97%94%EB%93%9C%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90</guid>
            <pubDate>Tue, 14 Nov 2023 04:41:39 GMT</pubDate>
            <description><![CDATA[<h1 id="프론트엔드와-백엔드">프론트엔드와 백엔드</h1>
<blockquote>
<p>둘의 가장 큰 차이점은 <strong>사용자와의 거리</strong>와 <strong>사용하는 언어</strong>라고 생각한다. </p>
</blockquote>
<p>프론트엔드는 <strong>사용자가 보는 영역</strong>인 웹 사이트에 나타나는 레이아웃, 이미지, 텍스트, 버튼 등의 모든 요소를 개발하는 기술이고, 백엔드는 웹 애플리케이션의 <strong>사용자가 보지 못하는 영역</strong>인 서버나 데이터베이스를 관리하는 기술이다.</p>
<p>또한 프론트엔드는 HTML, CSS, JavaScript, 등을 사용하고 백엔드는 PHP, Java, python 등의 다양한 프로그래밍 언어를 사용한다.</p>
<br>

<hr>
<h2 id="내가-생각하는-프론트엔드-개발자">내가 생각하는 프론트엔드 개발자</h2>
<blockquote>
<p><strong>사용자 인터페이스(UI)</strong>와 <strong>사용자 경험(UX)</strong>에 초점을 맞춰 개발하는 직업이라고 생각한다. </p>
</blockquote>
<p>보기 좋은 떡이 맛도 있다는 말이 있다. 나는 프론트엔드 개발자가 보기 좋은 떡을 만드는 사람이라고 생각한다. 보기 좋으면 맛도 있을 거란 기대감에 사용자의 관심을 한 번은 더 끌 수 있기 때문이라고 생각한다. 그러나 보기에만 좋고 맛이 없는 떡은 오래 가지 못 한다. 그렇기 때문에 맛있고 보기 좋은 떡을 만들어야 한다. </p>
<p>이처럼 프론트엔드 개발자들은 <strong>깔끔하고 사용자들에게 편안한 서비스를 제공</strong>할 수 있는 웹 사이트 혹은 애플리케이션을 개발해야 한다고 생각한다.</p>
<br>

<hr>
<h3 id="그렇다면-프론트엔드-개발자에게-필요한-역량은-무엇일까">그렇다면 프론트엔드 개발자에게 필요한 역량은 무엇일까?</h3>
<blockquote>
<p><strong>문제 해결 능력</strong>, <strong>협업 능력</strong>, <strong>꾸준함</strong>, <strong>성실함</strong>, <strong>이해력</strong>, <strong>트렌디</strong>, ..... </p>
</blockquote>
<p>사용자의 니즈를 충족시키기 위해 필요한 문제 해결 능력과, 백엔드 개발자 디자이너, 기획자 모두와 소통해야 하는 역할로서의 협업 능력, 코드를 구현하는 중에 막다른 길에 다다라도 포기하지 않을 꾸준함과 성실함, 웹과 모바일 환경의 프로세스에 대한 전반적인 이해와 요구 사항을 제대로 이해할 수 있는 이해력. 마지막으로 쉴새 없이 바뀌는 트렌드를 적응할 수 있는 능력까지 정말 <strong>다재다능</strong> 그 자체여야겠다! (?)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트엔드 개발자에 도전해보자!]]></title>
            <link>https://velog.io/@reina__/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%97%90-%EB%8F%84%EC%A0%84%ED%95%B4%EB%B3%B4%EC%9E%90-3wyfr7c9</link>
            <guid>https://velog.io/@reina__/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%97%90-%EB%8F%84%EC%A0%84%ED%95%B4%EB%B3%B4%EC%9E%90-3wyfr7c9</guid>
            <pubDate>Fri, 10 Nov 2023 09:52:39 GMT</pubDate>
            <description><![CDATA[<h2 id="나는-왜-프론트엔드를">나는 왜 프론트엔드를?</h2>
<p>불씨는 그저 &#39;예쁜 웹 페이지가 좋다&#39;라는 마음에서 생긴 <strong>웹 디자이너에 대한 관심</strong>이다. </p>
<p>예쁘고 깔끔한 UI의 웹 페이지나 앱을 봤을 때 더 사용하고 싶고, 어딘가를 더 보완했으면 좋겠다는 생각을 자주 하곤 했다. 그러다 2학년 1학기 때 웹 프로그래밍이란 과목을 듣게 되었는데 사실 HTML, CSS, JavaScript를 사용한 건 아니었고 JAVA를 주로 이용해 데이터 위주의 프로그래밍이었고 JS와 HTML는 살짝 곁들인 수준이었다. 그럼에도 불구하고 웹 페이지에 내가 작성한 코드들이 드러나는 걸 보며 쾌감(?)을 느꼈고, 이를 기점으로 웹 디자이너라는 꿈을 <strong>프론트엔드 개발자로 확장시키게 되었다.</strong> </p>
<br>

<hr>
<h2 id="제로베이스-프론트엔드-스쿨">제로베이스 프론트엔드 스쿨</h2>
<p>을 선택하게 된 건 학교에서 배우는 것보다 좀 더 빠르게 내 꿈에 도전하고 싶었던 마음이 컸고, 부트캠프를 검색해봤는데 온라인 강의로 내가 일정을 정해서 공부할 수 있다는 점과 많은 포트폴리오를 제작해볼 수 있을 것 같았기 때문이다.</p>
<p>강의 목차를 보았을 때 매우 많은 분량의 내용이 있는 걸 확인했다. 선불제로 결제했기 때문에 강의를 미리 들어볼 수 있었는데, 들으면 들을수록 재밌다는 생각만 가득했다. 나는 무엇을 하든 기본이 제일 중요하다고 생각한다. 기본기를 제일 튼튼하게 잡은 후 하루빨리 다양하고 어려운 기술들을 배우며 나만의 포트폴리오를 잔뜩 만들고 싶다!</p>
<br>

<hr>
<h2 id="6개월-간의-학습-계획">6개월 간의 학습 계획</h2>
<p>학교와 병행하기란 쉽지가 않다는 걸 요즘 느끼고 있지만 가장 큰 목표는 부지런히 공부해서 6개월 동안 부트캠프를 완주하는 것이다.</p>
<br>

<blockquote>
<p><em><strong>&quot; 배움은 우연히 얻어지는 것이 아니라 열성을 다해 갈구하고 부지런히 집중해야 얻을 수 있는 것이다. &quot;</strong></em> &nbsp; - 애비게일 애덤스</p>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>