CSS로 HTML 요소 스타일링하기: 테두리, 그림자 및 윤곽

저자는 기술 다양성 기금기부를 위한 글 쓰기 프로그램의 일환으로 선정했습니다.

소개

그림자, 테두리 및 윤곽을 다루는 것은 웹 개발의 주요 구성 요소이며, HTML 요소와 텍스트 항목 주변에 시각적 정의를 제공할 수 있습니다. 테두리와 그림자의 외관은 다섯 가지 주요 CSS 속성을 통해 조작할 수 있습니다: border, border-radius, box-shadow, text-shadow, 및 outline. 그림자는 깊이를 제공하고 요소가 돋보이도록 도와주며, border 속성은 콘텐츠 사이의 선형 구분자를 만들거나 그리드의 공간을 정의하는 등 여러 가지 시각적 기능을 수행할 수 있습니다. border-radius 속성은 상자의 모서리를 둥글게 만들고 심지어 원형 모양을 만들 수도 있습니다. 마지막으로 outline은 종종 무시되는 속성으로, 콘텐츠의 흐름을 방해하지 않으면서 border 속성의 많은 기능을 제공합니다.

이 자습서에서는 이러한 속성을 사용하여 허구의 우주 여행 회사를 위한 법적 고지를 작성할 것입니다. 데모를 통해 가장자리 기반 속성을 사용하여 시각적으로 풍부한 컨테이너를 만들 것입니다. 또한 여러 그림자와 같은 보다 복잡한 값 및 다른 브라우저가 특정 속성을 다르게 구현할 수 있는 점에 대해 고려할 것입니다.

필수 조건

기본 HTML 및 CSS 설정

이 섹션에서는 튜토리얼 전체를 통해 작성할 모든 시각적 스타일의 HTML 기본을 설정합니다. 또한 styles.css 파일을 생성하고 콘텐츠의 레이아웃을 설정하는 스타일을 추가합니다.

index.html을 텍스트 편집기에서 열고 파일에 다음 HTML을 추가합니다:

index.html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Travel Disclosure - Destination: Moon</title>
    <link href="styles.css" rel="stylesheet" />
  </head>
  <body>
  </body>
</html>

요소 내에 많은 페이지 설정이 정의되어 있습니다. 첫 번째 요소는 텍스트에 사용할 문자 세트를 정의합니다. 이렇게 하면 악센트 표시와 같은 대부분의 특수 문자가 특별한 HTML 코드 없이 렌더링됩니다. 두 번째 요소는 브라우저 및 모바일 브라우저가 특히 콘텐츠의 너비를 처리하는 방법을 알려줍니다. 그렇지 않으면 브라우저가 960px의 데스크톱 너비를 시뮬레이션합니다. 요소는 브라우저에 페이지 제목을 제공합니다. <link/> 요소는 튜토리얼 전반에 걸쳐 스타일을 작성할 CSS 파일을 로드합니다.

또한 스타일링할 콘텐츠가 필요합니다. 법적 텍스트의 경우 채우기 용도로 Legal Ipsum의 샘플 콘텐츠를 사용합니다.

텍스트 편집기에서 index.html로 돌아가 다음 코드 블록에서 강조 표시된 HTML을 추가하십시오:

index.html
<!doctype html>
<html>
  ...
  <body>
    <section class="disclosure-alert">
      <header class="disclosure-header">
        <h2  class="disclosure-title"><em>Destination: Moon</em> Travel Disclosure</h2>
      </header>
      <div class="disclosure-content">
        <p>Although space travel is routine practice, there are many unknown possibilities that any traveller must be aware of before traveling with <em>Destination: Moon</em>. Agreeing to this disclosure of knowns is required prior to purchase of tickets with <em>Destination: Moon</em>. PLEASE, READ AND AGREE TO THE FOLLOWING DISCLOSURE OF TRAVEL UNKNOWNS BEFORE PROCEEDING TO PURCHASE.</p>
        <div class="legal-contents">
          <p>Effect of Termination. Upon termination, You agree not to use it under the terms of Sections 4(a) through 4(e) for that Covered Code, or any third party. Description of Modifications.<p>
          <p>You must make sure that you know you can do these things. To make sure the requirements of this Agreement. REQUIREMENTS A Contributor may participate in any way. Notwithstanding the foregoing, if applicable law or agreed to in writing, the Copyright Holder, but only to the terms applicable to Covered Code. Inability to Comply Due to Statute or Regulation.</p>
          <p>If it is impossible for You to the Recipient retains any such Additional Terms. Versions of This License. If you are re-using, b) a hyperlink (where possible) or URL to the terms of Sections 4(a) through 4(e) for that Work shall terminate if it fails to comply with the exception of content that is granting the License. License Terms 1.</p>
          <p>Grant of Patent Infringement. If you have knowledge of patent infringement litigation, then the only applicable Base Interpreter is a "commercial item" as defined in 48 C.F.R. Consistent with 48 C.F.R.</p>
          <p>U.S. Government End Users acquire Covered Code (Original Code and/or as part of a Larger Work; and b) allow the Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Distributor in writing of such Contributor, if any, to grant more extensive warranty protection to some or all of these conditions: (a) You must make it clear that any Modifications made by such Respondent, or (ii) withdraw Your litigation claim is resolved (such as Wikimedia-internal copying), it is Recipient's responsibility to secure any other exploitation. Program, and in any of the provisions set forth in Section 4(b), you shall terminate if it fails to comply with.</p>
          <p>Please note that these licenses do allow commercial uses of your company or organization, to others outside of this License Agreement), provided that You meet the following terms which differ from this License) and (b) You must duplicate the notice in Exhibit A in each changed file stating how and when you changed the files and the definitions are repeated for your past or future use of the Original Code; or 3) for infringements caused by: i) third party against the drafter will not be used as a handle): 1895.22/1011. This Agreement shall be held by the terms of this agreement. If any provision of this license which gives you legal permission to modify NetHack, or otherwise using this software in source and binary forms, with or without modification in printed materials or in related documentation, stating that you provide a service, including but not limited to the terms under which you distribute, wherever you describe the origin or ownership of such termination, the Recipient a non-exclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6b1 or any part of Derivative Works. If You initiate litigation by asserting a patent infringement against You in that instance.</p>
          <p>Effect of New York and the like. While this license document the following disclaimer in the Work contain all the conditions listed in Clause 6 above, concerning changes from the Work. If you created a Modification, you may at your option offer warranty protection to some or all of the Licensed Program as a product of your Modifications available to others outside of this License.</p>
          <p>Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted to Licensor for inclusion in the documentation and/or other rights consistent with this program; if not, write to the modified files to carry prominent notices stating that You distribute, all copyright, patent, trademark, and attribution notices from the Public Domain or from the Original Code; 2) separate from the Public Domain or from the Work, you may distribute a Compiled Work on their system exactly as it is being maintained, then ask the Current Maintainer to update their communication data within one month. If the program is free software; you can change the License will not have to defend and indemnify every other Contributor to control, and cooperate with the Source Code version of the Licensed Program, or any Contributor.</p>
        </div>
        <div class="button-group">
          <a href="#" class="button button-primary">
            Agree
          </a>
          <a href="#" class="button button-secondary">
            Disagree
          </a>
        </div>
      </div>
    </section>
  </body>
