Aligning font-variant: smallcaps with other elements - css

I am having a bit of an issue with aligning elements vertically, as can be seen in the picture:
Namely, when font-variant: smallcaps is in effect, the span containing the text is no longer "centered" with the icon beside it, this is more apparent the bigger the "font" due to icon being a sized by the font-size.
I tried converting the span to a display:block element but couldn't manage to get it to work with vertical-align: middle, i tried turning it into display: flex and using align-items: center. No success, seems that only the display is "out of touch" while internally the text is properly sized. How would you fix this?
Fiddle: https://jsfiddle.net/1nzhgymf/
.menu-item {
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: center;
overflow: hidden;
width: 100%;
height: 2.8em;
color: inherit;
text-decoration: none;
text-transform: uppercase;
font-family: Roboto;
font-size: 20px;
flex-grow: 0;
flex-shrink: 0;
padding: 0.4em;
}
.icon {
min-width: 1em;
min-height: 1em;
background: red;
margin-right: 0.4em;
}
<div>
<a class="menu-item">
<div class="icon"></div>
<span>Example</span>
</a>
<a class="menu-item" style="font-variant: all-small-caps">
<div class="icon"></div>
<span>Example</span>
</a>
</div>

The initial attempt at an answer here incorrectly concluded that the em size of a font was affected by all-small-caps in CSS font-variant. This is not so (and certainly should not be, an em being fixed for a font/font size) but I keep this answer here rather than deleting it because the questioner has made some useful comments.
Here is a further attempt at an explanation:
The problem as stated was an issue with aligning elements vertically. An example was given of an all uppercase word appearing to align differently from one which was set at all-small-caps. In the screenshot below you can see variations on this - with a line which is all lowercase or all small caps seeming to be further down than the uppercase example.
In some sense this is true - in the uppercase example the mid line goes through the middle of the uppercase E and X which makes it balanced about the line. In the all-small-caps example though the capitals' centres have dropped below the mid line. The final line in the image shows why this is necessary - mixed text would otherwise be waving up and down.

Related

How to float an element to the right with inline display block while maintaining a centered vertical sibling?

Hi I'm currently trying to float my icon element to the right, while maintaining how its centered vertically next to its sibling element. I know float and display: inline-block can't coexist with each other. I've already tried using direction: rtl and text-align: right for my icon. I also don't want to hardcode by using pixels with margins/paddings, since I want this to be mobile-responsive. Are there any ideas?
Here's what the HTML would look like:
<span class='container'>
<p class='text'>Here is a lot of text and it is meant to overflow.</p>
<icon class='caret'></icon>
</span>
Here's my current CSS:
.text{
width: 340px;
display: inline-block;
vertical-align: middle;
}
.caret{
color: gray;
display: inline-block;
vertical-align: middle;
//float: right; //doesn't work
}
Photo Example of Desired Result:

Align flex-box items to baseline of last text line in a block

I am trying to achive the last example on the following image, using flex-box.
From what I see, the align-items: baseline; property works great when the blocks only have 1 line.
The property align-items: flex-end; creates some issues mainly because the left and right items have different font-sizes and line-heights. Although the edges of the items are aligned, the white space created by the font size and line-height differences looks really bad when the item has no borders.
I'm trying to find a good all-around solution without any JS.
Thanks in advance.
You can wrap the contents of the flex items inside inline-block wrappers:
.flex {
display: flex;
align-items: baseline;
}
.inline-block {
display: inline-block;
}
.item { border: 1px solid red; }
.item:first-child { font-size: 200%; }
.flex::after { content: ''; position: absolute; left: 0; right: 0; border-top: 1px solid blue; }
<div class="flex">
<div class="item">
<div class="inline-block">Lorem<br />Ipsum<br />Dolor</div>
</div>
<div class="item">
<div class="inline-block">Foo bar</div>
</div>
</div>
That will work because, according to CSS 2.1,
The baseline of an 'inline-block' is the baseline of its last line box
in the normal flow, unless it has either no in-flow line
boxes or if its 'overflow' property has a computed value other than
'visible', in which case the baseline is the bottom margin
edge.
At the time of writing the CSS box model alignment working draft proposes a ‘first’ and ‘last’ value to be added to ‘align-items’. The would allow:
align-items: last baseline
Current it only appears to be supported by Firefox so is one for the future.
https://developer.mozilla.org/en-US/docs/Web/CSS/align-items

How to change vertical alignment of content with a button element?

