CSS : 컨테이너 크기를 변경하지 않고 일부 텍스트를 굵게 표시


119

기본적으로 <ul>요소가 나란히 설정된 가로 탐색 메뉴가 있습니다. 너비를 정의하지 않고 단순히 패딩을 사용합니다. 너비가 메뉴 항목의 너비로 정의되기를 원하기 때문입니다. 현재 선택된 항목을 굵게 표시합니다.

문제는 굵게 표시하면 단어가 약간 더 넓어지고 나머지 요소가 왼쪽이나 오른쪽으로 약간 이동한다는 것입니다. 이런 일이 발생하지 않도록하는 현명한 방법이 있습니까? 굵은 글씨로 인한 추가 너비를 무시하도록 패딩에 지시하는 내용이 있습니까? 내 첫 번째 생각은 단순히 "활성"요소의 패딩에서 몇 픽셀을 빼는 것이었지만이 양은 다양합니다.

가능한 경우 각 항목에 정적 너비를 설정 한 다음 현재 가지고있는 패딩 솔루션과 반대로 중앙에 배치하는 것을 피하고 싶습니다. 나중에 항목을 간단하게 변경할 수 있습니다.


크기 변경이 문제가되는 이유는 무엇입니까? 어떻게 든 레이아웃이 엉망입니까?
— Chaulky 2011

웹 프로그래밍 질문은 Stack Overflow에서 가장 잘 묻는 것 같습니다. 아마도 모드가 이것을 그곳으로 마이그레이션 할 것입니다.
— Ciaran 2011

2
Chaulky : 버튼을 클릭해야 할 때보 다 레이아웃 측면에서 더 싫어하는 것이 거의 없기 때문에
— Mala

doejo.com/blog/… 는 John과 Blowski가 jscript에 대해 말한 것과 정확히 일치하는 솔루션 중 하나입니다.
— thebulfrog

답변:


152

나는 같은 문제가 있었지만 약간의 타협으로 비슷한 효과를 얻었고 대신 텍스트 그림자를 사용했습니다.

li:hover {text-shadow:0px 0px 1px black;}

다음은 작동하는 예입니다.

body {
  font-family: segoe ui;
}

ul li {
  display: inline-block;
  border-left: 1px solid silver;
  padding: 5px
}

.textshadow :hover {
  text-shadow: 0px 0px 1px black;
}

.textshadow-alt :hover {
  text-shadow: 1px 0px 0px black;
}

.bold :hover {
  font-weight: bold;
}
<ul class="textshadow">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li><code>text-shadow: 0px 0px 1px black;</code></li>
</ul>

<ul class="textshadow-alt">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li><code>text-shadow: 1px 0px 0px black;</code></li>
</ul>

<ul class="bold">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li><code>font-weight: bold;</code></li>
</ul>

jsfiddle 예


51
이 솔루션을 좋아하지만 1px 0px 0px로 전환하는 것이 좋습니다. 좀 더 대담 해 보입니다.
— M. Herold 2013 년

CSS 전용 솔루션이 필요했고 이것이 답입니다.
— JCasso 2013 년

당신의 진짜 천재! 단순함은 그것을 끔찍하게 만듭니다!
— lufi

1
추가 li:hover {text-shadow: 1px 0 0 black;}만하면 글자 사이의 간격이 너무 적은 텍스트가 생성됩니다. 이를 다시 개선하기 위해 우리는 또한 설정했습니다li {letter-spacing: 1px;}
— Patrick Hammer

5
-0.5px 0 #fff, 0.5px 0 #fff텍스트 자체와 그림자 사이의 작은 간격을 볼 수 있었기 때문에를 사용했습니다 . 또한 텍스트가 굵게 표시되면 양쪽에 가중치가 추가됩니다.
— atorscho

101

:: after를 사용한 최상의 작업 솔루션

HTML

<li title="EXAMPLE TEXT">
  EXAMPLE TEXT
