Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

clear:both after an element

8 views
Skip to first unread message

Stan Brown

unread,
May 20, 2022, 1:58:24 PM5/20/22
to
Do I need a vacuous <div> to accomplish this, or is there something I
can apply to the selector that actually contains text?

I am formatting some letters. Each letter is headed by a dateline of
two or three short lines, such as

Villa Miranda
Corfu
Thursday

I put this block against the right-hand margin, but have the lines
within it aligned at the left. In other words, the last character of
the longest line is against the right margin, and the first character
of the shorter lines are left-aligned with the first character of the
longest line. This all works fine, with this selector:

p.letterdateline { float:right;
margin-left:auto; margin-right:0;
text-align:left; text-indent:0; }

I want the first line of the letter ("Dear Smith:") to begin (at the
left) on the next line after the last line of the class
letterdateline heading. I know I can get that by inserting <div
style="clear:both"></div> after the </p> of the letterdateline, but I
hate using vacuous elements.

I had hoped to use the ::after pseudo-element, like this:

p.letterdateline::after { clear:both; }

but when I do that the text of the letter flows around the dateline
header, rather than beginning on the next line as I wish. (Tried in
the latest Chrome and Firefox.)

Is a vacuous <div> the only way to do what I want, or can I do
something with the p.letterdateline selector?

--
Stan Brown, Tehachapi, California, USA
https://BrownMath.com/

😉 Good Guy 😉

unread,
May 20, 2022, 5:32:54 PM5/20/22
to
On 20/05/2022 18:58, Stupid Stan Brown wrote:
Do I need a vacuous <div> to accomplish this, or is there something I 
can apply to the selector that actually contains text?

I am formatting some letters. Each letter is headed by a dateline of 
two or three short lines, such as

					         Villa Miranda
                                       Corfu
                                       Thursday 




        
    
    

Villa Miranda

Corfu

Thursday


Arrest
Dictator Putin

We Stand
With Ukraine

Stop Putin
Ukraine Under Attack


--
Similar to Windows 11 Home edition, Windows 11 Pro edition now requires internet connectivity during the initial device setup (OOBE) only. If you choose to setup device for personal use, MSA will be required for setup as well. You can expect Microsoft Account to be required in subsequent WIP flights.

Now this is not the end. It is not even the beginning of the end. But it is, perhaps, the end of the beginning

Philip Herlihy

unread,
May 21, 2022, 2:27:06 PM5/21/22
to
In article <MPG.3cf17696f...@news.individual.net>, Stan Brown
wrote...
Interesting puzzle. I bet there's a compelling and elegant solution, but I
don't know what it is...

First observation is that this may possibly not be an appropriate use of
'float'. You choose float when you *do* want other elements to flow around the
floated object. But perhaps there's a logo or whatever that you do want to
appear to the left of this "address" block, so the float is needed. Otherwise,
all you need to do is have a 100% wide block, text-align'd to the right.

Secondly, it's arguable that you're trying to put into a rule for one object
properties which are to apply to another (the following element). Something
about that doesn't seem quite right!

I think I've spotted why your code didn't work. Picking through Eric Meyer &
Estelle Weyle's "Definitive Guide to CSS" (4th Edition) I see the ::after
pseudo-selector can take a 'content' property which makes explicit what it is
you are inserting after the element, optionally followed by any other
properties include styling. So you could have:
p.letterdateline::after {content: "hello"; color: red}

But you aren't inserting anything, so the styling you apply doesn't have a
target. Try this:
p.letterdateline::after {" "; clear:both}
That puts in an arguably superfluous space, but at least the clear directive
has something to chew on. You might try an empty string, with or without the
use of the content property. Clear is only valid for block elements, so you
may need to include display:block; as well. In theory you could put a newline
in there as \A, though Meyer & Weyl note that this isn't currently at all
widely supported (publication 2018).

Otherwise, going back to the notion that you're really targeting the properties
of the element following your address block, the "adjacent sibling" selector
'+' may do the trick.
p.letterdateline + p {clear:both}
This may be generalisable to any adjacent sibling:
p.letterdateline + * {clear:both}

None of this is tested - I do have my own work to do! And what a rabbit-hole
that post turned out to be :-)

--

Phil, London

J𝕒𝕞𝕖𝕤 𝕂𝕚𝕣𝕜

unread,
May 21, 2022, 2:59:26 PM5/21/22
to
In Message <MPG.3cf17696f...@news.individual.net>
On Fri, 20 May 2022 10:58:20 -0700
Stan Brown <the_sta...@fastmail.fm> wrote:

> Do I need a vacuous <div> to accomplish this, or is there something I
> can apply to the selector that actually contains text?

