I'm trying to display an icon (font awesome) to the left of a heading, which currently works when the heading is on a single line, but the alignment gets messed up when the heading goes onto a second line.
What it currently looks like:
What I want:
Here's the simplest form of what I have (fiddle):
<div>
<h1><i class="fa fa-file-text fa-fw fa-lg"></i>Multi-line Title</h1>
</div>
I've tried separating the icon into a separate h1, then float or inline display each of those, but because it's multi-line text none of that has worked.
What's a clean way to get this alignment I'm looking for?
A little late to the party, but if anyone else is having the same issue - this is an easy fix with CSS Flexbox (which is a new...ish style, but by this point is pretty robustly supported).
(Note for code below: You can wrap the <i> in a <div>, or something else if necessary, but I would advise against including a second <h1> tag as that could cause SEO issues. Basically, you need the .wrapper class with two children - one as the icon (or a div containing the icon), and one as the header.)
First, the new HTML:
<div>
<i class="fa fa-file-text fa-fw fa-lg"></i>
<h1>Multi-line Title</h1>
</div>
And the new CSS:
div {
display: flex;
align-items: center;
}
Note: align-items: center; sets vertical alignment. This can also be flex-start (top-aligned) or flex-end (bottom-aligned) as desired.
Add this
div h1 {
display: inline-block;
position: relative;
padding-left: 55px;
vertical-align: middle;
}
div h1 i {
position: absolute;
left: 0;
top: 50%;
margin-top: -10px; // half height of icon
}
Fiddle
In this case, Using absolute positioning on the icon solves the problem. Besides, adjust it's top margin to align with the title text.
Fiddle: https://jsfiddle.net/0fadtcm7/
div h1 i {
position: absolute;
margin-left: -55px;
margin-top: 3px;
}
div h1 {
padding-left: 55px;
}
Just found an easier way to solve this.
HTML:
<div>
<h1 class="icon">
<i class="fa fa-file-text fa-fw fa-lg"></i>
</h1>
<h1>Multi-line Title</h1>
</div>
CSS:
div {
width: 225px;
background-color: #ccc;
padding: 10px;
}
.icon {
display: inline;
}
h1 {
display: inline-block;
vertical-align: middle;
width: 55%;
}
The most important point is to change the width to a suitable value.
Working JSFiddle here: https://jsfiddle.net/hfqoj5d9/
Related
Good evening dear community,
I am building one of my first HTML / CSS projects.
I want to arrange a h-tag and three small icon (webp-data) in a row.
What am I doing wrong?
I have all four elements framed in a div and have formulated both for the div and for the individual elements in CSS display: inline. The three icons appear side by side but the h-tag still behaves like a block element.
HTML
<div id="kanon-r">
<h2 id="kanon-h">KANON</h2>
<img src="republik.webp" alt="Republik-Logo" class="icon">
<img src="klonkriege.webp" alt="Klonkriege-Logo" class="icon">
<img src="imperium.webp" alt="Imperium-Logo" class="icon">
</div>
#kanon-r {
display: inline;
text-align: right;
position: relative;
}
#kanon-h {
display: inline;
position: relative;
}
.icon {
display: inline;
position: relative;
align-items: right;
It works for me.
https://codepen.io/deleite/pen/JjaPYxL
.icon {
display: inline;
position: relative;
align-items: right;
height:32px;
width:32px;
}
U are probably missing the size of the images? Maybe set the size first?
I just can't get the button with class align-right to vertically align in the middle.
HTML:
<div class="panel-footer">
<span style="width:100%;" class="header-footer-item">
<button class="align-right" type="button">Save</button>
</span>
</div>
CSS:
.panel-footer {
height: 70px;
vertical-align: middle;
border: solid;
}
.header-footer-item {
display: inline-block;
line-height: 70px;
border: solid red;
}
.align-right {
float: right;
}
.align-middle {
vertical-align: middle;
}
Here's the jsfiddle:
https://jsfiddle.net/d1vrqkn9/2/
If I remove float:right from the button, it works, but I want it on the right.
If I change header-footer-item from inline-block to inline then the floated button renders above its containing element, which I thought was against the rules: (#4 in the accepted answer here How to vertically middle-align floating elements of unknown heights?) - although the parent element is then vertically aligned in the middle.
I have added line heights as per CSS Vertical align does not work with float
The big question is - how do I fix it? I'm also interested to know why making a child element (the button) float right makes the parent element (the span) no longer vertically align in the containing div (but only if it is inline-block, not inline). ...and finally, isn't it 'against the rules' (https://www.w3.org/TR/CSS21/visuren.html#float-rules, #4) for a floating box's outer top to be higher than the top of its containing block? ...which it clearly is if header-footer-item is inline.
There are so many questions about vertically aligning things you'd think they'd make a css for "Seriously, vertically align this thing - no matter what, no complaints, just do it: sudo force vertical-align:middle !important or I'm coming for you"
The cleanest way to do that is to use flex like this:
Add display: flex to your outer div panel-footer [Check code below]
Remove the float and use text-align:right on the span for the button. [Check code below]
Add align-self: center to the inner span. [Check code below]
For 1:
.panel-footer {
height: 70px;
border: solid;
display:flex;
}
For 2:
.header-footer-item {
text-align: right;
}
For 3:
.header-footer-item {
align-self: center;
}
jsFiddle: https://jsfiddle.net/d1vrqkn9/4/
Here's a version with proper HTML, and just enough CSS.
.panel-footer {
height: 70px;
border: solid;
position: relative;
}
.panel-footer button {
position: absolute;
right: .5em;
top: 50%;
transform: translate(0,-50%);
}
<div class="panel-footer">
<button>Save</button>
</div>
There's an accepted answer already with some flexbox magic, here's an answer without it and the extra wrapping span element.
.panel-footer{
position:relative;
height: 200px;
border:1px solid #000;
}
.panel-footer button.align-right{
position:absolute;
right:0;
top:50%;
transform:translateY(-50%);
}
<div class="panel-footer">
<button class="align-right" type="button">Save</button>
</div>
If you don't need your button to be box-modeled then you can remove float:right; and add text-align:right to parent.
But I agree with previous answer that flexbox is pretty good answer to all positioning doubts.
Solution with text-align:
https://jsfiddle.net/d1vrqkn9/8/
Solution with flexbox:
https://jsfiddle.net/d1vrqkn9/9/
line-height will do. Try different height values.
<span style="width:100%; line-height: ??px;" class="header-footer-item">
In my point of view, trying to achieve that with a float element is a dead end.
If your goal is to have an element at the right inside another element, you better use another solution, like table positionning.
You just have to create the 4 following css class (the row element is not used in this case) :
.table {
display: table;
width: 100%;
}
.row {
display: table-row;
width: 100%;
}
.cell {
display: table-cell;
}
.cell-min-width {
display: table-cell;
width: 1%;
}
Then you just have to change your code for :
<div class="panel-footer table"> <!-- Position with table -->
<span style="width:100%;" class="header-footer-item">
<div class="cell"></div><!-- Empty cell to fill the left-->
<div class="cell-min-width"> <-- Cell with min width to fit the button -->
<button class="" type="button">Save</button>
</div>
</span>
</div>
https://jsfiddle.net/outch27/d1vrqkn9/366/
This seems almost impossible.
I am trying to create HTML/CSS-only square link buttons with text centered inside and without using CSS3.
I have tried variations of every answer I could find about vertically-centering text in an inline-block, but nothing that I try fulfills the following constraints:
The entire button element must be a link, not just the text.
The text inside the button element must be vertically and horizontally-center and wrap nicely if the width of the button element is not wide enough.
The height and width of all buttons should be the same.
The buttons must be placeable side-by-side horizontally and wrap to the next line below if the width of the browser is reduced or not enough to fit all buttons.
To ensure compatibility with older browsers, this solution must not require CSS3 (e.g. display:flex).
Think something like the side-by-side square buttons on the iOS and Android home screens but using simple and pure HTML/CSS. The shadowing, gradients, reflections aren't necessary, just the button structures.
I've tried nested divs using :before as a trick to vertically-align the text within an inline-block, I've tried using display:table with rows and cells, and I've even tried display:flex but that uses CSS3. No solution I tried fits all the criteria above.
So I'm wondering, is this even possible without CSS3? If so, what's the trick as I would have thought something like this would have been very straightforward to accomplish?
Yes, I believe this is possible, but it uses a lot of nested spans!
The craziest CSS used here is display: table and display: inline-block, so I think you should be pretty safe.
body {
font-family: sans-serif;
}
.special-button {
display: inline-block;
height: 100px;
width: 100px;
overflow: hidden;
position: relative;
background: #eee;
color: #333;
text-decoration: none;
}
.special-button:hover {
background: #333;
color: #fff;
}
.special-button-table {
display: table;
width: 100%;
height: 100%;
}
.special-button-cell {
display: table-cell;
vertical-align: middle;
text-align: center;
padding: 10px;
}
<a href="#" class="special-button">
<span class="special-button-table">
<span class="special-button-cell">Text Here</span>
</span>
</a>
<a href="#" class="special-button">
<span class="special-button-table">
<span class="special-button-cell">Longer Text Item Here</span>
</span>
</a>
<a href="#" class="special-button">
<span class="special-button-table">
<span class="special-button-cell">Text Here</span>
</span>
</a>
<a href="#" class="special-button">
<span class="special-button-table">
<span class="special-button-cell">Really Really Long Text Item That Overflows Here</span>
</span>
</a>
Ive possibly missed some details due to a very quick skim read - let me know how far off this is.
<style>
.ios li {
display: inline-block;
background: #eee;
padding: 5% 10px 20px 10px;
width: 100px;
max-width: 100px;
height: 50px;
max-height: 100px;
vertical-align: top;
text-align: center;
}
</style>
<ul class="ios">
<li>short text</li>
<li>much longer lot of text</li>
</ul>
I have a text element centered with text-align: center;, I want to place another element (a small inline <span>) to the right of it without affecting its position.
Neither of the elements (and especially the span) have a known size, so I can't use an offsetting margin on the left of the text element. Is there a way to do that in pure CSS?
Obligatory code that doesn't work:
<div style="text-align: center;">
<h3 id="centered-text">My centered text</h3>
<span class="to-the-right" style="background-color: blue;">BADGE</span>
</div>
how's this?
#centered-text {
display: inline-block;
}
#to-the-right {
display: inline-block;
position: absolute;
margin-left: 4px;
}
<div style="text-align: center;">
<div id="centered-text">My centered text</div>
<div id="to-the-right" style="background-color: blue;">BADGE</div>
</div>
I made your H3 not an H3 because it made the BADGE appear weirdly high above the title, but that could be easily corrected by giving the BADGE an attribute like "top: 10px;"
If you can put the h3 and the span inside a wrapper, you can center that wrapper, and position the span outside the wrapper using absolute positioning.
This may be a bit tricky if the h3 is full page width (the span will be outside of the visible area), or if the span contains a longer text (it may wrap awkwardly). However, it's a start, and those issues may not be issues to you.
.wrapper {
display: inline-block;
position: relative;
}
h3 {
display: inline-block;
margin: 0;
}
.wrapper span {
display: block;
position: absolute;
left: 100%;
top: 0;
}
<div style="text-align: center;">
<div class="wrapper">
<h3 id="centered-text">My centered text</h3>
<span class="to-the-right" style="background-color: blue;">BADGE</span>
</div>
</div>
Your css is off. Give your div an id and then
#divid {margin-left:auto; margin-right:auto; width:100%;}
h3 {text-align:center;}
A way to do this without using positioning is to use display: flex and a pseudo element. I personally think that oxguy3's way is better, but if you want to stay away from positioning then this will also do the trick.
span {
background: blue;
}
div {
display: flex;
justify-content: center;
}
div:before, span {
content: "";
flex: 1 1;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
<div>
<h3>My Centered Text</h3>
<span>BADGE</span>
</div>
This does have a few issues that may or may not matter based on your needs. If any other elements are needed in the div, then some reconfiguration is necessary, because any new elements also become flex-items and mess with the centering of the h3.
Also, as you may notice the span now extends to the edge of the div. If this is not a problem, then the markup is fine as is, but if it is a problem then wrapping it in another element also fixes this problem, like so:
span {
background: blue;
}
.container {
display: flex;
justify-content: center;
margin-bottom: 5%;
}
.container:before,
.badge {
content: "";
flex: 1 1;
}
* {
margin: 0;
padding: 0;
}
<div class="container">
<h3>My Centered Text</h3>
<div class="badge"><span>BADGE</span></div>
</div>
It's not perfect and, as I said, I like oxguy3's answer better, but if you want to stay away from positioning, then I think this is a good alternative.
Here's a codepen with both examples.
I have a div container in which there are already 2 spans: one floating left and one floating right. Now I want to add a third span that will be in the center of the div.
I've tried a ton of things, most promising tracks include things like this on the span that is supposed to be the center one:
position: absolute;
overflow: hidden;
display: inline-block;
margin-left: 0px;
margin-right: 0px;
I've even tried using the tags and coupled it with position:absolute which almost gives what I want except the centered text is on another line.
The left floating element has no styles to it as default is left floating
The right floating element has nothing except:
float:right;
The best way is to put text-align: center to the parent div:
div {
text-align: center;
}
div>span:first-child {
float: left;
}
div>span:nth-child(3) {
float: right;
}
<div>
<span>Left</span>
<span>Center</span>
<span>Right</span>
</div>
JSFiddle
Use auto margin left and right on an element you want to be centered:
margin-left:auto;
margin-right:auto;
If I correctly understood your problem, I have created an example fiddle http://jsfiddle.net/8e3au9ay/
Basically, in HTML, do something like following,
<div>
<span style="float: left;">span 1</span>
<span style="float: right;">span 2</span>
<span class="centered-span">span 3</span>
</div>
and in CSS,
div{
position: relative;
}
span.centered-span{
position: absolute;
left: 50%;
margin-left: -20.6px; //half of width
}
If I were you I would do this
Create Three spans with the same class
ex.
<span class="spanNext"> Span 1 </span>
<span class="spanNext"> Span 2 </span>
<span class="spanNext"> Span 3 </span>
Then I would use the following css on the class "spanNext"
.spanNext{
float: left;
width: 30%;
height: 50px;
}
This would set a global Class for all the three spans all using the same class which will always float left until end of page is reached since I am using percentage as a width.
Now If you want to add a margin to each span as a seperator / space between one span and another I would include the following
margin-left: 3px; //in the same css of class '.spanNext'
and to exclude the last div from having a margin left too You should include this in the css
.spanNext:last-child{
margin-left: 0px !important;
}
and if your are using SCSS / SASS {The Best in my Opinion}
.spanNext{
&:last-child{
margin-left: 0px !important;
}
}