</li>

CSS

li::after {
  display: block;
  content: attr(title);
  font-weight: bold;
  height: 1px;
  color: transparent;
  overflow: hidden;
  visibility: hidden;
}

title속성에 의해 제공되는 굵은 텍스트 너비의 보이지 않는 의사 요소를 추가 합니다.

그만큼 text-shadow 솔루션은 Mac에서 부 자연스럽게 보이며 Mac에서 텍스트 렌더링이 제공하는 모든 아름다움을 활용하지 않습니다 .. :)

http://jsfiddle.net/85LbG/

크레딧 : https://stackoverflow.com/a/20249560/5061744


11
이것은 가장 안정적이고 깨끗한 솔루션이며 요소에서 굵은 텍스트를위한 공간을 예약합니다. 제 경우에는 추가 의사 요소로 인해 높이가 변경되었습니다. 블록에 음수 margin-top를 추가하면 ::after문제가 해결되었습니다.
— Vaclav Novotny

2
이 솔루션은 훌륭합니다! HTML을 변경하지 않도록 JS를 사용하여 요소의 텍스트를 포함하는 "data-content"속성을 추가했습니다.
— mistykristie 18:57에

1
대박. 이것이 최선의 답이 될 것입니다. li와 다른 요소가 있으면 display : block을 사용해야 할 수도 있습니다. : after 부모 요소.
— Blackbam

훌륭한 솔루션! :: before에서도 잘 작동합니다. 제 경우에는 하단에 추가 여백을 방지합니다.
— Thomas Champion

이 솔루션에 감사드립니다. 처음에는 text-shadow를 사용했지만 십진수 값을 반올림하기 때문에 Safari에서는 작동하지 않습니다. 0.1px를 사용했기 때문에 이것은 0으로 반올림되었습니다. 귀하의 솔루션은 완벽하게 작동했습니다. 내가 표시하는 툴팁을 원하지 않았다 나는 단지 이름이 제목 속성을 대체
— 조나단 Cardoz을

32

가장 휴대 가능하고 시각적으로 만족스러운 솔루션은를 사용하는 것 text-shadow입니다. 이것은 Alexxali 와 내 자신의 조정을 사용하여 Thorgeir의 답변의 예를 수정하고 보여줍니다 .

  li:hover { text-shadow: -0.06ex 0 black, 0.06ex 0 black; }

이렇게 black하면 글꼴 렌더링과 함께 적절하게 크기가 조정되는 단위를 사용하여 각 문자의 양쪽 에 작은 "그림자"가 검은 색 ( 필요한 경우 대신 글꼴의 색상 이름 / 코드 사용)으로 표시됩니다.