I suggest that display grid just may be what you are looking for.

> I am formatting some letters. Each letter is headed by a dateline of
> two or three short lines, such as

> Villa Miranda
> Corfu
> Thursday

> I put this block against the right-hand margin, but have the lines
> within it aligned at the left. In other words, the last character of
> the longest line is against the right margin, and the first character
> of the shorter lines are left-aligned with the first character of the
> longest line. This all works fine, with this selector:

[snip]

> I want the first line of the letter ("Dear Smith:") to begin (at the
> left) on the next line after the last line of the class
> letterdateline heading. I know I can get that by inserting <div
> style="clear:both"></div> after the </p> of the letterdateline, but I
> hate using vacuous elements.

[snip]

div {
display: grid;
row-gap: 1ex;
margin-right: 0;
margin-left: auto;
width: fit-content;
outline: solid blue thin;
}

div > p {
margin: 0;
line-height: 1;
}

div > p {
grid-column: 2;
}

div > p + p {
grid-column: 1;
}


<div>
<p>
Villa Miranda
</p>
<p>
Corfu
</p>
<p>
Thursday
</p>
</div>


That should display similarly to a table.

table {
border-collapse: collapse;
margin-right: 0;
margin-left: auto;
outline: solid blue thin;
}

td {
padding: 0;
line-height: 1;
}

td + td {
text-align: right;
}

<table>
<tr>
<td></td>
<td>
Villa Miranda
</td>
</tr>
<tr>
<td>
Corfu
</td>
<td></td>
</tr>
<tr>
<td>
Thursday
</td>
<td></td>
</tr>
</table>

IF you are going to insist on using a float, post an example of the
HTML you are using. There are a few ways to clear floats, but I see no
need to use a float in this example.

--
J𝕒𝕞𝕖𝕤 𝕂𝕚𝕣𝕜

Stan Brown

unread,
May 21, 2022, 5:21:31 PM5/21/22
to
On Sat, 21 May 2022 19:27:04 +0100, Philip
Herlihy wrote:
>
> In article <MPG.3cf17696f...@news.individual.net>, Stan Brown
> wrote...
> >
But in the course of writing your reply, you
hit upon the C & E S.

> First observation is that this may possibly not be an appropriate use of
> 'float'. You choose float when you *do* want other elements to flow around the
> floated object. But perhaps there's a logo or whatever that you do want to
> appear to the left of this "address" block, so the float is needed. Otherwise,
> all you need to do is have a 100% wide block, text-align'd to the right.

text-align:right is no good. That will line up
the _last_ character of each line, but I want
to line up the _first_ character of each line.

> Secondly, it's arguable that you're trying to put into a rule for one object
> properties which are to apply to another (the following element). Something
> about that doesn't seem quite right!
>
> I think I've spotted why your code didn't work. Picking through Eric Meyer &
> Estelle Weyle's "Definitive Guide to CSS" (4th Edition) I see the ::after
> pseudo-selector can take a 'content' property which makes explicit what it is
> you are inserting after the element, optionally followed by any other
> properties include styling. So you could have:
> p.letterdateline::after {content: "hello"; color: red}
>
> But you aren't inserting anything, so the styling you apply doesn't have a
> target. Try this:
> p.letterdateline::after {" "; clear:both}

I tried this with and without display:block,
and the following lines moved up and to the
left of the dateline.

> Otherwise, going back to the notion that you're really targeting the properties
> of the element following your address block, the "adjacent sibling" selector
> '+' may do the trick.
> p.letterdateline + p {clear:both}
> This may be generalisable to any adjacent sibling:
> p.letterdateline + * {clear:both}

Bingo! This was a winner. It did exactly what
I want, without the extra vacuous <div>.

Thank you very much!

Stan Brown

unread,
May 21, 2022, 5:31:12 PM5/21/22
to
On Sat, 21 May 2022 14:59:11 -0400, J???? ????
wrote:
Thanks for responding.

I had never heard of display:grid, but when I
looked it up I saw that it's necessary to
define sizes of rows and columns, and I won't
know that in advance.

The table with margin-right: 0; margin-left:
auto; looks as though it ought to work, and I
hadn't thought of that. But it's a lot more
HTML tags than a simple <p>.

I ended up using Philip Herlihy's solution:
p.letterdateline + * { clear:both; }
It worked for me, with no extra HTML and just
one line of styling.

Philip Herlihy

