프런트 엔드 프로젝트의 일반적인 CSS 문제

게시 됨: 2022-03-10
빠른 요약 ↬ 최근 몇 년 동안 여러 브라우저에서 렌더링 및 상호 작용의 일관성이 훨씬 높아졌습니다. 그러나 여전히 완벽하게 균일하지 않으며 많은 작은 문제로 인해 문제가 발생할 수 있습니다. 이러한 문제 외에도 다양한 화면 크기, 언어 기본 설정 및 단순한 인적 오류의 변수를 추가하면 개발자를 당황하게 하는 작은 일들이 많이 있습니다.

브라우저에서 사용자 인터페이스를 구현할 때 UI를 예측할 수 있도록 가능한 모든 곳에서 이러한 차이점과 문제를 최소화하는 것이 좋습니다. 이러한 차이점을 모두 추적하는 것은 어렵기 때문에 새 프로젝트에서 작업할 때 유용한 참조 가이드로 일반적인 문제 목록과 해당 솔루션을 함께 작성했습니다.

의 시작하자.

1. button 배경 재설정 및 요소 input

버튼을 추가할 때 배경을 재설정하십시오. 그렇지 않으면 브라우저마다 다르게 보일 것입니다. 아래 예에서는 Chrome과 Safari에 동일한 버튼이 표시됩니다. 후자는 기본 회색 배경을 추가합니다.

(큰 미리보기)

배경을 재설정하면 이 문제가 해결됩니다.

 button { appearance: none; background: transparent; /* Other styles */ } 

CodePen에서 Ahmad Shadeed(@shadeed)의 펜 버튼 및 입력을 참조하십시오.

CodePen에서 Ahmad Shadeed(@shadeed)의 펜 버튼 및 입력을 참조하십시오.
점프 후 더! 아래에서 계속 읽기 ↓

2. 오버플로: scrollauto

요소의 높이를 제한하고 사용자가 요소 내에서 스크롤할 수 있도록 하려면 overflow: scroll-y 를 추가하십시오. 이것은 macOS의 Chrome에서 잘 보일 것입니다. 그러나 Chrome Windows에서는 스크롤 막대가 항상 존재합니다(내용이 짧더라도). scroll-y 는 내용에 관계없이 스크롤 막대를 표시하는 반면 overflow: auto 는 필요할 때만 스크롤 막대를 표시하기 때문입니다.

왼쪽: macOS의 Chrome. 오른쪽: Windows의 Chrome. (큰 미리보기)
 .element { height: 300px; overflow-y: auto; } 

CodePen에서 Ahmad Shadeed(@shadeed)의 Pen overflow-y를 참조하십시오.

CodePen에서 Ahmad Shadeed(@shadeed)의 Pen overflow-y를 참조하십시오.

3. flex-wrap 추가

display: flex 를 추가하여 요소가 플렉스 컨테이너처럼 작동하도록 합니다. 그러나 화면 크기가 줄어들 때 flex-wrap 이 추가되지 않은 경우 브라우저는 가로 스크롤 막대를 표시합니다.

 <div class="wrapper"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div>
 .wrapper { display: flex; } .item { flex: 0 0 120px; height: 100px; }

위의 예는 큰 화면에서 잘 작동합니다. 모바일에서는 브라우저에 가로 스크롤 막대가 표시됩니다.

왼쪽: 가로 스크롤 막대가 표시되고 항목이 줄 바꿈되지 않습니다. 오른쪽: 항목이 두 행으로 줄 바꿈됩니다. (큰 미리보기)

솔루션은 매우 쉽습니다. 래퍼는 공간을 사용할 수 없을 때 항목을 포장해야 한다는 것을 알아야 합니다.

 .wrapper { display: flex; flex-wrap: wrap; } 

CodePen에서 Ahmad Shadeed(@shadeed)의 Pen flex-wrap을 참조하십시오.

CodePen에서 Ahmad Shadeed(@shadeed)의 Pen flex-wrap을 참조하십시오.

4. Flex 항목의 수가 동적인 경우 justify-content: space-between 사용하지 마십시오.

justify-content: space-between 이 플렉스 컨테이너에 적용되면 요소를 배포하고 요소 사이에 동일한 양의 공간을 남깁니다. 이 예에는 8개의 카드 항목이 있으며 보기에 좋습니다. 어떤 이유에서인지 항목 수가 7개라면? 요소의 두 번째 행은 첫 번째 행과 다르게 보입니다.

8개의 항목이 있는 래퍼. (큰 미리보기)
7개의 항목이 포함된 래퍼. (큰 미리보기)

CodePen에서 Ahmad Shadeed(@shadeed)의 Pen justify-content를 참조하십시오.

CodePen에서 Ahmad Shadeed(@shadeed)의 Pen justify-content를 참조하십시오.

이 경우 CSS 그리드를 사용하는 것이 더 적합합니다.

5. 긴 단어와 링크

모바일 화면에서 기사를 볼 때 긴 단어나 인라인 링크로 인해 가로 스크롤 막대가 나타날 수 있습니다. CSS의 word-break 를 사용하면 그런 일이 발생하지 않습니다.