</html>

index.html의 변경 사항을 저장한 다음 웹 브라우저를 엽니다. 파일 메뉴 항목을 선택한 다음 열기 옵션을 선택하여 브라우저에서 index.html 파일을 로드합니다. 다음 이미지는 이 HTML이 브라우저에서 어떻게 렌더링되는지를 보여줍니다:

index.html과 동일한 디렉토리에 styles.css라는 새 파일을 만들고 텍스트 편집기에서 엽니다. 이 파일에는 튜토리얼 전체에 사용되는 모든 스타일이 포함됩니다. 첫 번째 스타일 세트는 구축할 일반적인 미적 감각을 적용합니다. 다음 코드 블록의 CSS를 styles.css 파일에 적용하십시오:

styles.css
html, body {
  height: 100%;
}

body {
  display: flex;
  margin: 0;
  font: 100% / 1.5 sans-serif;
  background: url("images/moon-bg.jpg") no-repeat fixed center / cover black;
}
.disclosure-alert {
  background-color: hsl(0, 0%, 95%);
  width: 85%;
  max-width: 48rem;
  margin: auto;
  color: hsl(0, 0%, 20%);
}
.disclosure-header {
  background: linear-gradient(hsl(300, 50%, 20%), hsl(300, 50%, 10%));
  padding: 2rem 0.5rem;
  text-align: center;
  color: hsl(300, 50%, 95%);
}
.disclosure-title {
  margin: 0;
  font-size: 2rem;
  line-height: 1.25;
}
.disclosure-content {
  margin: 1.5rem;
}
.legal-contents {
  margin-top: 1.5rem;
  background-color: white;
  padding: 0.75rem;
  font-family: "Times New Roman", serif;
}
.button-group {
  margin-top: 1.5rem;
  display: flex;
  justify-content: center;
}
.button {
  display: inline-block;
  text-align: center;
  padding: 0.5rem 1rem;
  background: black;
  text-decoration: none;
  color: white;
  width: 50%;
  max-width: 8rem;
}
.button + .button {
  margin-left: 1.5rem;
}
.button-primary {
  background: linear-gradient(to bottom, hsl(200, 100%, 30%), hsl(200, 100%, 20%));
}
.button-primary:hover {
  background: linear-gradient(to bottom, hsl(200, 100%, 25%), hsl(200, 100%, 15%));
}
.button-secondary {
  background: linear-gradient(to bottom, hsl(200, 10%, 30%), hsl(200, 10%, 20%));
}
.button-secondary:hover {
  background: linear-gradient(to bottom, hsl(200, 10%, 25%), hsl(200, 10%, 15%));
}

이 파일의 스타일링은 페이지의 초기 레이아웃을 설정합니다. 중앙에 정렬된 법적 공개 선언서, 간격이 있는 버튼 및 선형 그라디언트로 렌더링된 이미지, 그리고 배경으로 사용된 달 이미지가 있습니다. 계속하기 전에 styles.css 파일을 저장하세요.

body 규칙의 background 속성에 링크된 이미지를 표시하려면 달 배경 이미지가 필요합니다. 먼저, index.html 파일과 동일한 폴더에 images 디렉토리를 만드세요:

  1. mkdir images

브라우저를 사용하여이 파일을 새로 만든 images 디렉토리로 다운로드하거나 다음 curl 명령을 사용하여 명령 줄을 통해 다운로드하십시오:

  1. curl -sL https://assets.digitalocean.com/articles/68102/moon-bg.jpg -o images/moon-bg.jpg

다음으로 브라우저로 돌아가서 새로 고침하세요. 이제 브라우저는 페이지 내용에 스타일을 렌더링하고 적용합니다. 다음 이미지는 전체 페이지가 어떻게 렌더링되는지 보여줍니다:

콘텐츠의 길이로 인해 매우 긴 페이지가 됩니다. 이것은 법적 복사본으로 의도되었으므로 .legal-contents의 내용이 스크롤 가능한 공간이 될 수 있습니다. 이는 height, max-heightoverflow 속성의 조합을 통해 수행됩니다.

스크롤 가능한 영역을 만들려면 텍스트 편집기에서 styles.css를 열고 다음 코드로 법적 콘텐츠의 높이를 조정하세요:

styles.css
...
.legal-contents {
  height: 50vh;
  max-height: 20rem;
  overflow: auto;
  margin-top: 1.5rem;
  background-color: white;
  padding: 0.75rem;
  font-family: "Times New Roman", serif;
}
...

이 코드에서는 .legal-contents 선택기 블록에 height 속성을 만들었습니다. 그런 다음 값을 50vh로 설정하여 뷰포트 창 높이의 50%로 설정했습니다. 또한 값이 20rem으로 설정된 max-height 속성을 만들었습니다. 마지막으로 overflow 속성을 추가하여 값으로 auto를 설정했습니다. 이는 콘텐츠가 컨테이너를 넘어서는 경우 스크롤 바를 생성합니다.

이러한 추가 사항을 styles.css 파일에 저장한 다음 브라우저로 돌아가 index.html을 새로 고치세요. 페이지와 메인 컨테이너의 전체 높이가 축소되었습니다. 이제 Legal Ipsum 복사본을 지정된 컨테이너 내에서 스크롤할 수 있습니다. 다음 애니메이션에 설명된 것처럼:

이 섹션 전체에서 나머지 튜토리얼에 사용할 기본 HTML을 설정했습니다. 또한 overflow 속성으로 스크롤 가능한 공간을 설정했습니다. 다음 섹션에서는 이러한 컨테이너에 테두리를 적용하기 위해 border 속성을 사용할 것입니다.

border 속성 사용

border 속성은 요소의 가장자리에 스타일을 적용하는 초기 방법 중 하나입니다. 컨테이너의 외곽 주변에 어떤 색상의 선을 적용합니다. 속성 값은 세 가지 구성 요소로 구성됩니다: 두께, 스타일 및 색상. border 속성은 요소의 네면에 이러한 값을 적용합니다. border-top 속성과 같은 border의 방향 변형으로 개별 면을 지정할 수 있습니다. 이것은 요소의 맨 위에만 적용됩니다.

border 속성 작업을 시작하려면 텍스트 편집기에서 styles.css를 열고 .disclosure-alert 클래스 선택기로 이동하십시오. 선택기 블록 내에 border 속성을 추가하고 값으로 1px solid hsl(0, 0%, 0%)을 설정합니다. 다음 코드 블록에서 강조된 대로:

styles.css
...
.disclosure-alert {
  background-color: hsl(0, 0%, 95%);
  width: 85%;
  max-width: 48rem;
  margin: auto;
  color: hsl(0, 0%, 20%);
  border: 1px solid hsl(0, 0%, 0%);
}
...

border 속성은 줄임 속성으로, 그 값이 다른 값의 조합입니다. 이 경우 1px의 두께는 border-width 속성 값으로 나타냅니다. 이 값은 단위와 함께 숫자 값 또는 몇 가지 이름 있는 값(thin, medium, thick)이 될 수 있습니다. 그 다음으로 solid은 요소 주변의 선이 어떻게 나타날지를 정의하는 border-style 값입니다. 이 경우에는 단단한 연속 선으로 나타납니다. border-style에는 dotted, dashed, double, none 등의 다른 값이 있습니다. 마지막 값은 border-color 속성을 정의하며, 이는 유효한 색상 값을 가질 수 있습니다.

styles.css에 변경 사항을 저장한 후, 웹 브라우저에서 index.html을 엽니다. 주요 콘텐츠 컨테이너에는 이제 얇은 검은 테두리가 있습니다. 이는 달 배경 이미지 위에 겹쳐져 가장 잘 나타납니다. 다음 이미지는 주요 콘텐츠 영역에 border가 어떻게 나타나는지 보여줍니다:

이제 요소에 하이라이트와 그림자를 적용하여 깊이감을 만들기 위해 border 속성을 사용할 수 있습니다. 이것은 배경색보다 밝은 방향으로 조금 밝은 색상의 border를 한 쪽에 적용한 다음 인접한 쪽에 더 어두운 색상을 사용하여 달성할 수 있습니다.

텍스트 편집기에서 styles.css로 돌아가서 .disclosure-header 클래스 선택기 블록으로 이동합니다. background 속성의 linear-gradient()는 약간 더 어두운 색조로 전환되는 짙은 보라색 그라데이션을 정의합니다. 그라디언트만으로는 깊이감을 만들기 어려울 때 다음 코드로 테두리를 조절할 수 있습니다:

styles.css
...
.disclosure-header {
  background: linear-gradient(hsl(300, 50%, 20%), hsl(300, 50%, 10%));
  padding: 2rem 0.5rem;
  text-align: center;
  color: hsl(300, 50%, 95%);
  border-top: 1px solid hsl(300, 50%, 35%);
  border-bottom: 1px solid hsl(300, 50%, 5%);
}
...

값이 1px solid hsl(300, 50%, 35%)border-top 속성을 추가했습니다. 이 값은 시작 그라데이션 값보다 약간 더 밝습니다. 그 다음에는 1px solid hsl(300, 50%, 5%) 값으로 설정된 border-bottom 속성을 만들었는데, 이 값은 그라디언트 끝부분보다 약간 어둡습니다.

styles.css에 변경 사항을 저장한 후, 브라우저로 돌아가서 index.html을 새로 고칩니다. 이제 보라색 헤더 배경에는 헤더 위쪽에 약간의 보라색 하이라이트와 아래쪽에 약간의 그림자가 있습니다. 다음 이미지는 이것이 브라우저에서 어떻게 나타날지 보여줍니다:

border는 약식 속성이므로 추가적인 긴 속성을 추가할 수 있습니다. 두 버튼 클래스의 너비와 스타일을 정의하는 border를 적용할 수 있으며, 개별 클래스에 border-color를 적용할 수 있습니다.

border-color를 사용하려면 텍스트 편집기에서 styles.css를 엽니다. .button 선택기 블록에 1px solid 값을 가진 border 속성을 추가한 다음, .button-primary.button-secondary에 대해 border-color 속성을 추가하십시오:

styles.css
...
.button {
  ...
  border: 1px solid;
}
...
.button-primary {
  background: linear-gradient(to bottom, hsl(200, 100%, 30%), hsl(200, 100%, 20%));
  border-color: hsl(200, 100%, 15%);
}
.button-primary:hover {
  background: linear-gradient(to bottom, hsl(200, 100%, 25%), hsl(200, 100%, 15%));
  border-color: hsl(200, 100%, 10%);
}
.button-secondary {
  background: linear-gradient(to bottom, hsl(200, 10%, 30%), hsl(200, 10%, 20%));
  border-color: hsl(200, 10%, 15%);
}
.button-secondary:hover {
  background: linear-gradient(to bottom, hsl(200, 10%, 25%), hsl(200, 10%, 15%));
  border-color: hsl(200, 10%, 10%);
}

이는 두 버튼에 1px 너비의 solid 스타일 테두리를 정의합니다. 그런 다음, .button-primary, .button-secondary 및 해당 :hover 상태 선택기에 대한 색상을 사용자 정의하기 위해 border-color 속성을 추가했습니다.

이러한 변경 사항을 styles.css에 저장한 다음 웹 브라우저에서 페이지를 새로 고칩니다. 다음 이미지에 표시된 것처럼, 버튼에는 이제 일치하는 더 어두운 색상의 테두리가 제공되어 약간 더 정의가 생겼습니다:

마지막으로, 각 border 방향도 약식입니다. 이는 -width, -style-color가 각각 방향 속성에 적용될 수 있다는 것을 의미합니다. 예를 들어, 긴 속성 border-right-color는 오른쪽 테두리에만 색상을 적용합니다.

