Inline-block line-wrap extra space

前端 未结 4 1910
无人及你
无人及你 2020-12-14 19:15

I\'ve got an inline-block element that contains a very long word. When I resize the viewport until I reach the breakpoint of the text wrapping to the next line, I get a subs

相关标签:
4条回答
  • 2020-12-14 19:56

    I don't think this is possible only with CSS for the one element. The reason for your behavior is that the width of the element is still 100% of its container. The only way I could think to accomplish this is by doing something a little bit "creative"...try setting the style to inline so you get the shrink-wrap behavior, but to get around the background color issue, also put it in a container that shares the same background. That should work.

    0 讨论(0)
  • 2020-12-14 19:56

    If im understanding you correctly you could use the @media type to decide what css to use depending on the width of the screen

    here is an example of what i mean

    @media(min-width:0px) and (max-width:200px){
        div {
        display: block;
        background-color: black;
        color: white;
        padding: 5px;
        }
    }
    @media (min-width:200px){
        div {
        display: inline-block;
        background-color: black;
        color: white;
        padding: 5px;
        }
    }
    
    0 讨论(0)
  • 2020-12-14 20:15

    I am still very appreciative of @lapin's answer (which I accepted and awarded bounty to), I found out after the fact that it didn't quite work on multiple elements next to each other (that has nothing to do with @lapin, I just didn't mention it in my original question as I thought it would be irrelevant information).

    Anyway, I've come up with the following that works for me (assuming the elements it should be applied to are .title and .subtitle):

    $('.title, .subtitle').each(function(i, el) {
        var el = $(el),
            inner = $(document.createElement('span')),
            bar = $(document.createElement('span'));
    
        inner.addClass('inner');
        bar.addClass('bar');
    
        el.wrapInner(inner)
            .append(bar)
            .css({
                backgroundColor: 'transparent'
            });
    });
    
    function shrinkWrap() {
        $('.title, .subtitle').each(function(i, el) {
            var el = $(el),
                inner = $('.inner', el),
                bar = $('.bar', el),
                innerWidth = inner.width();
    
            bar.css({
                bottom: 0,
                width: innerWidth + parseFloat(el.css('paddingLeft')) + parseFloat(el.css('paddingRight'))
            });
        });
    }
    shrinkWrap();
    
    $(window).on('resize', function() {
        shrinkWrap();
    });
    

    Basically what I do is:

    1. put the text in an inner wrap element
    2. create an additional absolutely-positioned background element
    3. get the width of the inline inner wrap element
    4. apply said width to the background element (plus padding and whatnot)

    The CSS:

    .title, .subtitle {
        position: relative;
        z-index: 500;
        display: table;
        padding-left: 10px;
        margin-right: 10px;
        background-color: red;
    }
    
    .title .bar, .subtitle .bar {
        position: absolute;
        top: 0;
        left: 0;
        bottom: 0;
        z-index: -10;
        background-color: red;
    }
    
    0 讨论(0)
  • 2020-12-14 20:19

    The inline-block indeed extends on resizing as your animation shows, so that it keeps place for the long word to go into that space again.

    One simple solution would be to add text-align: justify, but I'm afraid it may not exactly be what you want (see demo).

    Another one would be the use of media queries, as @Parody suggested, but you would have to know the dimentions of the containing div, and that would not be very scalable as you mentionned.

    The word-break: break-all suggested by @yugi also works but causes the words to to collapse letter by letter, regardless of their length.

    The only way to achieve the exact behavior is (as far as I know) to use javascript. For example, you would have to wrap your text into a span element inside the div, and then add something like this :

    var paddingLeft = parseInt($('#foo').css('padding-left')),
        paddingRight = parseInt($('#foo').css('padding-left')),
        paddingTop = parseInt($('#foo').css('padding-top')),
        paddingBottom = parseInt($('#foo').css('padding-Bottom')),
        cloned = $('#foo span').clone(),
        cloned_wrap = document.createElement('div');
    
    $(cloned_wrap).css({
        paddingLeft : paddingLeft,
        paddingRight : paddingRight,
        display : 'inline-block',
        visibility: 'hidden',
        float: 'left',
    });
    
    $(cloned_wrap).insertAfter('#foo');
    cloned.appendTo(cloned_wrap);
    
    $(window).on('resize', function(){
        $('#foo').css('width', cloned.width() + 1);
        $(cloned_wrap).css('margin-top',- $('#foo').height() - paddingTop - paddingBottom);
    }).resize();
    

    Please see the jsfiddle working demo. (← edited many times)

    That's quite a lot of code, but it works ; )

    (PS : I assumed jquery was available, if not, quite the same is achievable in pure JS)

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