How to make an inline element appear on new line, or block element not occupy the whole line?

Viewed 210064

I can't figure out how to do this with CSS. If I just use a <br> tag, it works flawlessly, but I'm trying to avoid doing that for obvious reasons.

Basically, I just want the .feature_desc span to start on a new line, but:

  • If I make it an inline element, it won't have a line-break.
  • If I make it a block element, it will expand to fit the entire line, putting each of these icons on its own line, and wasting tons of space on the screen (each .feature_wrapper will be a slightly different size, but none will ever be as wide as the entire screen.)

Example code: This works, but uses a br tag:

<li class='feature_wrapper' id='feature_icon_getstart'> 
    <span style='display: none;' class='search_keywords'>started</span> 
    <span class='feature_icon spriteicon_img' id='icon-getstart'><a href='getstarted/index.html' class='overlay_link'></a></span><br/>
    <span class='feature_desc'><a href='getstarted/index.html' >Getting Started Wizard</a></span> 
</li>

I want to style this with CSS to achieve the same result:

<li class='feature_wrapper' id='feature_icon_getstart'> 
    <span style='display: none;' class='search_keywords'>started</span> 
    <span class='feature_icon spriteicon_img' id='icon-getstart'><a href='getstarted/index.html' class='overlay_link'></a></span>
    <span class='feature_desc'><a href='getstarted/index.html' >Getting Started Wizard</a></span> 
</li>

Any ideas? Or am I going about this the wrong way?

9 Answers

span::before { content: "\A"; white-space: pre; }

Using a flex parent works too. Setting flex-direction to column will put each child on a new line and setting align-items will make them not take up the whole width. Here is a small example:

<div class="parent">
   <a>some links</a>
   <a>that should be on their own lines</a>
   <a>but not take up the whole parent width</a>
</div>
.parent {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

I was running into a similar situation on our WooCommerce site. The "Add to cart" button was right next to a custom product field, and I needed to drop the product field below the button. This is the CSS that ended up doing the trick for me

#product-57310 label[for="wcj_product_input_fields_local_1"] { display: -webkit-box!important; margin-top: 80px; }

where "#product-57310" is the ID of the product in woocommerce, so that it only applies to the specific product page and not every product page, and where "label[for="wcj_product_input_fields_local_1"]" is targeting the first label specifically to get under the "Add to cart" button.

I had a similar issue where I had something like this:

<span>
 <input>
 <label>
 <input>
 <label>
 ...
</span>

I didn't wanna mess with the source html generator (even tho this html is pretty bad). So the way I fixed it is use a display: grid on the top span. Then grid-template-columns: auto auto;

Anyone looking to do something similar, grid is a good solution now (in 2021).

For example, for this particular problem, applying display: grid; grid-template-columns: auto auto; to li and grid-column: 1 / 3; to last span will do it.

Use two CSS rules

word-break: break-all;
display: list-item;

inside of a CSS selector and body


Note:

If only dealing with text that needs to be put on separate lines.

Try using word-break like so (note stack overflow code automatically does this but I included it to help clarify usage in other environments:

 word-break: break-all;

If only dealing with in-line HTML elements like a <span>

Then see this answer as to how to convert non text elements (like an anchor tag) to line separated elements using a display: list-item also on the html tag

Link

How to make text in <a> tag wordwrap


Example (For HTML inline elements like span)

span {
  display: list-item;
  word-break: break-word;
}
<span>Line 1</span>
<span>Line 2</span>
<span>Line 3</span>
<span>Line 4</span>
<span>Line 5</span>

Example (For Text Content)

function makePerson(name, age) {
    // add code here
    let person = Object.create({});
    person.name = name;
    person.age = age;
    return person;
}

const person = makePerson('Vicky', 24);
const outputDiv = document.querySelectorAll("body .output");
const keys = Object.keys(person);

outputDiv.forEach((div,key) => {
    div.innerHTML = person[keys[key]];
});
body #output{
    word-break: break-all;
}
<div>
   <div class="output"></div>
   <div class="output"></div>
</div>

Related