이 방향성 장수 속성들을 사용하기 위해 텍스트 편집기에서 styles.css로 돌아가십시오. .legal-contents 선택기 블록으로 이동하여 네 개의 테두리 모서리에 대해 너비와 스타일을 설정한 다음 각 측면의 색상을 사용자 정의하십시오:

styles.css
...
.legal-contents {
  height: 50vh;
  max-height: 20rem;
  margin-top: 1.5rem;
  overflow: auto;
  background-color: white;
  border: 1px solid;
  border-top-color: hsl(0, 0%, 65%);
  border-bottom-color: hsl(0, 0%, 100%);
  border-right-color: hsl(0, 0%, 80%);
  border-left-color: hsl(0, 0%, 80%);
  padding: 0.75rem;
  font-family: "Times New Roman", serif;
}
...

이 코드에서 파일 끝에 border: 1px solid를 추가했습니다. 그 후에 추가로 border-top-color, border-bottom-color, border-right-color, 그리고 border-left-color 속성을 만들었습니다. 값으로는 서로 다른 hsl() 값을 회색으로 사용했습니다.

styles.css를 저장한 다음 브라우저에서 페이지를 다시로드하십시오. 스크롤 가능한 콘텐츠 컨테이너에는 이제 위쪽에 짙은 회색 테두리, 측면에는 약간 더 연한 회색, 아래쪽에는 흰색 테두리가 있습니다. 이것은 콘텐츠가 연한 회색 배경 뒤에 내입혀져 있어 하단 가장자리에 하이라이트가 있는 효과를 줍니다. 다음 이미지에서 보여지는 것처럼:

이 섹션에서는 border 속성과 그 다양한 장수 변형을 사용했습니다. 필요한 경우 서로 다른 측면에 적용된 여러 테두리를 만들었습니다. 다음 섹션에서는 컨테이너의 모서리를 둥글게 만드는 border-radius 속성을 사용할 것입니다.

border-radius 적용하기

둥근 모서리는 border-radius 속성이 작업을 수행하기 전에 웹에서 오랫동안 디자인적 요소로 사용되었습니다. 이 속성은 모든 숫자 단위 또는 백분율 값을 허용할 수 있으며, margin 또는 padding 속성과 같이 약식 속성입니다. 이것은 각 모서리를 필요에 따라 개별적으로 조절할 수 있음을 의미합니다.

border-radius 속성 작업을 시작하려면 텍스트 편집기에서 styles.css 파일을 엽니다. .disclosure-alert 선택기 블록과 border-radius 속성으로 이동합니다. 그런 다음, 값을 1.5rem으로 설정하십시오. 이렇게 하면 속성의 네 꼭지점에 해당 값이 적용됩니다. 다음 코드 블록에서 강조된 CSS는 이를 어떻게 작성하는지 보여줍니다:

styles.css
...
.disclosure-alert {
  ...
  border: 1px solid hsl(0, 0%, 0%);
  border-radius: 1.5rem;
}
...

styles.css에 이 추가를 저장한 다음 웹 브라우저에서 index.html을 열거나 새로 고침하십시오. 위쪽 두 꼭지점은 각각 원뿔 모양으로 남아 있으면서 아래쪽 두 꼭지점만 둥근 모양으로 나타납니다. 다음 이미지는 브라우저에서 이것이 렌더링되는 방식을 보여줍니다:

이 두 개의 둥근 모서리만 보이는 이유는 웹에서 하위 요소가 서로 상호 작용하는 방식 때문입니다. 브라우저는 콘텐츠가 보이도록 유지하는 쪽으로 작동합니다. .disclosure-alert에는 네 개의 둥근 모서리가 있지만 .disclosure-header가 요소 내부에 있고 둥근 모서리가 없기 때문에 둥근 모서리가 겹쳐져 있습니다. 빠른 수정은 .disclosure-alertoverflow: hidden을 추가하여 하위 컨테이너와 콘텐츠를 잘라내도록 하는 것입니다. 그러나 이 방식은 필요한 콘텐츠가 읽기 불가능하거나 보이지 않게 할 수 있습니다. 더 나은 방법은 조상의 코너 곡선과 일치하도록 .disclosure-header 클래스에 border-radius를 적용하는 것입니다.

겹치는 모서리를 조정하려면 텍스트 편집기에서 styles.css로 돌아가세요. .disclosure-header 선택기 블록으로 이동하고 border-radius 속성을 추가하세요. 맨 위의 두 개의 모서리만 조정해야 하므로 값은 1.5rem 1.5rem 0 0이 될 것입니다:

styles.css
...
.disclosure-header {
  ...
  border-top: 1px solid hsl(300, 50%, 35%);
  border-bottom: 1px solid hsl(300, 50%, 5%);
  border-radius: 1.5rem 1.5rem 0 0;
}
...

이 값의 확장 형식은 위쪽 왼쪽 및 오른쪽 모서리에 1.5rem 곡선을 적용합니다.

styles.css를 저장하고 브라우저에서 index.html을 새로 고칩니다. 보라색 헤더에 이제 둥근 모서리가 있고 메인 컨테이너를 가리지 않습니다. 그러나 새로운 문제가 발생했습니다. 부모 컨테이너의 흰색 조각이 보라색 헤더 뒤에서 피어오르는 것을 확인할 수 있습니다. 다음에 줌된 이미지에 표시됩니다:

.disclosure-alert.disclosure-header의 코너는 모두 1.5rem의 크기입니다. 그러나 그들의 폭은 크기 차이가 있습니다. 이 크기 차이는 .disclosure-alert 요소의 왼쪽과 오른쪽에 있는 border에 의해 발생합니다. border의 폭은 양쪽 모두 1px이므로 크기 차이는 2px 또는 0.125rem입니다. 곡선을 일치시키려면 .disclosure-headerborder-radius를 현재보다 0.125rem 작게 설정해야 합니다. 다음 코드 블록에서 강조된 대로 1.5remborder-radius 값을 1.375rem로 변경하십시오:

styles.css
...
.disclosure-header {
  background: linear-gradient(hsl(300, 50%, 20%), hsl(300, 50%, 10%));
  padding: 2rem 0.5rem;
  text-align: center;
  color: hsl(300, 50%, 95%);
  border-top: 1px solid hsl(300, 50%, 35%);
  border-bottom: 1px solid hsl(300, 50%, 5%);
  border-radius: 1.375rem 1.375rem 0 0;
}
...