unread,
May 21, 2022, 7:12:24 PM5/21/22
to
In article <MPG.3cf2f7ce...@news.individual.net>, Stan Brown wrote...
### Indeed I had somehow failed to register that - sorry! In fact the more I
study your p.letterdateline selector above, the less I understand how it works
(yes, I'm rusty with CSS!). Does each address line have its own
p.letterdateline, or is there just one, using <BR> tags to lay out the three
lines? I'm guessing the latter.

I've fooled around with this a bit more (that rabbit-hole again) and I'll post
two code samples. One uses an <IMG>, which I found I had to wrap in a DIV to
get the ::after trick to work. The other attempted to put your address lines
in a container DIV, with display set to inline-block, and floated right. But
it doesn't work. I put some visible content in the ::after properties, and I
think it's signifcant where that content ends up. Look for two follow-up posts
from me. I'll stop there.

Sometimes I do think that CSS is just too darn complicated for mere mortals
like me...

> > Secondly, it's arguable that you're trying to put into a rule for one object
> > properties which are to apply to another (the following element). Something
> > about that doesn't seem quite right!
> >
> > I think I've spotted why your code didn't work. Picking through Eric Meyer &
> > Estelle Weyle's "Definitive Guide to CSS" (4th Edition) I see the ::after
> > pseudo-selector can take a 'content' property which makes explicit what it is
> > you are inserting after the element, optionally followed by any other
> > properties include styling. So you could have:
> > p.letterdateline::after {content: "hello"; color: red}
> >
> > But you aren't inserting anything, so the styling you apply doesn't have a
> > target. Try this:
> > p.letterdateline::after {" "; clear:both}
>
> I tried this with and without display:block,
> and the following lines moved up and to the
> left of the dateline.
>
> > Otherwise, going back to the notion that you're really targeting the properties
> > of the element following your address block, the "adjacent sibling" selector
> > '+' may do the trick.
> > p.letterdateline + p {clear:both}
> > This may be generalisable to any adjacent sibling:
> > p.letterdateline + * {clear:both}
>
> Bingo! This was a winner. It did exactly what
> I want, without the extra vacuous <div>.
>
> Thank you very much!

(follow-up comment inline above)

--

Phil, London

Philip Herlihy

unread,
May 21, 2022, 7:14:25 PM5/21/22
to
In article <MPG.3cf38235a...@news.eternal-september.org>, Philip
Herlihy wrote...
>

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Does work</title>
<style>
img {
float: right
}
div#abc::after {
content: "## THE CONTENT ##";
display: block;
clear: both;
}
</style>
</head>

<body>
<div id="abc">
<img src="http://leytonstone.net/bluebells/chalet200.jpg" width="200"
height="125">
</div>
<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vulputate,
justo at facilisis fringilla, elit leo egestas purus, vel pulvinar nunc urna et
elit.
</p>
</body>
</html>



--

Phil, London

Philip Herlihy

unread,
May 21, 2022, 7:15:05 PM5/21/22
to
In article <MPG.3cf38235a...@news.eternal-september.org>, Philip
Herlihy wrote...
>

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Doesn't work</title>
<style>
div#abc {
background-color: #EEE;
display: inline-block;
float:right;
}
div#abc::after {
content: "## THE CONTENT ##";
display: block;
clear: both;
}
</style>
</head>

<body>
<div id="abc">
<p>Bunham House</p>
<p>Walthamstow</p>
<p>London</p>

Philip Herlihy

unread,
May 22, 2022, 7:14:56 AM5/22/22
to
In article <568c10e8-648d1ff0...@james.kirk.invalid>, J???? ????
wrote...
That works! I have to say I have a real blind-spot for grid and flexbox. I
get very little time these days to fool about with CSS, and it's often only
when someone posts something interesting here that I get to think about it at
all - while the skills I did have are atrophying all the time.

I've looked at flexbox, but while it makes sense in the tutorials, it seems to
me that you have to spend time working through examples really to get the hang
of it, and time's short for me. Once I master flexbox (and I really must) I'll
move on to grid. But it's clear that yours is the elegant and compelling
solution to go for.

--

Phil, London

Philip Herlihy

unread,
May 22, 2022, 7:21:54 AM5/22/22
to
In article <MPG.3cf2fa18d...@news.individual.net>, Stan Brown
wrote...
width: fit-content;
... seems to be the only size directive.

J*'s solution does seem to be the most general, and I'm persuaded that grid is
easier to master than I've been assuming!
--

Phil, London

Stan Brown