I'm working on a project where there is a row of controls, each of which is a button element. There is content inside of the buttons, and they are laid out in a row with flexbox. The button element centers its content vertically, and I can't figure out how to override it to vertically align it at the top of the button. The controls all need to be the same height and same width, and clicking anywhere in the borders must count as a click on the button.
This Codepen shows the problem clearly: http://codepen.io/anon/pen/RPpqdz
.wrapper {
display: flex;
flex-direction: row;
width: 80%;
}
button,
.object {
font-family: sans-serif;
font-size: 1em;
padding: 1em;
background: #fff;
flex: 1;
border: 1px solid red;
text-align: left;
}
<h1>What it looks like</h1>
<div class="wrapper">
<button>I am Content</button>
<button>I am Much Longer Content That Goes Here and Here</button>
<button>I am Content</button>
</div>
<h1>What I want it to look like</h1>
<div class="wrapper">
<div class="object">I am Content</div>
<div class="object">I am Much Longer Content That Goes Here and Here</div>
<div class="object">I am Content</div>
</div>
I realize this issue could be solved by not using button elements, but I also feel like I SHOULD be able to override this behavior of button elements. I'd like to figure this out for my own sanity!
Firstly, having h2 and p inside button is not valid HTML.
Secondly, there is no simple way to control the position of elements in a button, especially vertically.
But if you really really must use this BROKEN HTML, and only the top alignment is important, you can force the elements to take up fixed heights so that the button will align them at the top, like so:
button > h2 {
height: 48px;
}
button > p {
height: 16px;
}
I must say this is still not exactly the same as using <div>, so I don't know if this is sufficient.
In any case, do seriously try to convince those in charge of the "larger context of the project" to use proper valid HTML.
Edit:
If only inline elements are used inside the button, the problem becomes more manageable. The only caveat is: you need to know beforehand the height of the button. You can then simulate top-bottom flow using paddings.
button {
padding-top: 1em;
padding-right: 1em;
padding-bottom: 5em; /* make sure bottom + top padding == height */
padding-left: 1em;
height: 6em;
}
Still probably not ideal - feels like a heavily plastered hack solution.
*I'm not sure what do you want and what do you mean by "how to override it to vertically align it at the top of the button?"? but I hope this code is what you want.(same height, width and even with spaces also buttons matching with div (.objects).
.wrapper {
display: inline-flex;
display: -moz-inline-box;
width: 90%;
}
button, .object {
font-family: sans-serif;
font-size: 1em;
padding: 1em;
background: #fff;
border: 1px solid red;
text-align: left;
margin: 0em 0.3em 0em 0em;
}

Why does the display function interfere with text-align?

Alright, so I'm trying to make a line of different text bits in html/css. This will be the precursor for a navbar. My HTML is:
<div id="navBar">
<p class="navBartext">About</p>
<p class= "navbartext">News</p>
<p class= "navbartext">Contact Us</p>
<p class= "navbartext">Jobs</p>
</div>
and the CSS:
.navBartext{
text-align: center;
color:black;
font-size: 20;
font-family: 'Poiret One', cursive;
display: inline;
padding-right: 20px;
}
#navbar{
width: 100%;
height: 50px;
}
Now, when I take the "display: inline;" out of the code, the text aligns vertically instead of horizontally, and then I can use text align to position it, but I want them all in one line. When I use display-inline though it seems to completely circumvent the text-align function (as anything put in here will be ignored). Is there something I'm missing? Perhaps I just don't know enough about the display function.
If you want to align the words horizontally, you have to use display:inline-block; so that the elements will be treated as text. Always use inline-block for the child elements and text-align:center; for the parent.
p{
color:black;
font-size: 20;
font-family: 'Poiret One', cursive;
display: inline-block;
padding-right: 20px;
}
#navbar{
width: 100%;
height: 50px;
text-align:center;
}
VIEW DEMO
Try this, you can use <ul> element instead of div, div is better as a wrapper if u need wrap navBar:
[http://jsfiddle.net/WT7qv][1]
http://jsfiddle.net/WT7qv

How to vertically align 2 different sizes of text?

I know to vertically align text to the middle of a block, you set the line-height to the same height of the block.
However, if I have a sentence with a word in the middle, that is 2em. If the entire sentence has a line-height the same as the containing block, then the larger text is vertically aligned but the smaller text is on the same baseline as the larger text.
How can I set it so both sizes of text are vertically aligned, so the larger text will be on a baseline lower than the smaller text?
Try vertical-align:middle; on inline containers?
EDIT : it works but all your text must be in an inline container, like this :
<div style="height:100px; line-height:100px; background:#EEE;">
<span style="vertical-align:middle;">test</span>
<span style="font-size:2em; vertical-align:middle;">test</span>
</div>
the two set of text must have the same fixed line-height and the vertical-align set
span{
vertical-align: bottom;
line-height: 50px;
}
The functionality you are seeing is correct because the default for "vertical-align" is baseline. It appears that you want vertical-align:top. There are other options.
See here at W3Schools.
Edit W3Schools has not cleaned up their act and still, appear, to be a shoddy (at best) source of information. I now use sitepoint. Scroll to the bottom of the sitepoint front page to access their reference sections.
Easy way - use flex:
<div>
abcde
<span>efghai</span>
</div>
<style>
div {
padding: 20px;
background-color: orange;
display: flex;
align-items: center; }
span {
font-size: 1.5em; }
</style>
You technically can't, however, if you have fixed text sizes you could use positioning (relative) to move the larger text down and set the line-height to the smaller text (I'm presuming this larger text is marked up as such so you can use that as a CSS selector)
You can use percentage sizes to reapply the parent's line-height
.big {
font-size: 200%;
line-height: 25%;
display: inline-block;
vertical-align: middle;
}
Utque aegrum corpus <span class="big">etiam</span> levibus solet offensis
An option is to use a table there the different sized texts are in their own cells and use align:middle on each cell.
Its not pretty and does not work for all occasions, but it is simple and works with any text size.
This works
header > span {
margin: 0px 12px 0px 12px;
vertical-align:middle;
}
.responsive-title{
font-size: 12vmin;
line-height: 1em;
}
.responsive-subtitle{
font-size: 6vmin;
line-height: 2em;
}
<header>
<span class="responsive-title">Foo</span>
<span class="responsive-subtitle">Bar</span>
</header>

Resources