이 변경 사항을 styles.css에 저장한 다음 웹 브라우저에서 페이지를 새로 고칩니다. 이제 하얀색의 가는 선이 없어졌으며 두 요소의 곡선이 적절한 위치에서 만나게 됩니다. 다음 확대된 스크린샷에서 이러한 곡선이 어떻게 일치하는지를 보여줍니다:

마지막으로, 메인 컨테이너 하단의 버튼에 둥근 모서리를 적용합니다. 이 버튼은 피스타치오 모양을 가지며, 긴 평평한 상단과 하단 및 완전히 둥근 측면을 가집니다. 이를 위해 border-radius 값은 요소의 높이보다 큰 단위 기반 값이어야 합니다.

원형 모양의 버튼을 만들려면 텍스트 편집기에서 styles.css 파일을 엽니다. .button 선택기 블록에서 border-radius 속성을 추가한 다음 값을 2rem으로 설정합니다. 이 값은 계산된 높이보다 큰 임의의 숫자일 수 있습니다. 이는 요소의 전체 높이에 영향을 줄 수 있는 font-size, line-height, padding, 및 border-width의 조합입니다. 다음 코드 블록에서 강조된 CSS는 이 속성을 추가해야 하는 위치를 보여줍니다:

styles.css
...
.button {
  ...
  border: 1px solid;
  border-radius: 2rem;
}
...

이 접근 방식에 대해 두 가지 사항을 주의해야 합니다. 첫째로, 이 요소에는 height 값이 설정되지 않습니다. height 값을 설정하는 것은 내용이 컨테이너를 벗어나는 위치에 있을 수 있기 때문에 피해야 합니다. 설정된 height를 피함으로써 버튼은 총 콘텐츠와 일치하도록 확장될 수 있습니다. 둘째로, 이 방법은 백분율 기반 값과 올바르게 작동하지 않습니다. 백분율 기반 값은 border-radius 속성에서 높이와 너비의 백분율을 곡선화하여 둥근 모양이 아닌 타원 모양을 만듭니다.

styles.css 파일을 저장한 후 브라우저로 돌아가 index.html을 새로 고칩니다. 이제 페이지에는 다음 이미지에 표시된 것과 같이 두 개의 타원형 원형 버튼이 렌더링됩니다:

이 섹션 전반에 걸쳐 여러 요소에 둥근 모서리를 적용하기 위해 border-radius 속성을 사용했습니다. 여러 요소에 레이어링된 둥근 모서리가 있는 경우 하위 요소가 곡선 공간을 벗어나지 않는다는 것을 발견했습니다. 또한 여러 요소에 레이어링된 경우 요소의 너비와 일치하도록 border-radius 값을 조정했습니다. 다음 섹션에서는 텍스트 콘텐츠에 그림자를 적용하기 위해 text-shadow 속성을 사용할 것입니다.

text-shadow 속성 사용하기

텍스트에 그림자를 적용하는 것은 일상적인 웹 개발에서 많이 사용됩니다. 그림자는 깊이를 만들거나, 빛나는 효과를 줄 수 있으며, 텍스트가 간과되기 쉬운 곳에서 텍스트를 두드러지게 만들 수 있습니다. 이 섹션 전반에 걸쳐 여러 요소에 text-shadow를 적용하여 다양한 시각적 효과를 만들 것입니다.

text-shadow 속성은 최대 네 가지 값으로 구성됩니다: x축 오프셋, y축 오프셋, 흐림 반경 및 색상. 예를 들어, 값은 다음과 같을 수 있습니다: 2px 4px 10px red. 이 네 가지 값 중 오프셋 값만 필수입니다. 그림자 색상은 기본적으로 텍스트의 color입니다.

text-shadow 작업을 시작하려면 헤더에 발광 효과를 만들어야 합니다. 텍스트 편집기에서 styles.css를 열고 .disclosure-header 클래스 선택기로 이동하십시오. 선택기 블록 내에 다음 text-shadow 속성을 추가하십시오:

styles.css
...
.disclosure-header {
  ...
  border-radius: 1.375rem 1.375rem 0 0;
  text-shadow: 0 0 0.375rem hsl(300, 50%, 50%);
}
...

A glow effect means the color will emanate from every edge of the text, so the x- and y-axis offset values here are set to 0. You set the blur for the glow to 0.375rem (equivalent to 6px) to give a subtle halo of color to the text. Lastly, the color value was set to a bit darker than the color property: hsl(300, 50%, 50%).

당신의 styles.css 파일에 이 추가를 저장하세요. 그 다음, 웹 브라우저에서 index.html을 엽니다. 보라색 그라디언트 배경에 있는 굵은 제목 텍스트에는 이제 중간 보라색의 빛이 밝아집니다. 이 효과가 브라우저에서 어떻게 렌더링되는지 보여주는 이미지가 있습니다:

다음으로, 텍스트 요소에 여러 그림자를 배치하여 텍스트에 입체감 효과를 만들 수 있습니다. 이 효과는 객체 아래에 더 밝은 색상의 그림자를 배치하고 위에 더 어두운 색상의 그림자를 배치하여 달성됩니다.

입체감 효과를 만들려면 텍스트 편집기에서 styles.css로 돌아가세요. 효과는 컨테이너 하단의 버튼에 추가됩니다. .button-primary, .button-primary:hover, .button-secondary, 그리고 .button-secondary:hover 선택기에 text-shadow 속성을 추가하세요. 다음 코드 블록에서 강조된 CSS 값을 확인하세요:

styles.css
...
.button-primary {
  border: 1px solid hsl(200, 100%, 5%);
  background: linear-gradient(to bottom, hsl(200, 100%, 30%), hsl(200, 100%, 20%));
  text-shadow: 0 1px hsl(200, 100%, 50%),
               0 -1px hsl(200, 100%, 5%);
}
.button-primary:hover {
  border: 1px solid hsl(200, 100%, 0%);
  background: linear-gradient(to bottom, hsl(200, 100%, 25%), hsl(200, 100%, 15%));
  text-shadow: 0 1px hsl(200, 100%, 45%),
               0 -1px hsl(200, 100%, 0%);
}
.button-secondary {
  border: 1px solid hsl(200, 10%, 5%);
  background: linear-gradient(to bottom, hsl(200, 10%, 30%), hsl(200, 10%, 20%));
  text-shadow: 0 1px hsl(200, 10%, 50%),
               0 -1px hsl(200, 10%, 5%);
}
.button-secondary:hover {
  border: 1px solid hsl(200, 10%, 0%);
  background: linear-gradient(to bottom, hsl(200, 10%, 25%), hsl(200, 10%, 15%));
  text-shadow: 0 1px hsl(200, 10%, 45%),
               0 -1px hsl(200, 10%, 0%);
}

