Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS: inline all elements that fit on first line, line break after each next element

Tags:

css

less

no javascript and no screen width media queries

I am trying to find a css-only way to achieve the situation depicted in below image. I couldn't find a way to create the following:

  • a line of blocks (inline blocks or floated blocks) with variable width, aligned to the right of the line using float:right or right text align
  • elements that don't fit on the line, wrap to the next line. All elements after the first line have their own line.

I've been experimenting around with several strategies to no avail, I have a feeling that flexbox might help but I'm not very experienced with flexbox and couldn't find a way to use it.

enter image description here


A few things that I have tried:

  1. try to put the elements' content in a :before pseudo element, using content:attr(data-content). The element itself would have no width. On the next line there would be a left floating element with a width of 99.9% that pushes each element on a next line. The problem with this is that the elements on the first line should maintain their normal width and I didn't find a way to do that. The :first-line pseudo-selector is limited to words on the line and doesn't work for inline containers on the line
  2. Alternative to above method: also add :after pseudo elements which are absolutely positioned and have the same content as the :befores. The :before elements would only show on the first line and don't wrap, the :after elements would form the vertical list on the right. Also with this way I walked into a dead end.

UPDATE: I made a (less) fiddle that works when the elements' widths are fixed and equal. Unfortunately fixed width, so not yet what I want to achieve. If you want to help me you could perhaps use this as a starting point. I put the content in a :before so perhaps it could overflow the element and somehow fix the element width to auto.

currently CHROME only: http://jsfiddle.net/2px3b63j/7/

html:

<div class="pusher"></div>
<nav>
  <a data-title="First" href="#"></a><a data-title="Second" href="#"></a><a data-title="Third" href="#"></a><a data-title="Fourth" href="#"></a><a data-title="Fifth" href="#"></a>
</nav>

less:

@h: 3em;
@w:6em;
* {
  margin: 0;
  padding: 0;
}

body {
  font: 0.9rem sans-serif;
  background: #666;
}

.pusher {
  float: left;
  width: ~"calc(100% - " (@w * 1.01) ~")";
  height: @h * 6;
  -webkit-shape-outside: polygon(0 @h, 100% @h, 100% 100%, 0 100%);
}

nav {
  position: relative;
  text-align: right;
  background: white;
  height: @h;
  line-height:0;
  a {
    position: relative;
    text-align:center;
    width: @w;
    max-width: 100%;
    display: inline-block;
    background: white;
    text-decoration: none;
    color: #333;
    font-weight: bold;
    height: @h;
    line-height: @h;
    &:before {
      content: attr(data-title);
    }
  }
}

LINK TO ANSWER: https://jsfiddle.net/ky83870x/1/ doesn't work in Internet Explorer but I assume it works in Edge. If anyone can find a way to make it work in IE, I will be very interested to know

like image 655
Hacktisch Avatar asked Feb 24 '16 13:02

Hacktisch


People also ask

Does an inline element forces the next content to a new line?

Inline elements display in a line. They do not force the text after them to a new line. An anchor (or link) is an example of an inline element.

How can you apply style to first line of every paragraph?

The ::first-line pseudo-element is for applying styles to the first line of an element. Imagine a paragraph that is several lines long (like this one!). ::first-line allows you to style that first line of text. You could use it to make it larger or set it in small-caps as a stylistic choice.

How do I put all elements in one line in CSS?

To get all elements to appear on one line the easiest way is to: Set white-space property to nowrap on a parent element; Have display: inline-block set on all child elements.

How do I make a line break in CSS?

A line-break can be added in HTML, using only CSS, by employing the pseudo-class ::after or ::before . In the stylesheet, we use these pseudo-classes, with the HTML class or id, before or after the place where we want to insert a line-break. In myClass::after : Set the content property to "\a" (the new-line character).


1 Answers

One posibility to get your output using flex box.

Make the flexbox so narrow that any child will fit. That forces the children to go one in a row.

Add a pseudo element before the first child to force an extra margin.

Justify the flex as needed

And place the flex to the right, because now everything is to the left.

The elements are color coded to see easily what is happening

.container {
  display: flex;
  flex-flow: row wrap;
  border: solid 1px red;
  width: 10px;
  left: 500px;
  position: absolute;
  justify-content: flex-end;
}

.container div {
  font-size: 20px;
  margin: 5px;
  background-color: lightblue;
  display: inline-block;
  flex-basis: auto;
  flex-shrink: 0;
}

.container:before {
  content: "";
  margin-left: -500px;
  flex-basis: 10px;
  background-color: yellow;
  height: 6px;
}
<div class="container">
  <div>Lorem</div>
  <div>Ipsum dolor sit amet</div>
  <div>Consectetur adipisicing elit</div>
  <div>Unde saepe</div>
  <div>Placeat neque mollitia</div>
  <div>Accusamus fuga</div>
  <div>Lorem</div>
  <div>Ipsum dolor sit amet</div>
  <div>Consectetur adipisicing elit</div>
  <div>Unde saepe</div>
  <div>Placeat neque mollitia</div>
  <div>Accusamus fuga</div>
</div>
like image 87
vals Avatar answered Oct 12 '22 20:10

vals