93

I want to remove the <br />'s and do the break lines through CSS. If I change the spans to display:block the width will go 100% and I need the width to be exactly the length of the text, like it is now. Any suggestions?

<div class="fullscreen">
    <p class="text">
        <span class="medium">We</span> <br />
        <span class="large">build</span> <br />
        <span class="medium">the</span> <br />
        <span class="large">Internet</span>
    </p>
</div>

.text span {
   background:rgba(165, 220, 79, 0.8);
   display:inline-block;
   padding:7px 10px;
   color:white;
}
.fullscreen .large {  font-size:80px }

Fidddle

ditto
  • 5,917
  • 10
  • 51
  • 88
  • 3
    X-Ref: [CSS to line break before/after a particular `inline-block` item](http://stackoverflow.com/q/4609279/367456) – hakre May 22 '14 at 10:26
  • 1
    `=ARRAYFORMULA(UNIQUE(TEXT(INDIRECT("A1:A"&COUNTA(A1:A)), "mmm-yyyy")))` - https://i.stack.imgur.com/lvbzL.png – player0 Sep 30 '19 at 22:18

7 Answers7

145

Remove all br tags and use display: table.

.text span {
   background: rgba(165, 220, 79, 0.8);
   display: table;
   padding: 7px 10px;
   color: white;
}
.fullscreen .large { font-size: 80px }

Explanation: The table wraps the width of its content by default without setting a width, but is still a block level element. You can get the same behavior by setting a width to other block-level elements:

<span style="display:block;border:1px solid red;width:100px;">Like a default table.</span>
<code>null</code>

Notice the <code> element doesn't flow inline with the <span> like it would normally. Check it out with the computed styles in your dev tools. You'll see pseudo margin to the right of the <span>. Anyway, this is the same as the table, but the table has the added benefit of always forming to the width of its content.

Modular
  • 6,440
  • 2
  • 35
  • 38
Devang Rathod
  • 6,650
  • 2
  • 23
  • 32
  • 9
    I think this answer is more relevant than the accepted answer. display: table acts as an inline-block element by being as wide as the content it contains, but also acts as a block element by adding a line break before AND after the element. Floats do not add a line break after the element. – Pascalculator Sep 11 '14 at 10:52
  • also it's useful to add border-collapse: separate; to have padding working – arekk Feb 19 '15 at 09:52
  • didn't seem to work for me in adding a line break between two `inline-block` elements setting both or either to `table` – David Apr 25 '16 at 23:29
  • 5
    `display: table;` carries behavior beyond line breaking that will probably break some css. I know `height` and `width` will not work – robisrob May 24 '17 at 15:37
  • 4
    This answer would benefit from more explanation. – Paul Rooney Jan 07 '18 at 23:34
  • 1
    @PaulRooney Just added the explanation to his question. – Modular Nov 09 '20 at 00:17
41

use float: left; and clear: left;

http://jsfiddle.net/rtM6J/

.text span {
   background: rgba(165, 220, 79, 0.8);
   float: left;
   clear: left;
   padding: 7px 10px;
   color: #fff;
}
Luca
  • 9,259
  • 5
  • 46
  • 59
  • 1
    because inline-block won't let the OP achieve what he wants, float:left still does what he was using inline-block for (make the element wrap the text instead of going full width). I could have left display: inline-block but float: left also invisibly sets display to block, a cleaner code is better than cluttered. I presume you didn't know this, reason why you decided to downvote. After all, my answer is one possible right answer (I'm sure there are other ways to achieve that), and does not cater for google indexing... – Luca May 22 '14 at 16:48
  • 1
    any floating sets to display: block. That's why I think that using float here when asked about inline-block is misleading. The downvote was, while searching for it, this got high ranking, however was not helpful. I thought my previous comment did explain that. Sorry if it was not clear. – hakre May 22 '14 at 20:18
  • 1
    @hakre - that's not quite correct. Since they're not in the same flow as the parent anymore, the block widths collapse as if they were display:inline-block, which is really all the OP wants. This worked well for me, solving the same problem. – Don McCurdy Jul 30 '15 at 21:01
  • 1
    @Luca Might also be worth pointing out that you may need a clearfix on the parent of the spans, like `.text { clear: left; overflow: auto; }`. – Don McCurdy Jul 30 '15 at 21:03
17

Set the items into display: inline and use :after:

.text span { display: inline }
.break-after:after { content: '\A'; white-space:pre; }

and add the class into your html spans:

<span class="medium break-after">We</span>
ET-CS
  • 6,334
  • 5
  • 43
  • 73
13

I think the best way to do this as of 2018 is to use flexbox.

.text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
/* same as original below */
.text span {
   background:rgba(165, 220, 79, 0.8);
   display:inline-block;
   padding:7px 10px;
   color:white;
}
.fullscreen .large {  font-size:80px }
<div class="fullscreen">
    <p class="text">
        <span class="medium">We</span> 
        <span class="large">build</span> 
        <span class="medium">the</span> 
        <span class="large">Internet</span>
    </p>
</div>
Will
  • 4,075
  • 1
  • 17
  • 28
  • Worked best for me. I needed to align items in left, center or right. So, I could use `align-items: flex-start`, `align-items: center` & `align-items: flex-end`. – Rehmat Apr 05 '19 at 04:54
12

Here is another solution (only relevant declarations listed):

.text span {
   display:inline-block;
   margin-right:100%;
}

When the margin is expressed in percentage, that percentage is taken from the width of the parent node, so 100% means as wide as the parent, which results in the next element getting "pushed" to a new line.

ultracrepidarian
  • 1,080
  • 11
  • 18
  • Not a part of the answer, but I thought some explanation would be appropriate. I wanted to style `
    ` blocks so that they had borders, were only as wide as the contents, but not wider than the parent node, and each appeared on a new line. For various reasons (I can elaborate if anyone is interested), none of the earlier solutions were satisfactory in my case, so I came up with my own. It looks good when the parent node has a limited width and `overflow: visible`; otherwise it can result in an unnecesary horizontal scrollbar or empty space.
    – ultracrepidarian Jan 26 '18 at 10:57
  • Couldn't make `text-align:center` to work on my `inline-block`. – Dan Froberg Jun 18 '23 at 11:16
2

I think floats may work best for you here, if you dont want the element to occupy the whole line, float it left should work.

.text span {
       background:rgba(165, 220, 79, 0.8);
       float: left;
       clear: left;
       padding:7px 10px;
       color:white;
    }

Note:Remove <br/>'s before using this off course.

Bhushan Firake
  • 9,338
  • 5
  • 44
  • 79
2

If you're OK with not using <p>s (only <div>s and <span>s), this solution might even allow you to align your inline-blocks center or right, if you want to (or just keep them left, the way you originally asked for). While the solution might still work with <p>s, I don't think the resulting HTML code would be quite correct, but it's up to you anyways.

The trick is to wrap each one of your <span>s with a corresponding <div>. This way we're taking advantage of the line break caused by the <div>'s display: block (default), while still keeping the visual green box tight to the limits of the text (with your display: inline-block declaration).

.text span {
   background:rgba(165, 220, 79, 0.8);
   display:inline-block;
   padding:7px 10px;
   color:white;
}
.large {  font-size:80px }
<div class="text">
  <div><span class="medium">We</span></div>
  <div><span class="large">build</span></div>
  <div><span class="medium">the</span></div>
  <div><span class="large">Internet</span></div>
</div>
Rui Pimentel
  • 584
  • 1
  • 5
  • 16