첫 번째 그림자는 더 밝은 아래쪽의 안쪽 하이라이트입니다. 이는 0 1px 오프셋으로 수행되며, 그런 다음 배경 그라디언트 색조의 더 밝은 버전을 사용합니다. 다음으로, 텍스트 위에 그림자를 만들었습니다. 0 -1px 오프셋으로, 이는 그림자를 1px 올려놓고 배경 색상의 더 어두운 변형을 사용합니다.

이 변경 사항을 styles.css에 저장한 다음, 웹 브라우저에서 페이지를 새로 고칩니다. 버튼 안의 텍스트에는 이제 텍스트 아래에 약간의 하이라이트와 텍스트 위에 약간의 그림자가 있습니다. 이러한 text-shadow 값의 조합이 다음 이미지에 표시된 바와 같이 입체감 효과를 만듭니다:

이 섹션에서는 몇 가지 요소에 text-shadow 속성을 적용했습니다. 헤더에는 빛나는 효과를 만들었고, 버튼에는 여러 그림자로 입체감 있는 효과를 만들었습니다. 다음 섹션에서는 box-shadow 속성을 사용하여 HTML 요소에 그림자를 적용할 것입니다.

요소에 box-shadow 추가하기

text-shadow 속성이 텍스트 콘텐츠에 그림자를 적용하는 것과 마찬가지로 box-shadow 속성은 요소와 컨테이너에도 그림자를 적용할 수 있습니다. box-shadow에는 이 섹션에서 살펴볼 두 가지 추가 기능이 있습니다. 그것은 블러의 확산을 제어하고 그림자를 요소 안쪽에 설정하는 기능입니다.

box-shadow 속성을 사용하기 시작하려면 텍스트 편집기에서 styles.css 파일을 엽니다. .disclosure-alert 선택자 블록에 box-shadow 속성을 추가합니다. text-shadow와 마찬가지로 x 및 y 축 오프셋 값이 필요하며, 색상이 제공되지 않으면 color 속성 값이 사용됩니다. 이 첫 번째 box-shadow에서는 오프셋을 0, 블러를 0.5rem, 색상을 어두운 hsl(300, 40%, 5%)로 설정합니다. 아래 코드 블록에서 강조된 대로 설정합니다:

styles.css
...
.disclosure-alert {
  ...
  border-radius: 1.5rem;
  text-shadow: 0 0 0.375rem hsl(300, 50%, 50%);
  box-shadow: 0 0 0.5rem hsl(300, 40%, 5%);
}
...

styles.css에 변경 사항을 저장하고 웹 브라우저에서 페이지를 새로 고칩니다. 이제 컨테이너에서 거의 검은색 그림자가 퍼져 나가는 것을 볼 수 있습니다. 또한 그림자가 border-radius 속성으로 만든 곡선을 존중하고 따릅니다. 다음 이미지는 이를 브라우저에서 렌더링하는 방법을 보여줍니다:

다음으로 styles.css로 돌아가서 box-shadow에 두 가지 추가 큰 빛나는 효과를 추가하여 보다 복잡한 효과를 만들기 시작하세요. 각 새 그림자 사이에 쉼표를 추가하고, 각각을 0.5rem의 y-축 오프셋으로 설정합니다. 그런 다음 컬러 팔레트에서 파란색과 보라색의 더 밝은 변형을 사용하여 큰 흐림을 설정합니다. 다음 코드 블록에 강조된 대로:

styles.css
...
.disclosure-alert {
  ...
  box-shadow: 0 0 0.5rem hsl(300, 40%, 5%),
              0 0.5rem 6rem hsl(200, 40%, 30%),
              0 0.5rem 10rem hsl(300, 40%, 30%);
}
...

이 그림자의 순서가 중요합니다. 거의 검은 색상의 첫 번째 그림자가 새로운 그림자 위에 표시되고, 각 후속 그림자가 다음 그림자 뒤에 추가됩니다.

styles.css에 변경 사항을 저장하고 웹 브라우저에서 페이지를 새로 고칩니다. 다음 이미지에 설명된 대로 여러 그림자를 결합하면 독특한 효과가 렌더링됩니다:

box-shadow 속성의 흐림 확산 기능을 사용하여 깊이감을 만들 수 있습니다. 확산 값은 양수와 음수 값을 모두 허용합니다. 강한 오프셋과 흐림이 결합된 음수 값 확산은 소스 컨테이너에서 멀리 떨어져 있는 그림자를 만듭니다.

시작하려면 텍스트 편집기에서 .disclosure-alert 선택기의 어두운 작은 그림자와 더 큰 파란색 그림자 사이에 다음 강조된 CSS를 추가하세요.

styles.css
...
.disclosure-alert {
  ...
  box-shadow: 0 0 0.5rem hsl(300, 40%, 5%),
              0 6rem 4rem -2rem hsl(300, 40%, 5%),
              0 0.5rem 6rem hsl(200, 40%, 30%),
              0 0.5rem 10rem hsl(300, 40%, 30%);
}
...

이 그림자 세트의 추가는 x 축 오프셋을 0으로 유지하지만, y 축은 상당히 6rem으로 이동합니다. 다음으로, 흐림은 빛보다 크지 않지만 4rem의 적당한 크기로 설정됩니다. 그런 다음 이동합니다. 이 경우에 흐림 확산 값은 -2rem으로 설정됩니다. 확산의 기본값은 0으로, 이는 컨테이너와 동일합니다. -2rem에서 확산하면 컨테이너에서 안쪽으로 압축되어 깊이감을 시각적으로 만듭니다.

styles.css에 변경 사항을 저장한 다음 브라우저에서 index.html을 새로 고칩니다. 이 그림자는 깊은 보라색으로, 메인 콘텐츠 상자가 달 표면의 상단을 훌쩍 떠다니는 느낌을 줍니다. 다음 이미지에 렌더링되어 있습니다:

