Font scaling based on width of container

后端 未结 30 3038
面向向阳花
面向向阳花 2020-11-21 04:35

I\'m having a hard time getting my head around font scaling.

I currently have a website with a body font-size of 100%. 100% of what though? This seems t

相关标签:
30条回答
  • 2020-11-21 05:13

    I've prepared a simple scale function using CSS transform instead of font-size. You can use it inside of any container, you don't have to set media queries, etc. :)

    Blog post: Full width CSS & JS scalable header

    The code:

    function scaleHeader() {
      var scalable = document.querySelectorAll('.scale--js');
      var margin = 10;
      for (var i = 0; i < scalable.length; i++) {
        var scalableContainer = scalable[i].parentNode;
        scalable[i].style.transform = 'scale(1)';
        var scalableContainerWidth = scalableContainer.offsetWidth - margin;
        var scalableWidth = scalable[i].offsetWidth;
        scalable[i].style.transform = 'scale(' + scalableContainerWidth / scalableWidth + ')';
        scalableContainer.style.height = scalable[i].getBoundingClientRect().height + 'px';
      }
    }
    

    Working demo: https://codepen.io/maciejkorsan/pen/BWLryj

    0 讨论(0)
  • 2020-11-21 05:13

    My problem was similar, but related to scaling text within a heading. I tried Fit Font, but I needed to toggle the compressor to get any results, since it was solving a slightly different problem, as was Text Flow.

    So I wrote my own little plugin that reduced the font size to fit the container, assuming you have overflow: hidden and white-space: nowrap so that even if reducing the font to the minimum doesn't allow showing the full heading, it just cuts off what it can show.

    (function($) {
    
      // Reduces the size of text in the element to fit the parent.
      $.fn.reduceTextSize = function(options) {
        options = $.extend({
          minFontSize: 10
        }, options);
    
        function checkWidth(em) {
          var $em = $(em);
          var oldPosition = $em.css('position');
          $em.css('position', 'absolute');
          var width = $em.width();
          $em.css('position', oldPosition);
          return width;
        }
    
        return this.each(function(){
          var $this = $(this);
          var $parent = $this.parent();
          var prevFontSize;
          while (checkWidth($this) > $parent.width()) {
            var currentFontSize = parseInt($this.css('font-size').replace('px', ''));
            // Stop looping if min font size reached, or font size did not change last iteration.
            if (isNaN(currentFontSize) || currentFontSize <= options.minFontSize ||
                prevFontSize && prevFontSize == currentFontSize) {
              break;
            }
            prevFontSize = currentFontSize;
            $this.css('font-size', (currentFontSize - 1) + 'px');
          }
        });
      };
    })(jQuery);
    
    0 讨论(0)
  • 2020-11-21 05:14

    I don't see any answer with reference to CSS flex property, but it can be very useful too.

    0 讨论(0)
  • 2020-11-21 05:17

    My own solution, jQuery-based, works by gradually increasing the font size until the container gets a big increase in height (meaning it got a line break).

    It's pretty simple, but works fairly well, and it is very easy to use. You don't have to know anything about the font being used, everything is taken care of by the browser.

    You can play with it on http://jsfiddle.net/tubededentifrice/u5y15d0L/2/

    The magic happens here:

    var setMaxTextSize=function(jElement) {
        // Get and set the font size into data for reuse upon resize
        var fontSize=parseInt(jElement.data(quickFitFontSizeData)) || parseInt(jElement.css("font-size"));
        jElement.data(quickFitFontSizeData, fontSize);
    
        // Gradually increase font size until the element gets a big increase in height (i.e. line break)
        var i = 0;
        var previousHeight;
        do
        {
            previousHeight=jElement.height();
            jElement.css("font-size", "" + (++fontSize) + "px");
        }
        while(i++ < 300 && jElement.height()-previousHeight < fontSize/2)
    
        // Finally, go back before the increase in height and set the element as resized by adding quickFitSetClass
        fontSize -= 1;
        jElement.addClass(quickFitSetClass).css("font-size", "" + fontSize + "px");
    
        return fontSize;
    };
    
    0 讨论(0)
  • 2020-11-21 05:17

    Take look at my code. It makes the font size smaller to fit whatever there.

    But I think this doesn't lead to a good user experience

    var containerWidth = $("#ui-id-2").width();
    var items = $(".quickSearchAutocomplete .ui-menu-item");
    var fontSize = 16;
    
    items.each(function(){
        // Displaying a value depends sometimes on your case. You may make it block or inline-table instead of inline-block or whatever value that make the div take overflow width.
        $(this).css({"whiteSpace": "nowrap", "display": "inline-block"});
        while ($(this).width() > containerWidth){
             console.log("$(this).width()" + $(this).width() + "containerWidth" + containerWidth)
             $(this).css("font-size", fontSize -= 0.5);
        }
    });
    

    0 讨论(0)
  • 2020-11-21 05:18

    100% is relative to the base font size, which, if you haven't set it, would be the browser's user-agent default.

    To get the effect you're after, I would use a piece of JavaScript code to adjust the base font size relative to the window dimensions.

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