unread,
May 22, 2022, 3:31:47 PM5/22/22
to
On Sun, 22 May 2022 00:12:22 +0100, Philip Herlihy wrote:
>
> In article <MPG.3cf2f7ce...@news.individual.net>, Stan Brown wrote...
> > text-align:right is no good. That will line up
> > the _last_ character of each line, but I want
> > to line up the _first_ character of each line.
> >
> ### Indeed I had somehow failed to register that - sorry! In fact the more I
> study your p.letterdateline selector above, the less I understand how it works
> (yes, I'm rusty with CSS!). Does each address line have its own
> p.letterdateline, or is there just one, using <BR> tags to lay out the three
> lines? I'm guessing the latter.

You're correct. I wanted just one container for the complete
dateline, so <p class="letterdateline"> ... <br> ... <br> ... </p>
did that.

I feared if I had multiple <p> within a <div>, that the lining up
wouldn't work as I wished. I didn't actually test that, because the
<br> version worked and was a simpler.

It was a nice benefit that I could then follow your suggestion of a
p.letterdateline + * selector without changing anytjing except
removing all my <div class="clear">&nbsp;</div>.

Stan Brown

unread,
May 22, 2022, 3:54:40 PM5/22/22
to
On Sun, 22 May 2022 00:15:04 +0100, Philip Herlihy wrote:
> In article <MPG.3cf38235a...@news.eternal-september.org>, Philip
> Herlihy wrote...
[See top of subthread for HTML.]

Hmm -- I can't see why your "Doesn't work" should fail, unless it's
the inline-block on the div#abc. But I'm not a CSS expert.

Stan Brown

unread,
May 22, 2022, 3:55:51 PM5/22/22
to
On Sun, 22 May 2022 00:14:23 +0100, Philip Herlihy wrote:
>
> In article <MPG.3cf38235a...@news.eternal-september.org>, Philip
> Herlihy wrote...
[See top of subthread for origibal HTML.]

I wondered about the need to wrap the <img> in a <div>; I thought
making the <img> display:block might obviate the <div>; see the
result below. Specifically, I modified your code like this:
1. Added display:block in img { }
2. Added an img + * selector.
3. Removed the <div> and </div> lines.

Thhis also worked.

Google Chrome kept nagging me, on all three HTML pages, to translate
from Latin from English. Finally I did, and found the result amusing.
I had always understood that "Lorem ipsum" text was not Latin but
just looked like Latin. Apparently it was a good enough resemblance
to fool Google. The result:

"The pain itself is love, the main storage system. Proin Olympic,
just at the easy sort, the lion's pain is pure poverty, or the couch
is now urn and elite."

Philip's "Does work" as modified by Stan (> prevents lines breaking)

> <!doctype html>
> <html>
> <head>
> <meta charset="utf-8">
> <title>Also works</title>
> <style>
> img {
> float: right;
> display: block;
> }
> img + * { clear:both; }
> </style>
> </head>
>
> <body>
> <img src="http://leytonstone.net/bluebells/chalet200.jpg" width="200"
> height="125">
> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vulputate,
> justo at facilisis fringilla, elit leo egestas purus, vel pulvinar nunc urna et
> elit.
> </p>
> </body>
> </html>




--

Stan Brown

unread,
May 22, 2022, 4:00:03 PM5/22/22
to
On Sun, 22 May 2022 12:14:54 +0100, Philip Herlihy wrote:
>
> In article <568c10e8-648d1ff0...@james.kirk.invalid>, J???? ????
> wrote...
[stuff with display:grid]

> That works! I have to say I have a real blind-spot for grid and flexbox. I
> get very little time these days to fool about with CSS, and it's often only
> when someone posts something interesting here that I get to think about it at
> all - while the skills I did have are atrophying all the time.
>
> I've looked at flexbox, but while it makes sense in the tutorials, it seems to
> me that you have to spend time working through examples really to get the hang
> of it, and time's short for me. Once I master flexbox (and I really must) I'll
> move on to grid. But it's clear that yours is the elegant and compelling
> solution to go for.

I'm grateful to both of you for posting. But elegance is in the eye
of the beholder. To me the p.letterdateline + * solution seems the
more elegant, at least in my application. I concede that it may not
be applicable in as many situations as J?'s.

Philip Herlihy

unread,
May 23, 2022, 6:39:39 AM5/23/22
to
In article <MPG.3cf434d47...@news.individual.net>, Stan Brown
wrote...
>
> On Sun, 22 May 2022 00:15:04 +0100, Philip Herlihy wrote:
> > In article <MPG.3cf38235a...@news.eternal-september.org>, Philip
> > Herlihy wrote...
> [See top of subthread for HTML.]
>
> Hmm -- I can't see why your "Doesn't work" should fail, unless it's
> the inline-block on the div#abc. But I'm not a CSS expert.

The inline-block was my attempt to solve the problem of having a right-aligned
container with left-aligned contents. I just found if I take it out, it makes
no difference at all! The div containing the address lines adopts the width of
its contents, and the float pushes it to the right.

The attempt to get a clear to work by adding (using ::after) some content
styled clear:both doesn't work. I'd found in the other version (which did
work) that an empty string was enough content, but if you put something in
there, you can see where it ends up. That, I think, is a clue to why it
doesn't work. Why it should work for the version with the image is entirely
beyond me. I guess you can put something into a DIV, but you can't do that to
an IMG.

Fundamentally, CSS is baffling. I predict it will never catch on.

--

Phil, London

Ben

unread,
May 23, 2022, 7:43:44 AM5/23/22
to
Philip Herlihy <Phillip...@SlashDevNull.invalid> writes:

> In article <MPG.3cf38235a...@news.eternal-september.org>, Philip
> Herlihy wrote...
>>
>
> <!doctype html>
> <html>
> <head>
> <meta charset="utf-8">
> <title>Doesn't work</title>
> <style>
> div#abc {
> background-color: #EEE;
> display: inline-block;
> float:right;
> }
> div#abc::after {
> content: "## THE CONTENT ##";
> display: block;
> clear: both;
> }

