Reputation: 1639
I have a container with two other pieces of text inside it - a title and a description, for example:
.item {
box-sizing: border-box;
width: 33%;
text-align: center;
padding: 20px;
border: 1px solid #CCC;
min-height: 200px;
margin: 20px;
}
.item-title {
font-size: 28px;
margin-bottom: 15px;
}
.item-description {
font-size: 12px;
}
<div class="item">
<div class="item-title">Title</div>
<div class="item-description">Some descriptive text</div>
</div>
<div class="item">
<div class="item-title">A Much Longer Title</div>
<div class="item-description">Some other descriptive text</div>
</div>
Here's a diagram of the desired effect:
What I'd like is for the title to be vertically-centred at the same point (blue line), no matter how many lines it wraps over. The description should always stay underneath, the same distance away from the title, top-aligned (red line). So the blue line doesn't move but the red line can.
What I've tried so far:
Applying a negative Y transform to the title. This worked in that it moved the title up, but the description text did not follow it.
Margins: tried setting a percentage vertical margin but of course this is relative to the parent's width rather than the height of the element, it didn't have the desired effect.
Flexbox: same sort of result as margins.
position: absolute on the title. Works to vertically align the title but then makes it very difficult to align the description.
After experimenting for a while and a lot of reading up, it seems like it might not be possible, but if anyone's managed to solve this I'd be very interested to know how.
Upvotes: 3
Views: 1031
Reputation: 371231
I agree with you. I don't think this is possible with CSS alone.
Your requirements:
What I'd like is for the title to be vertically-centred at the same point (blue line), no matter how many lines it wraps over. The description should always stay underneath, the same distance away from the title, top-aligned (red line). So the blue line doesn't move but the red line can.
The following solution satisfies requirement #1 (blue line). The titles are centered along the same horizontal line.
Make the top-level parent (.item
) a flex container.
Give the first child (.item-title
) a set proportion of the container space. In my example below, I used flex-grow: 3
.
Also give the second child (.item-description
) a set proportion of the container space. I used flex-grow: 1
.
Now vertical centering can be uniform across both containers because they are occupying the same proportions of free space.
However, the descriptions will also be a proportional distance away from the title element, and cannot remain anchored to the same horizontal axis (red line).
.item {
display: inline-flex;
flex-direction: column;
vertical-align: top;
width: 33%;
text-align: center;
padding: 20px;
border: 1px solid #CCC;
min-height: 200px;
margin: 20px;
box-sizing: border-box;
}
.item-title {
flex: 3;
font-size: 28px;
display: flex;
align-items: center;
justify-content: center;
border: 1px dashed red;
}
.item-description {
flex: 1; /* also try flex: 2 for a narrower gap between items */
font-size: 12px;
border: 1px dashed red;
}
hr {
position: absolute;
top: 100px;
background: blue;
width: 95vw;
}
<div class="item">
<div class="item-title">Title</div>
<div class="item-description">Some descriptive text</div>
</div>
<div class="item">
<div class="item-title">A Much Longer Title</div>
<div class="item-description">Some other descriptive text</div>
</div>
<hr>
The following solution satisfies requirement #2 (red line). The descriptions are always the same distance away from the title. However, the titles are no longer anchored to the same horizontal axis.
.item-title {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
flex: 1;
font-size: 28px;
border: 1px dashed red;
}
.item-description {
margin-top: 5px;
font-size: 12px;
}
hr {
position: absolute;
top: 100px;
width: 95vw;
}
/* non-essential decorative styles */
.item {
display: inline-flex;
vertical-align: top;
width: 33%;
text-align: center;
padding: 20px;
border: 1px solid #CCC;
min-height: 200px;
margin: 20px;
box-sizing: border-box;
}
<div class="item">
<div class="item-title">Title<span class="item-description">Some descriptive text</span>
</div>
</div>
<div class="item">
<div class="item-title">A Much Longer Title<span class="item-description">Some other descriptive text</span>
</div>
</div>
<hr>
Upvotes: 2