box-shadow를 사용하는 또 다른 용도는 헤더에서 border 속성을 사용한 것처럼 약간의 하이라이트와 그림자 베벨 효과를 만드는 것입니다. box-shadow를 사용하는 장점은 박스 모델에 영향을 주지 않는다는 것입니다. 이는 콘텐츠 흐름의 변화를 초래합니다. 또한 border와 함께 사용할 수 있습니다. 이 효과를 border와 함께 사용할 때는 그림자가 컨테이너 내부에 있도록 box-shadowinset 값을 추가해야 합니다.

box-shadowinset 값을 사용하려면 텍스트 편집기에서 styles.css를 엽니다. 이 효과는 버튼에 추가될 것이므로 이 스타일을 .button-primary, .button-primary:hover, .button-secondary, .button-secondary:hover에 적용할 것입니다. text-shadow와 마찬가지로 이것은 0 1px0 -1px 오프셋 조합으로 구성될 것입니다. 차이점은 inset이 값을 시작하거나 끝에 추가할 수 있다는 것입니다. 다음 코드 블록에서 강조된 대로입니다:

styles.css
...
.button-primary {
  ...
  text-shadow: 0 1px hsl(200, 100%, 50%),
               0 -1px hsl(200, 100%, 5%);
  box-shadow: inset 0 1px hsl(200, 100%, 50%),
              inset 0 -1px hsl(200, 100%, 15%);
}
.button-primary:hover {
  ...
  text-shadow: 0 1px hsl(200, 100%, 45%),
               0 -1px hsl(200, 100%, 0%);
  box-shadow: inset 0 1px hsl(200, 100%, 45%),
              inset 0 -1px hsl(200, 100%, 10%);
}
.button-secondary {
  ...
  text-shadow: 0 1px hsl(200, 10%, 50%),
               0 -1px hsl(200, 10%, 5%);
  box-shadow: inset 0 1px hsl(200, 10%, 50%),
              inset 0 -1px hsl(200, 10%, 15%);
}
.button-secondary:hover {
  ...
  text-shadow: 0 1px hsl(200, 10%, 45%),
               0 -1px hsl(200, 10%, 0%);
  box-shadow: inset 0 1px hsl(200, 10%, 45%),
              inset 0 -1px hsl(200, 10%, 10%);
}

이 변경 사항을 styles.css에 저장한 다음 브라우저에서 index.html을 새로 고칩니다. 이제 버튼에는 텍스트와 유사한 하이라이트와 그림자가 있습니다. 이것은 그라디언트 배경과 결합되어 버튼에 간단하지만 구별되는 효과를 만듭니다. 다음 이미지는 브라우저에서 이것이 렌더링되는 방식을 보여줍니다:

마지막으로, 인셋 쉐도우에도 흐림 확산 값을 적용할 수 있습니다. 확산은 흐림의 시작점을 가장자리에서 바깥쪽으로 이동시킵니다. 그러나 inset을 사용할 때, 확산은 흐림의 시작점을 안쪽으로 이동시킵니다. 이는 inset에 음수 값이 적용될 때 요소의 보기 영역 밖으로 그림자가 확장된다는 것을 의미합니다. 확산의 외부 확장은 짧은 그라디언트처럼 보이는 그림자를 만들 수 있습니다. 이는 그림자가 요소의 콘텐츠 아래에 적용되어 요소의 가장자리에 라운딩이 있는 것처럼 보이는 환상을 만들 수 있습니다.

이 효과를 만들기 위해 텍스트 편집기에서 styles.css를 엽니다. .legal-contents 클래스 선택기로 이동하여 box-shadow 속성을 추가합니다. 이 그림자는 세 개의 그림자로 구성됩니다. 첫 번째는 전체 컨테이너 주위에 짧은 그림자를 설정하고, 나머지 두 개는 요소의 위쪽과 아래쪽에 연장된 밝은 그림자를 제공합니다. 다음 코드 블록에서 강조된 CSS는 이를 설정하는 방법을 보여줍니다:

styles.css
...
.legal-contents {
  ...
  font-family: "Times New Roman", serif;
  box-shadow: 0 0 0.25rem hsl(0, 0%, 80%) inset,
              0 4rem 2rem -4rem hsl(0, 0%, 85%) inset,
              0 -4rem 2rem -4rem hsl(0, 0%, 85%) inset;
}
...

styles.css를 저장한 다음 브라우저에서 페이지를 새로 고칩니다. 그림자가 이제 법적 텍스트가 컨테이너로 유려하게 보이도록 효과를 만들고 있습니다. 또한, 이 요소에 적용된 border 색상을 강화하는 데도 그림자가 도움이 됩니다. 다음 이미지는 브라우저에서 이렇게 렌더링되는 것을 보여줍니다:

이 섹션에서는 box-shadow 속성을 실제로 사용했습니다. 블러 확산과 inset 기능을 사용하여 더 많은 스타일링 옵션을 제공했습니다. 마지막 섹션에서는 outline 속성을 구현한 다음 더 다양한 outline을 만들기 위해 box-shadow를 사용할 것입니다.

outline 속성 사용

마지막으로 요소의 가장자리에 영향을 주는 속성은 outline 속성입니다. 모든 브라우저에서 요소의 :focus 상태는 outline 속성을 사용하여 만듭니다. 그러나 각 브라우저의 기본 :focus 스타일 구현은 상당히 다릅니다. outline 속성은 border 속성과 유사하지만 두 가지 주요 차이점이 있습니다. 방향 속성 변형이 없으며 박스 모델에 영향을 주지 않습니다. 이 두 차이 중 마지막은 콘텐츠 흐름을 방해하지 않으면서 활성 요소의 시각적 표시를 제공하여 :focus 스타일에 이상적입니다.

:focus 상태의 브라우저 기본값을 관찰하려면 브라우저에서 index.html을 엽니다. 페이지를 탐색하려면 TAB 키를 사용하여 하단 버튼 중 하나에 포커스를 이동합니다. 사용하는 브라우저에 따라 기본 :focus 스타일을 볼 수도 있고 아닐 수도 있습니다. 예를 들어 Firefox는 흰색 점선 테두리를 표시하지만 연한 회색 배경에는 인식할 수 없습니다. 다음 이미지는 왼쪽부터 오른쪽으로 Firefox, Safari 및 Chrome에서 기본 포커스 스타일이 표시되는 방식을 보여줍니다:

