csscss-floatpseudo-element

Using `clear:both` inside a `::before` pseudo-element


I can't figure out why this isn't working:

my-selector::before {
  content: "";
  display: block;
  clear:  both;
}

I'm using floats into a wide, styled border to keep meta information out of the flow of the main content (This is an attempt to implement something like the Cornell Notetaking System; any suggestions for how to do this better would be appreciated, but I still want to know why this technique is failing!) When I have a meta note (aka cue), it simply gets the class cue and is floated left.

(Note that I don't have easy direct control of the HTML; it's generated from a Markdown-like language. But I can add the cue class.)

This works well, so long as the cues are shorter than the succeeding code they annotate:

div.Cornell {
  padding: 0 1em;
  border-left: 12em solid #cfc;
}
div.Cornell div.cue {
  float: left;
  width: 10em;
  margin-left: -12em;
  display: inline-block;
}
div.Cornell div.cue::before {
  content: "";
  display: block;
  clear:  both;
}
.Cornell-summary {
  margin: 1em 0;
  background-color: #ffe;
  padding: 0 1em 1em;
}
<div class="Cornell">

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Eu feugiat pretium nibh ipsum consequat nisl. Nulla facilisi etiam dignissim diam quis enim lobortis. Tortor condimentum lacinia quis vel eros donec. Neque laoreet suspendisse interdum consectetur libero id faucibus nisl. Sapien eget mi proin sed.</p>

<div class="cue">
  <p>First cue: <em>Consequat interdum varius sit amet mattis vulputate.  Pellentesque dignissim enim sit amet venenatis urna cursus.</em></p>
</div>

<p>The first cue should float left of this content.</p>

<p>Et ligula ullamcorper malesuada proin libero nunc consequat interdum. Consequat interdum varius sit amet mattis vulputate. Tristique senectus et netus et malesuada fames ac turpis egestas. Iaculis at erat pellentesque adipiscing commodo elit at imperdiet dui. Purus non enim praesent elementum facilisis. Pellentesque dignissim enim sit amet venenatis urna cursus. Nec tincidunt praesent semper feugiat nibh. Ullamcorper dignissim cras tincidunt lobortis feugiat vivamus at augue eget. Tempor nec feugiat nisl pretium fusce id velit ut tortor. Proin nibh nisl condimentum id venenatis a condimentum. Purus ut faucibus pulvinar elementum integer enim neque volutpat ac. Posuere morbi leo urna molestie at. Cum sociis natoque penatibus et magnis. Turpis nunc eget lorem dolor.</p>

<div class="cue"><p>Second cue: <em>Montes nascetur ridiculus mus mauris</em></p></div>

<p>The second cue should float left of this content</p>

<p>Nunc sed blandit libero volutpat sed cras ornare arcu. Habitasse platea dictumst vestibulum rhoncus est. Vel pretium lectus quam id leo in. Enim neque volutpat ac tincidunt. Arcu vitae elementum curabitur vitae. Montes nascetur ridiculus mus mauris. Ullamcorper sit amet risus nullam eget.</p>
</div>
<div class="Cornell-summary">
<hr/>
<h2>Summary</h2>
<p>Eu feugiat pretium nibh ipsum consequat nisl. Nulla facilisi etiam dignissim diam quis enim lobortis. Tortor condimentum lacinia quis vel eros donec.</p>
</div>

But when the cue content is longer, it causes issues. The floated content simply overlaps. I thought I would be able to solve this with the ::before pseudo-element and clear: both, but as you can see here, it doesn't seem to work:

div.Cornell {
  padding: 0 1em;
  border-left: 12em solid #cfc;
}
div.Cornell div.cue {
  float: left;
  width: 10em;
  margin-left: -12em;
  display: inline-block;
}
div.Cornell div.cue::before {
  content: "";
  display: block;
  clear:  both;
}
.Cornell-summary {
  margin: 1em 0;
  background-color: #ffe;
  padding: 0 1em 1em;
}
<div class="Cornell">

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Eu feugiat pretium nibh ipsum consequat nisl. Nulla facilisi etiam dignissim diam quis enim lobortis. Tortor condimentum lacinia quis vel eros donec. Neque laoreet suspendisse interdum consectetur libero id faucibus nisl. Sapien eget mi proin sed.</p>

<div class="cue">
  <p>First cue: <em>Consequat interdum varius sit amet mattis vulputate.  Pellentesque dignissim enim sit amet venenatis urna cursus.</em></p>
  <p>Sed cras ornare arcu dui. Erat nam at lectus urna duis convallis convallis tellus. Rhoncus est pellentesque elit ullamcorper. Feugiat nibh sed pulvinar proin. Orci a scelerisque purus semper eget duis at. Venenatis tellus in metus vulputate. Vulputate ut pharetra sit amet aliquam. Proin sed libero enim sed faucibus. Interdum velit euismod in pellentesque massa. Elit ullamcorper dignissim cras tincidunt lobortis feugiat vivamus at augue. Facilisis leo vel fringilla est ullamcorper. Sapien nec sagittis aliquam malesuada bibendum arcu vitae.</p>
</div>

<p>The first cue should float left of this content.</p>

