I know this is easy with Javascript but... is there any way with just CSS?
Let's say we have two elements (green and red) within a parent one (beige). The red element should be always to the right of the green one, except if the green one (because of the content) is too big to fit the parent in which case the red one will be over the green one (the normal behaviour would be the red element staying to the right of the green one and therefore being hidden because of the overflow of the parent)
In other words: red.x = min(green.x + green.w, beige.x+beige.w-red.w)
For more info, here's the concrete HTML:
<div class="beige" style="width:250px"> <!-- parent with a given width (unknown until the page is rendered) & overflow hidden -->
<a class="green"> <!-- link with display:inline -->
content
<em class="red"></em> <!-- actually a button, 15 px width -->
</a>
</div>
EDIT: @kyledws answer is awesome but I'll update the question with more info (needed things) such as:
If you're able to wrap the content inside <a>
in a span
then try this.
HTML
<div class="beige">
<a class="green" href="#">
<span class="content">This is some text.</span><em class="red"></em>
</a>
</div>
CSS
.beige {
background-color: #EBDFA0;
height: 32px;
overflow: hidden;
border: 4px solid #EBDFA0;
white-space: nowrap;
width: 400px;
}
.green {
background-color: #4CA73D;
color: #222;
display: inline-block;
height: 100%;
text-decoration: underline;
vertical-align: middle;
}
.content {
display: inline-block;
height: 100%;
margin-left: 4px;
position: relative;
width: 100%;
max-width: 364px;
top: -50%;
}
.red {
border: 2px solid red;
display: inline-block;
height: 28px;
position: absolute;
width: 28px;
}
Essentially the <a class="green">
, <span class="content">
and <em class="red">
need to be display: inline-block
and the <span class="content">
has to be width: 100%
with a max-width
of the different between the <div class="beige">
and the <em class="red"
minus any additional padding/margin/border etc. (So in this example, max-width: 364px
) By setting a width on the span
you force the em
outside of it's container but by setting a max-width
you stop the em
from flowing outside of the main wrapper.
Here is a codepen.io link to an example.
(Note: Most of the CSS above is just to make the example look like your images.)
UPDATE:
To show or hide the <em class="red">
add the :hover
pseudo-class to .beige
and visibility or opacity to .red
. (Use opacity if you want to use a transition.)
.red {
opacity: 0;
}
.beige:hover .red {
opacity: 1;
}
Because the width of <div class="beige">
is unknown you can't use CSS to set max-width
on <span class="content">
.
(The 100% in max-width: calc(100% - 28px)
is width of <a class="green">
not <div class="beige">
. I couldn't hack it with pseudo-elements, positioning, floats or different display types like flex either.)
The way around this is to fix the max-width
of the <span class="content">
in CSS (as is shown above) or use Javascript to detect the width of <div class="beige">
and then set the max-width
.
content.style.maxWidth = beige.clientWidth - red.clientWidth + "px";
I updated the example with visibility and Javascript versions.
Also, I added position: absolute
to .red
so <span class="content">
doesn't have empty space on the right.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With