outline 속성을 사용하여 사용자 지정 :focus 상태를 시작하려면 텍스트 편집기에서 styles.css를 엽니다. .button 클래스 선택기로 이동하여 outline 속성을 추가합니다:

styles.css
...
.button {
  ...
}
.button:focus {
  outline: 0.25rem solid hsl(200, 100%, 50%);
}
...

border 속성과 마찬가지로 outline의 값은 너비, 스타일 및 색상 값을 포함합니다. 초점 상태의 목표는 요소에 주의를 끌기 위한 것이므로 너비를 0.25rem으로 증가시킵니다. 이는 4px와 동등합니다. 그 다음으로 스타일을 solid로 설정하여 초점 상태를 Safari와 Chrome의 것과 더 유사하게 만듭니다. 마지막으로 색상을 hsl(200, 100%, 50%)의 짙은 파랑으로 설정합니다.

styles.css에 변경 사항을 저장한 다음 브라우저로 돌아가 페이지를 새로 고칩니다. 다시 한번, 브라우저가 outline을 어떻게 렌더링할지 결정합니다. 다음 이미지는 Firefox, Safari 및 Chrome에서 이러한 스타일이 어떻게 보이는지를 보여줍니다. (왼쪽에서 오른쪽으로):

세 브라우저 모두 outline 속성이 다르게 표시됩니다. Firefox는 버튼의 전체 둥근 모양 주위에 꽉 잡아 유지합니다. Safari는 직각의 상자를 만들지만 버튼의 가장자리에 닿습니다. Chrome은 Safari와 유사하지만 버튼과 outline 사이에 약간의 여백을 추가합니다.

모든 브라우저에서 Firefox와 유사한 스타일을 만들려면 outline 대신 box-shadow를 사용해야 합니다.

더 사용자 정의된 :focus 상태를 만들기 위해 텍스트 편집기에서 styles.css 파일로 돌아갑니다. 첫 번째로 할 일은 브라우저의 기본 outline 스타일을 비활성화하는 것입니다. 이를 위해 .button:focus 선택기의 outline 값을 none으로 변경합니다. 다음 코드 블록에서 강조되었습니다:

styles.css
...
.button {
  ...
}
.button:focus {
  outline: none;
}
...

그 다음, button-primary:hoverbutton-secondary:hover 선택기로 이동한 다음 쉼표 다음에 :focus 상태 변형을 추가하십시오. 다음 코드 블록에서 강조된 대로:

styles.css
...

.button-primary {
  ...
}
.button-primary:hover,
.button-primary:focus {
  ...
}
.button-secondary {
  ...
}
.button-secondary:hover,
.button-secondary:focus {
  ...
}

마지막으로 각 버튼의 :focus에 대해 두 개의 새로운 선택기를 만드십시오. .button-primary: focus.button-secondary:focus. 새 선택기 블록 내부에 이전 선택기의 :hover, :focus와 동일한 삽입 그림자를 추가하십시오. 그런 다음 오프셋과 블러를 모두 0으로 설정한 다른 그림자를 시리즈에 추가하십시오. 그런 다음, 0.25rem의 스프레드를 추가하십시오. 이것은 요소 주위에 고체이고 블러 처리되지 않은 선을 만듭니다. 마지막으로, 두 인스턴스에 동일한 색상을 추가하십시오. 다음 코드 블록에서 강조된 CSS는 이를 작성하는 방법을 보여줍니다:

styles.css
...

.button-primary {
  ...
}
.button-primary:hover,
.button-primary:focus {
  ...
}
.button-primary:focus {
  box-shadow: inset 0 1px hsl(200, 100%, 45%),
              inset 0 -1px hsl(200, 100%, 10%),
              0 0 0 0.25rem hsl(200, 100%, 50%);
}
.button-secondary {
  ...
}
.button-secondary:hover,
.button-secondary:focus<^> {
  ...
}
.button-secondary:focus {
  box-shadow: inset 0 1px hsl(200, 10%, 45%),
              inset 0 -1px hsl(200, 10%, 10%),
              0 0 0 0.25rem hsl(200, 100%, 50%);
}

이러한 변경 사항을 styles.css에 저장하고 브라우저로 돌아가서 index.html을 새로 고칩니다. 이제 페이지를 통해 이동하는 동안 TAB 키를 사용하면 브라우저에 관계없이 버튼에 대한 :focus 스타일이 동일하게 보입니다. 다음 이미지는 브라우저에서 box-shadow 버전의 윤곽선이 나타나는 모습과 전체 페이지입니다:

마지막 섹션에서는 outline 속성을 소개하고 각 브라우저가 다른 방식으로 사용하는 방법을 설명했습니다. 접근성을 위해 최소한의 :focus 표시가 필요하며 outline 속성이 이 작업을 수행합니다. 이를 확장하여 큰 스프레드 값을 가진 box-shadow를 생성함으로써 더 고급스럽고 시각적으로 일관된 :focus 스타일을 만들었습니다.

결론

요소의 가장자리를 스타일링하면 웹 사이트의 디자인이 다양성과 주의를 끌 수 있습니다. border 속성은 콘텐츠 사이에 정의와 분리를 제공하는 데 도움을 줄 수 있습니다. border-radius 속성은 미적인 측면을 부드럽게 하고 디자인의 태도를 정의하는 데 도움이 됩니다. 텍스트와 상자에 그림자를 넣으면 깊이가 생기고 콘텐츠에 주의를 끌 수 있습니다. 마지막으로 outline 속성은 키보드 초점이 있는 요소에 주의를 끌기 위한 접근 가능한 방법을 제공합니다. 이 튜토리얼에서는 이러한 속성을 모두 사용하여 시각적으로 흥미로운 사용 가능한 웹 페이지를 만들었습니다. 이러한 각 속성을 이해하고 언제 어떻게 사용해야 하는지를 이해하면 다양한 종류의 프론트엔드 인터페이스 문제를 해결하고 새로운 경험을 만들 수 있습니다.

더 많은 CSS 튜토리얼을 읽고 싶다면 CSS로 HTML 스타일링하는 방법 시리즈의 다른 튜토리얼을 시도해보세요.

Source:
https://www.digitalocean.com/community/tutorials/how-to-style-html-elements-with-borders-shadows-and-outlines-in-css