This adds content as the last child of div#abc so there is nothing to
clear on either side: the content is in the div (as you can see). I've
not been following closely, so this may already have been pointed out.
Sorry if it has.

What you probably want is something like

#abc + p { clear: both; }

so that the first paragraph following the div with id #abc is clear of
the floats. You can make it more general if you like with #abx + * as
the selector.

> </style>
> </head>
>
> <body>
> <div id="abc">
> <p>Bunham House</p>
> <p>Walthamstow</p>
> <p>London</p>
> </div>
> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin
> vulputate, justo at facilisis fringilla, elit leo egestas purus, vel
> pulvinar nunc urna et elit. </p> </body> </html>

--
Ben.

Philip Herlihy

unread,
May 23, 2022, 8:16:26 AM5/23/22
to
In article <877d6c1...@bsb.me.uk>, Ben wrote...
Thanks, Ben. I've been groping this morning towards realising that - as you
say - it adds content as the last child of the div. (I had already spotted the
"adjacent sibling" alternative.)

My conclusion is that the "grid" solution offered by 'J' is the best and most
general solution, followed by the "#whatever + * {clear:both}" alternative.
Either is better than this stretch of mucking about with ::after. However,
it's been bugging me (for some unaccountable reason) that I could get ::after
to work with an image, but not with the paragraph originally proposed.

I've now got both working, and I've also revived my CodePen account, so anyone
interested (form an orderly queue) can see both of them here:

https://codepen.io/philipherlihy/pen/mdXMaaG (image version)
https://codepen.io/philipherlihy/pen/NWyvoKK (paragraph version)

They work just the same, and that became clear once I was meticulous about
structuring them equivalently. You can see from the background shading that
the ::after pseudo-property does indeed add content *within* the element
concerned.

If you can get really fluent in CSS, then learning Hungarian from a Finnish
textbook would surely be a breeze...

--

Phil, London

Stan Brown

unread,
May 23, 2022, 10:11:38 AM5/23/22
to
On Mon, 23 May 2022 11:39:37 +0100, Philip Herlihy wrote:
> Fundamentally, CSS is baffling. I predict it will never catch on.
>

:-)

J𝕒𝕞𝕖𝕤 𝕂𝕚𝕣𝕜

unread,
May 24, 2022, 7:35:34 AM5/24/22
to
In Message <t691e4$11guo$1...@news.mixmin.net>
On Fri, 20 May 2022 22:30:19 +0100
😉 Good Guy 😉 <Hello...@example.onion> wrote:

> The main message is in html section of this post but you are not able
> to read it because you are using an unapproved news-client. Please
> try these links to amuse youself:

[snip]

unapproved news-client?

FYI: 3 out of 4 Usenet Providers that I use do not have your message.

I can only presume your message has been filtered||remove because of the
html message.

If you are posting for you own amusement or for google then carry on.

If you want to contribute or participate, I suggest that you post text
only messages, because the posters you reply to may not even see your
message. Just as I will not likely see your message if you reply to
this one using html.

--
J𝕒𝕞𝕖𝕤 𝕂𝕚𝕣𝕜

Allodoxaphobia

unread,
May 24, 2022, 9:40:06 AM5/24/22
to
+1

Jonesy

Philip Herlihy

unread,
May 24, 2022, 9:55:57 AM5/24/22
to
In article <5b0310f9-34f99255...@james.kirk.invalid>, J???? ????
wrote...
Notorious troll.

--

Phil, London
0 new messages