큰 미리보기
 .article-content p { word-break: break-all; } 
(큰 미리보기)

자세한 내용은 CSS-Tricks를 확인하세요.

6. 투명한 그라디언트

투명한 시작점과 끝점이 있는 그라디언트를 추가하면 Safari에서 검은색으로 보입니다. Safari가 키워드 transparent 를 인식하지 못하기 때문입니다. rgba(0, 0, 0, 0) 으로 대체하면 예상대로 작동합니다. 아래 스크린샷을 참고하세요.

상단: Chrome 70. 하단: Safari 12. (큰 미리보기)
 .section-hero { background: linear-gradient(transparent, #d7e0ef), #527ee0; /*Other styles*/ }

대신 다음과 같아야 합니다.

 .section-hero { background: linear-gradient(rgba(0, 0, 0,0), #d7e0ef), #527ee0; /*Other styles*/ }

7. CSS 그리드에서 자동 auto-fitauto-fill 의 차이점에 대한 오해

CSS 그리드에서 repeat 기능은 미디어 쿼리를 사용하지 않고도 반응형 열 레이아웃을 만들 수 있습니다. 이를 달성하려면 auto-fill 또는 auto-fit 을 사용하십시오.

 .wrapper { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); } 
(큰 미리보기)

간단히 말해서 auto-fill 는 너비를 확장하지 않고 열을 정렬하는 반면 auto-fit 은 빈 열이 있는 경우에만 너비를 0으로 축소합니다. Sara Soueidan은 이 주제에 대한 훌륭한 기사를 작성했습니다.

8. 뷰포트가 충분히 높지 않을 때 화면 상단에 요소 고정

요소를 화면 상단에 고정하면 뷰포트가 충분히 높지 않으면 어떻게 됩니까? 단순함: 화면 공간을 차지하므로 결과적으로 사용자가 웹사이트를 탐색할 수 있는 수직 영역이 작고 불편하여 경험이 저하됩니다.

 @media (min-height: 500px) { .site-header { position: sticky; top: 0; /*other styles*/ } }

위의 스니펫에서 뷰포트의 높이가 500픽셀 이상인 경우에만 헤더를 상단에 고정하도록 브라우저에 지시합니다.

또한 중요: position: sticky 를 사용할 때 top 속성을 지정하지 않으면 작동하지 않습니다.

큰 미리보기

Pen Vertical 미디어 쿼리: CodePen에서 Ahmad Shadeed(@shadeed)의 고정 헤더를 참조하세요.

Pen Vertical 미디어 쿼리: CodePen에서 Ahmad Shadeed(@shadeed)의 고정 헤더를 참조하세요.

9. 이미지 max-width 설정

이미지를 추가할 때 max-width: 100% 를 정의하여 화면이 작을 때 이미지 크기가 조정되도록 합니다. 그렇지 않으면 브라우저에 가로 스크롤 막대가 표시됩니다.

 img { max-width: 100%; }

10. CSS 그리드를 사용하여 mainaside 요소 정의하기

CSS 그리드는 레이아웃의 main 섹션과 aside 섹션을 정의하는 데 사용할 수 있으며 그리드에 완벽하게 사용됩니다. 결과적으로 aside 섹션의 높이는 비어 있더라도 main 요소의 높이와 동일합니다.

이 문제를 해결하려면 aside 요소를 상위 요소의 시작 부분에 정렬하여 높이가 확장되지 않도록 합니다.

 .wrapper { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-gap: 20px; } // align-self will tell the aside element to align itself with the start of its parent. aside { grid-column: 1 / 4; grid-row: 1; align-self: start; } main { grid-column: 4 / 13; } 
(큰 미리보기)

CodePen에서 Ahmad Shadeed(@shadeed)의 펜 메인과 옆을 참조하십시오.

CodePen에서 Ahmad Shadeed(@shadeed)의 펜 메인과 옆을 참조하십시오.

11. SVG에 fill 추가하기

SVG로 작업하는 동안 fill 속성이 SVG에 인라인으로 추가된 경우 fill 가 예상대로 작동하지 않는 경우가 있습니다. 이 문제를 해결하려면 SVG 자체에서 fill 속성을 제거하거나 fill: color 를 재정의하십시오.

다음 예를 들어보세요.

 .some-icon { fill: #137cbf; }

SVG에 인라인 채우기가 있는 경우에는 작동하지 않습니다. 대신 다음과 같아야 합니다.

 .some-icon path { fill: #137cbf; }

12. 의사 요소로 작업하기

나는 가능하면 의사 요소를 사용하는 것을 좋아합니다. 그들은 HTML에 추가하지 않고 대부분 장식용으로 가짜 요소를 만드는 방법을 제공합니다.

작성자는 그들과 함께 작업할 때 다음 중 하나를 수행하는 것을 잊어버릴 수 있습니다.

  • content: "" 속성을 추가합니다.
  • display 속성을 정의하지 않고 widthheight 를 설정합니다.

아래 예에는 유사 요소로 배지가 있는 제목이 있습니다. content: "" 속성을 추가해야 합니다. 또한 widthheight 가 예상대로 작동하려면 요소에 display: inline-block 이 설정되어 있어야 합니다.

큰 미리보기

13. display: inline-block

둘 이상의 요소를 display: inline-block 또는 display: inline 은 각 요소 사이에 작은 공간을 만듭니다. 브라우저가 요소를 단어로 해석하기 때문에 공백이 추가되고 각 요소 사이에 문자 공백이 추가됩니다.

아래 예에서 각 항목의 오른쪽에는 8px 의 공간이 있지만 display: inline-block 을 사용하여 발생하는 작은 공간은 12px 로 만들어 원하는 결과가 아닙니다.

 li:not(:last-child) { margin-right: 8px; } 
(큰 미리보기)

이에 대한 간단한 수정은 부모 요소에 font-size: 0 을 설정하는 것입니다.

 ul { font-size: 0; } li { font-size: 16px; /*The font size should be reassigned here because it will inherit `font-size: 0` from its parent.*/ } 
(큰 미리보기)

CodePen에서 Ahmad Shadeed(@shadeed)의 Pen Inline Block Spacing을 참조하십시오.

CodePen에서 Ahmad Shadeed(@shadeed)의 Pen Inline Block Spacing을 참조하십시오.

14. 레이블 요소를 입력에 할당할 때 for="ID" 추가

양식 요소로 작업할 때 모든 label 요소에 할당된 ID가 있는지 확인하십시오. 이렇게 하면 더 쉽게 액세스할 수 있으며 클릭하면 연결된 입력에 포커스가 맞춰집니다.

 <label for="emailAddress">Email address:</label> <input type="email"> 
큰 미리보기

15. 대화형 HTML 요소와 작동하지 않는 글꼴

전체 문서에 글꼴을 할당할 때 input , button , selecttextarea 와 같은 요소에는 글꼴이 적용되지 않습니다. 브라우저가 기본 시스템 글꼴을 적용하기 때문에 기본적으로 상속하지 않습니다.

이 문제를 해결하려면 font 속성을 수동으로 할당하십시오.

 input, button, select, textarea { font-family: your-awesome-font-name; }

16. 수평 스크롤 바

일부 요소의 경우 해당 요소의 너비로 인해 가로 스크롤 막대가 나타납니다.

이 문제의 원인을 찾는 가장 쉬운 방법은 CSS 개요를 사용하는 것입니다. Addy Osmani는 페이지의 모든 요소를 ​​요약하기 위해 브라우저 콘솔에 추가할 수 있는 매우 편리한 스크립트를 공유했습니다.

 [].forEach.call($$("*"), function(a) { a.style.outline = "1px solid #" + (~~(Math.random() * (1 << 24))).toString(16); }); 
(큰 미리보기)

17. 압축되거나 늘어난 이미지

CSS에서 이미지의 크기를 조정할 때 가로 세로 비율이 이미지의 너비 및 높이와 일치하지 않으면 이미지가 압축되거나 늘어날 수 있습니다.

해결책은 간단합니다. CSS의 object-fit 사용하십시오. 그 기능은 background-size: cover 의 기능과 유사합니다.

 img { object-fit: cover; } 
(큰 미리보기)

object-fit 을 사용하는 것이 모든 경우에 완벽한 솔루션은 아닙니다. 일부 이미지는 자르기 또는 크기 조정 없이 나타나야 하며 일부 플랫폼에서는 사용자가 정의된 크기로 이미지를 업로드하거나 자르도록 강제합니다. 예를 들어 Dribbble은 800 x 600 픽셀의 썸네일 업로드를 허용합니다.

18. input 에 대한 올바른 type 을 추가합니다.

input 필드에 올바른 type 을 사용하십시오. 이렇게 하면 모바일 브라우저의 사용자 경험이 향상되고 사용자가 더 쉽게 액세스할 수 있습니다.

다음은 일부 HTML입니다.

 <form action=""> <p> <label for="name">Full name</label> <input type="text" id="name"> </p> <p> <label for="email">Email</label> <input type="email" id="email"> </p> <p> <label for="phone">Phone</label> <input type="tel" id="phone"> </p> </form>

초점이 맞춰지면 각 입력이 다음과 같이 표시됩니다.

(큰 미리보기)

19. RTL 레이아웃의 전화번호

+ 972-123555777 과 같은 전화번호를 오른쪽에서 왼쪽 레이아웃으로 추가하면 더하기 기호가 번호 끝에 위치하게 됩니다. 이 문제를 해결하려면 전화번호의 방향을 다시 지정하세요.

 p { direction: ltr; } 
(큰 미리보기)

결론

여기에 언급된 모든 문제는 프론트 엔드 개발 작업에서 직면한 가장 일반적인 문제 중 하나입니다. 내 목표는 웹 프로젝트에서 작업하는 동안 정기적으로 확인할 목록을 유지하는 것입니다.

CSS에서 항상 직면하는 문제가 있습니까? 댓글로 알려주세요!