<p>Et ligula ullamcorper malesuada proin libero nunc consequat interdum. Consequat interdum varius sit amet mattis vulputate. Tristique senectus et netus et malesuada fames ac turpis egestas. Iaculis at erat pellentesque adipiscing commodo elit at imperdiet dui. Purus non enim praesent elementum facilisis. Pellentesque dignissim enim sit amet venenatis urna cursus. Nec tincidunt praesent semper feugiat nibh. Ullamcorper dignissim cras tincidunt lobortis feugiat vivamus at augue eget. Tempor nec feugiat nisl pretium fusce id velit ut tortor. Proin nibh nisl condimentum id venenatis a condimentum. Purus ut faucibus pulvinar elementum integer enim neque volutpat ac. Posuere morbi leo urna molestie at. Cum sociis natoque penatibus et magnis. Turpis nunc eget lorem dolor.</p>

<div class="cue"><p>Second cue: <em>Montes nascetur ridiculus mus mauris</em></p></div>

<p>The second cue should float left of this content</p>

<p>Nunc sed blandit libero volutpat sed cras ornare arcu. Habitasse platea dictumst vestibulum rhoncus est. Vel pretium lectus quam id leo in. Enim neque volutpat ac tincidunt. Arcu vitae elementum curabitur vitae. Montes nascetur ridiculus mus mauris. Ullamcorper sit amet risus nullam eget.</p>
</div>
<div class="Cornell-summary">
<hr/>
<h2>Summary</h2>
<p>Eu feugiat pretium nibh ipsum consequat nisl. Nulla facilisi etiam dignissim diam quis enim lobortis. Tortor condimentum lacinia quis vel eros donec.</p>
</div>

Am I missing something simple? Something more complex but doable? It really feels as if this should work.

This output is what I was trying to achieve, but using hard-coded additional divs that have clear: both:

div.Cornell {
  padding: 0 1em;
  border-left: 12em solid #cfc;
}
div.Cornell div.cue {
  float: left;
  width: 10em;
  margin-left: -12em;
  display: inline-block;
}
.Cornell-summary {
  margin: 1em 0;
  background-color: #ffe;
  padding: 0 1em 1em;
}
<div class="Cornell">

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Eu feugiat pretium nibh ipsum consequat nisl. Nulla facilisi etiam dignissim diam quis enim lobortis. Tortor condimentum lacinia quis vel eros donec. Neque laoreet suspendisse interdum consectetur libero id faucibus nisl. Sapien eget mi proin sed.</p>

<div style="clear: both"></div>
<div class="cue">
  <p>First cue: <em>Consequat interdum varius sit amet mattis vulputate.  Pellentesque dignissim enim sit amet venenatis urna cursus.</em></p>
  <p>Sed cras ornare arcu dui. Erat nam at lectus urna duis convallis convallis tellus. Rhoncus est pellentesque elit ullamcorper. Feugiat nibh sed pulvinar proin. Orci a scelerisque purus semper eget duis at. Venenatis tellus in metus vulputate. Vulputate ut pharetra sit amet aliquam. Proin sed libero enim sed faucibus. Interdum velit euismod in pellentesque massa. Elit ullamcorper dignissim cras tincidunt lobortis feugiat vivamus at augue. Facilisis leo vel fringilla est ullamcorper. Sapien nec sagittis aliquam malesuada bibendum arcu vitae.</p>
</div>

<p>The first cue should float left of this content.</p>

<p>Et ligula ullamcorper malesuada proin libero nunc consequat interdum. Consequat interdum varius sit amet mattis vulputate. Tristique senectus et netus et malesuada fames ac turpis egestas. Iaculis at erat pellentesque adipiscing commodo elit at imperdiet dui. Purus non enim praesent elementum facilisis. Pellentesque dignissim enim sit amet venenatis urna cursus. Nec tincidunt praesent semper feugiat nibh. Ullamcorper dignissim cras tincidunt lobortis feugiat vivamus at augue eget. Tempor nec feugiat nisl pretium fusce id velit ut tortor. Proin nibh nisl condimentum id venenatis a condimentum. Purus ut faucibus pulvinar elementum integer enim neque volutpat ac. Posuere morbi leo urna molestie at. Cum sociis natoque penatibus et magnis. Turpis nunc eget lorem dolor.</p>

<!-- I do understand that this DIV is unnecessary; but having it
     here *works* and I hope it demonstrates what I was trying to
     do with my `::before` syntax.  --> 
<div style="clear: both"></div>
<div class="cue"><p>Second cue: <em>Montes nascetur ridiculus mus mauris</em></p></div>

<p>The second cue should float left of this content</p>

<p>Nunc sed blandit libero volutpat sed cras ornare arcu. Habitasse platea dictumst vestibulum rhoncus est. Vel pretium lectus quam id leo in. Enim neque volutpat ac tincidunt. Arcu vitae elementum curabitur vitae. Montes nascetur ridiculus mus mauris. Ullamcorper sit amet risus nullam eget.</p>
</div>
<div class="Cornell-summary">
<hr/>
<h2>Summary</h2>
<p>Eu feugiat pretium nibh ipsum consequat nisl. Nulla facilisi etiam dignissim diam quis enim lobortis. Tortor condimentum lacinia quis vel eros donec.</p>
</div>


Solution

  • The comment thread got long, so I will summarize here.

    What I was trying to do is impossible. The following creates a pseudo-element, but it does not appear in the DOM before the focused element. It appears before the content of that element:

    my-selector::before {
      content: "";
      display: block;
      clear:  both;
    }
    

    Thus I was trying to clear the float I was actually inside; it doesn't make sense.

    Thanks to everyone who helped clear that up, most especially @TemaniAfif!


    I did solve my underlying problem. I had said that I couldn't control the markup that was generated from the underlying language. But it turns out that if you look hard enough, you can add a custom markup element. Then it was simple to generate a clearing DIV before my new floating content, and everything works fine.