경고 경고 : px 값은 십진수 값을 지원하지만 글꼴 크기가 변경 될 때 (예 : 사용자가 Ctrl++ . 대신 상대 값을 사용하십시오.

이 답변은 ex글꼴에 따라 크기가 조정되므로 단위의 분수를 사용합니다 .
~ 대부분의 브라우저 기본값 * 에서 1ex≈을 예상 8px하므로 0.025ex≈ 0.1px.

직접 확인 :

li             { color: #000; } /* set text color just in case */
.shadow0       { text-shadow: inherit; }
.shadow2       { text-shadow: -0.02ex 0 #000, 0.02ex 0 #000; }
.shadow4       { text-shadow: -0.04ex 0 #000, 0.04ex 0 #000; }
.shadow6       { text-shadow: -0.06ex 0 #000, 0.06ex 0 #000; }
.shadow8       { text-shadow: -0.08ex 0 #000, 0.08ex 0 #000; }
.bold          { font-weight: bold; }
.bolder        { font-weight: bolder; }
.after span        { display:inline-block; font-weight: bold; } /* workaholic… */
.after:hover span  { font-weight:normal; }
.after span::after { content: attr(title); font-weight: bold; display:block; 
                     height: 0; overflow: hidden; }
.ltrsp         { letter-spacing:0; font-weight:bold; } /* @cgTag */
li.ltrsp:hover { letter-spacing:0.0125ex; }
li:hover       { font-weight: normal!important; text-shadow: none!important; }
<li class="shadow0">MmmIii123 This line tests shadow0 (plain)</li>
<li class="shadow2">MmmIii123 This line tests shadow2 (0.02ex)</li>
<li class="shadow4">MmmIii123 This line tests shadow4 (0.04ex)</li>
<li class="shadow6">MmmIii123 This line tests shadow6 (0.06ex)</li>
<li class="shadow8">MmmIii123 This line tests shadow8 (0.08ex)</li>
<li class="after"><span title="MmmIii123 This line tests [title]"
                   >MmmIii123 This line tests [title]</span> (@workaholic…)</li>
<li class="ltrsp"  >MmmIii123 This line tests ltrsp (@cgTag)</li>
<li class="bold"   >MmmIii123 This line tests bold</li>
<li class="bolder" >MmmIii123 This line tests bolder</li>
<li class="shadow2 bold">MmmIii123 This line tests shadow2 (0.02ex) + bold</li>
<li class="shadow4 bold">MmmIii123 This line tests shadow4 (0.04ex) + bold</li>
<li class="shadow6 bold">MmmIii123 This line tests shadow6 (0.06ex) + bold</li>
<li class="shadow8 bold">MmmIii123 This line tests shadow8 (0.08ex) + bold</li>

렌더링 된 선 위로 마우스를 가져 가면 표준 텍스트와 어떻게 다른지 확인할 수 있습니다.

브라우저의 확대 / 축소 수준 변경 ( Ctrl+ +및 Ctrl+- )을 차이를 확인합니다.

비교를 위해 여기에 두 가지 다른 솔루션을 추가했습니다 : @cgTag의 글자 간격 트릭 ( 글꼴 너비 범위 추측과 관련이 있기 때문에 잘 작동하지 않음)과 @ workaholic_gangster911의 :: after drawing 트릭 ( 굵은 텍스트가 확장 될 수 있도록 어색한 추가 공간을 남깁니다) 인접한 텍스트 항목을 뉘우 치지 않고 (저는 굵은 텍스트 뒤에 속성을 넣어서 어떻게 움직이지 않는지 볼 수 있습니다).


미래에, 우리는 더 할 것이다 변수 글꼴 변경 같은 것들을 할 수있는 글꼴 등급을 통해를 font-variation-settings. 브라우저 지원 이 증가하고 있지만 (Chrome 63+, Firefox 62+) 여전히 표준 글꼴 이상이 필요하며이를 지원하는 기존 글꼴은 거의 없습니다.

가변 글꼴을 삽입하면 다음과 같이 CSS를 사용할 수 있습니다.

/* Grade: Increase the typeface's relative weight/density */
@supports (font-variation-settings: 'GRAD' 150) {
  li:hover { font-variation-settings: 'GRAD' 150; }
}
/* Failover for older browsers: tiny shadows at right & left of the text
 * (replace both instances of "black" with the font color) */
@supports not (font-variation-settings: 'GRAD' 150) {
  li:hover { text-shadow: -0.06ex 0 black, 0.06ex 0 black; }
}

Mozilla Variable Fonts Guide에 다양한 등급으로 플레이 할 수있는 슬라이더 가있는 라이브 데모 가 있습니다. 웹의 가변 글꼴에 대한 Google의 소개 에는 높은 등급과 등급 없음 사이의 전환을 보여주는 애니메이션 GIF가 있습니다.

등급 축을 토글하는 애니메이션 Amstelvar Alpha 글꼴 데모


1
너무 간단하고 아름답습니다.
— Randy Hall

18

문자 간격을 1px로 조정하면 대부분의 글꼴이 같은 크기라는 것을 알았습니다.

a {
   letter-spacing: 1px;
}

a:hover {
   font-weight: bold;
   letter-spacing: 0px;
}

이렇게하면 일반 글꼴이 변경되어 각 문자에 추가 픽셀 간격이 있습니다. 메뉴의 경우 제목이 너무 짧아서 문제가되지 않습니다.


3
이것이 가장 좋고 가장 과소 평가 된 솔루션이지만 0으로 시작하고 굵게 표시되면 음수 문자 간격으로 이동하도록 변경했습니다. 또한 각 글꼴 및 글꼴 크기에 대해 미세 조정해야합니다. 나는 또한 (2 솔루션)이 포함되도록 Thorgeir의 바이올린 @ 업데이트 jsfiddle.net/dJcPn/50/
— robotik

최신 브라우저는 이제 하위 픽셀 정확도를 지원합니다. 따라서 0.98px또는 더 작은 분수를 사용하여 간격을 미세 조정할 수 있습니다 .
— Reactgular

간격 알고리즘이 정확히 동일하지 않기 때문에 약간 이상해 보입니다 (일부 글자가 약간 춤추고 있음). 더 중요한 것은 글꼴 크기를 조정할 때 또는 1px같은 상대 값으로 변환하더라도 작동하지 않기 때문 입니다. 라이브 데모에 대한 내 대답 을 참조하십시오 . 0.025ex0.0125ex
— Adam Katz 2017

@AdamKatz이 답변이 게시 된 이후로 글꼴 렌더링이 변경된 것으로 의심되며 사용중인 글꼴에 따라 많이 달라집니다.
— Reactgular

5

최신 답변을 보려면 다음을 사용할 수 있습니다 -webkit-text-stroke-width.

.element {
  font-weight: normal;
}

.element:hover {
  -webkit-text-stroke-width: 1px;
  -webkit-text-stroke-color: black;
}

이렇게하면 가상 요소 (화면 판독기의 장점)와 텍스트 그림자 (지저분 해 보이지만 여전히 약간의 '점프'효과를 생성 할 수 있음) 또는 고정 너비 설정 (비실용적 일 수 있음)을 피할 수 있습니다.

또한 요소를 1px보다 굵게 설정할 수 있습니다 (이론적으로 글꼴을 원하는대로 굵게 만들 수 있으며 굵게 표시되지 않은 글꼴의 굵은 버전을 만들기위한 조잡한 운동이 될 수도 있습니다. 사용자 정의 글꼴과 같은 변형 ( 편집 : 가변 글꼴은이 제안을 평가하지 않음). 일부 글꼴이 긁히고 들쭉날쭉하게 보이기 때문에 피해야합니다.)

나는 Edge, Firefox, Chrome 및 Opera (게시 시점) 와 Safari ( 편집 : @Lars Blumberg를 확인해 주셔서 감사 합니다)에서 확실히 작동합니다 . IE11 이하에서는 작동하지 않습니다.

또한 -webkit접두사를 사용 하므로 이는 표준이 아니며 향후 지원이 중단 될 수 있으므로 굵게 표시되는 것이 정말 중요합니다. 단순히 미적인 경우가 아니라면이 기술을 피하는 것이 가장 좋습니다.


1
Safari 13.0.5에서도 작동합니다. 지금까지 나를위한 가장 깨끗한 솔루션.
— Lars Blumberg

4

안타깝게도 텍스트가 굵게 표시 될 때 너비가 변경되는 것을 방지하는 유일한 방법은 목록 항목의 너비를 정의하는 것입니다. 그러나 수동으로 이렇게하는 것은 시간이 많이 걸리고 확장 할 수 없습니다.

내가 생각할 수있는 유일한 것은 탭이 굵게 표시되기 전에 탭의 너비를 계산 한 다음 굵게 표시되는 동시에 너비를 적용하는 자바 스크립트를 사용하는 것뿐입니다 (마우스 오버하거나 클릭 할 때).


음, JS가 아닌 사용자에게는 적어도 합리적으로 보이기를 원하지만 (즉, 굵게) 이것을 실험 해 볼 것입니다. 굵게 표시하고 JS를 사용하여 굵게 표시하고 너비를 계산 한 다음 다시 굵게 표시 할 수 있습니까? 아니면 그냥 어리석은가요?
— Mala

예, 비 자바 스크립트 사용자를 수용하는 가장 좋은 방법 인 것 같습니다.
— ajcw 2011

2

자바 스크립트를 사용하여 굵게 표시 되지 않은 콘텐츠를 기반으로 li의 고정 너비를 설정 한 다음 <a>태그에 스타일을 적용하여 콘텐츠를 굵게 표시합니다 (또는에 <li>자식이없는 경우 범위를 추가 ).


죄송합니다-반복해서 죄송합니다 : $
— Dan Blows

어쨌든 답변 주셔서 감사합니다 :)
— Mala

@Mala 해결책을 찾았습니까? 재미있게도 비슷한 문제가 있습니다.
— Dan Blows 2011

1

이것은 매우 오래된 질문이지만 제가 개발중인 앱에이 문제가 있었고 여기에서 원하는 모든 답변을 찾았 기 때문에 다시 검토하고 있습니다.

(TL; DR에 대해서는이 단락을 건너 뛰십시오 ...)cloud.typography.com의 Gotham 웹 폰트를 사용하고 있으며 비어있는 버튼 (흰색 테두리 / 텍스트 및 투명한 배경)으로 시작하고 마우스 오버시 배경색을 얻는 버튼이 있습니다. 사용하던 배경색 중 일부가 흰색 텍스트와 잘 대조되지 않았기 때문에 해당 버튼의 텍스트를 검은 색으로 변경하고 싶었지만 시각적 트릭이나 일반적인 앤티 앨리어싱 방법으로 인해 어두운 밝은 배경의 텍스트는 항상 어두운 배경의 흰색 텍스트보다 더 가벼운 것처럼 보입니다. 어두운 텍스트의 가중치를 400에서 500으로 늘리면 거의 동일한 "시각적"가중치가 유지된다는 것을 알았습니다. 그러나 버튼 너비를 픽셀의 일부로 조금씩 늘 렸지만 버튼이 약간 "떨리는"것처럼 보이게하는 것으로 충분했습니다. 제가 제거하고 싶었습니다.

해결책:

분명히 이것은 매우 까다로운 문제이므로 까다로운 솔루션이 필요했습니다. 궁극적 letter-spacing으로 위에서 권장 한 cgTag와 같이 굵은 텍스트에 네거티브 를 사용 했지만 1px는 너무 과도했을 것이므로 정확히 필요한 너비를 계산했습니다.

Chrome devtools의 버튼을 검사 한 결과 내 버튼의 기본 너비는 165.47px이고 호버시 165.69px로 0.22px의 차이를 나타 냈습니다. 버튼에는 9 개의 문자가 포함되어 있습니다.

0.22 / 9 = 0.024444px

이를 em 단위로 변환하면 조정 글꼴 크기를 알 수 없습니다. 내 버튼은 16px의 글꼴 크기를 사용했습니다.

0.024444 / 16 = 0.001527em

따라서 내 특정 글꼴의 경우 다음 CSS는 버튼 을 마우스 오버시 정확히 동일한 너비로 유지합니다 .

.btn {
  font-weight: 400;
}

.btn:hover {
  font-weight: 500;
  letter-spacing: -0.001527em;
}

약간의 테스트와 위의 공식을 사용하면 letter-spacing상황에 맞는 정확한 값을 찾을 수 있으며 글꼴 크기에 관계없이 작동합니다.

한 가지주의 할 점은 브라우저마다 약간 다른 하위 픽셀 계산을 사용하므로이 OCD 수준의 하위 픽셀 완벽 정밀도를 목표로하는 경우 테스트를 반복하고 각 브라우저에 대해 다른 값을 설정해야합니다. 브라우저를 대상으로하는 CSS 스타일은 일반적으로별로 눈살을 찌푸 리지만 타당한 이유가있는 유일한 사용 사례라고 생각합니다.


0

흥미로운 질문입니다. 나는 당신이 float를 사용하고 있다고 생각합니다.

글쎄, 나는이 글꼴 확대를 제거하는 데 사용할 수있는 기술을 알지 못하므로 필요한 최소 너비에 맞추려고 노력할 것이며 글꼴 두께를 변경하면이 값이 변경됩니다.

이 변경을 피하기 위해 내가 아는 유일한 해결책은 당신이 원하지 않는다고 말한 것입니다 : 고정 크기를 li로 설정하십시오.


0

amazon.com "부서별 쇼핑"호버 메뉴처럼이를 구현할 수 있습니다. 넓은 div를 사용합니다. 넓은 div를 만들고 오른쪽 부분을 숨길 수 있습니다.


0

업데이트 : IE11에서 내가 가시성을 가질 때 의사 클래스 i : after가 표시되지 않았기 때문에 제목에 B 태그를 사용해야했습니다. 숨김.

제 경우에는 입력이 선택되었을 때 텍스트가 굵게 표시되는 레이블 텍스트와 함께 (사용자 정의 디자인 된) 입력 확인란 / 라디오를 정렬하고 싶습니다.

여기에 제공된 솔루션은 Chrome에서 작동하지 않았습니다. 입력과 레이블의 수직 정렬이 : after psuedo 클래스로 엉망이되었고 -margins는 이것을 수정하지 않았습니다.

다음은 수직 정렬에 문제가없는 수정 사항입니다.

/* checkbox and radiobutton */
label
{
    position: relative;
    display: inline-block;
    padding-left: 30px;
    line-height: 28px;
}

/* reserve space of bold text so that the container-size remains the same when the label text is set to bold when checked. */
label > input + b + i
{
    font-weight: bold;
    font-style: normal;
    visibility: hidden;
}

label > input:checked + b + i
{
    visibility: visible;
}

/* set title attribute of label > b */
label > input + b:after
{
    display: block;
    content: attr(title);
    font-weight: normal;
    position: absolute;
    left: 30px;
    top: -2px;
    visibility: visible;
}

label > input:checked + b:after
{
    display: none;
}

label > input[type="radio"],
label > input[type="checkbox"]
{
    position: absolute;
    visibility: hidden;
    left: 0px;
    margin: 0px;
    top: 50%;
    transform: translateY(-50%);
}

    label > input[type="radio"] + b,
    label > input[type="checkbox"]  + b
    {
        display: block;
        position: absolute;
        left: 0px;
        margin: 0px;
        top: 50%;
        transform: translateY(-50%);
        width: 24px;
        height: 24px;
        background-color: #00a1a6;
        border-radius: 3px;
    }

    label > input[type="radio"] + b
    {
        border-radius: 50%;
    }

    label > input:checked + b:before
    {
        display: inline-block;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%) rotate(45deg);
        content: '';
        border-width: 0px 3px 3px 0px;
        border-style: solid;
        border-color: #fff;
        width: 4px;
        height: 8px;
        border-radius: 0px;
    }

    label > input[type="checkbox"]:checked + b:before
    {
        transform: translate(-50%, -60%) rotate(45deg);
    }

    label > input[type="radio"]:checked + b:before
    {
        border-width: 0px;
        border-radius: 50%;
        width: 8px;
        height: 8px;
    }
<label><input checked="checked" type="checkbox"/><b title="Male"></b><i>Male</i></label>
<label><input type="checkbox"/><b title="Female"></b><i>Female</i></label>

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.