CSS: bolding some text without changing its container's size

后端 未结 11 1146
生来不讨喜
生来不讨喜 2020-11-29 16:55

I have a horizontal navigation menu, which is basically just a

    with the elements set side-by-side. I do not define width, but simply use padding, bec
相关标签:
11条回答
  • 2020-11-29 17:49

    Interesting question. I suppose you are using float, right?

    Well, I don't know any technique you can use to get rid of this font enlarging, hence they will try to fit in the minimum width required - and varying font thickness will change this value.

    The unique solution I know to avoid this changing is one you said you don't want: setting fixed sizes to li's.

    0 讨论(0)
  • 2020-11-29 17:50

    UPDATE: Had to use the B tag for the title because in IE11 the pseudo class i:after didn't show when i had visibility:hidden.

    In my case I want to align a (custom designed) input checkbox/radio with label text where the text goes bold when the input is checked.

    The solution provided here did not work for me in Chrome. The vertical alignment of input and label got messed up with the :after psuedo class and -margins did not fix this.

    Here is a fix where you don't get trouble with vertical alignments.

    /* 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>

    0 讨论(0)
  • 2020-11-29 17:51

    The most portable and visually pleasing solution would be to use text-shadow. This revises and shows examples of Thorgeir's answer using Alexxali's and my own tweaks:

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

    This puts tiny "shadows" in black (use your font's color name/code in place of black if necessary) on both sides of each letter using units that will scale properly with font rendering.

    warning Warning: px values do support decimal values, but they won't look so great when the font size changes (e.g. the user scales the view with Ctrl++). Use relative values instead.

    This answer uses fractions of ex units since they scale with the font.
    In ~most browser defaults*, expect 1ex8px and therefore 0.025ex0.1px.

    See for yourself:

    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>

    Hover over the rendered lines to see how they differ from standard text.

    Alter your browser's zoom level (Ctrl++ and Ctrl+-) to see how they vary.

    I added two other solutions here for comparison: @cgTag's letter spacing trick, which doesn't work so well since it involves guessing font width ranges, and @workaholic_gangster911's ::after drawing trick, which leaves awkward extra space so the bold text can expand without nudging neighboring text items (I put the attribution after the bold text so you can see how it does not move).


    In the future, we'll have more variable fonts capable of things like changing font grade via font-variation-settings. Browser support is ramping up (Chrome 63+, Firefox 62+) but this still requires more than just standard fonts and few existing fonts support it.

    If you embed a variable font, you'll be able to use CSS like this:

    /* 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; }
    }
    

    There is a live demo with a slider to play with various grades on the Mozilla Variable Fonts Guide. Google's Introduction to variable fonts on the web has an animated GIF demonstrating a toggle between a high grade and no grade:

    animated Amstelvar Alpha font demo with toggling grade axis

    0 讨论(0)
  • 2020-11-29 17:55

    I had the same problem, but got a similar effect with a little compromise, I used text-shadow instead.

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

    Here's a working example:

    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 example

    0 讨论(0)
  • 2020-11-29 17:57

    I found that most fonts are the same size when you adjust letter spacing by 1px.

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

    While this does change the regular font so that each letter has an extra pixel spacing. For menus the titles are so short it doesn't present as a problem.

    0 讨论(0)
提交回复
热议问题