How to Mimic Android / iOS square buttons with plain HTML and CSS2? - html

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>

Related

Align image within a span to be to the right of a table cell

I made a JS Fiddle to show you what is currently happening.
https://jsfiddle.net/70z5Lm2r/2/
HTML
<table>
<tbody>
<tr>
<td class="first">
</td>
<td class="second">
<span>
<span onClick={doSomething} class="underline-hover">
<img src="pic.png" />
This is some clickable data. Sometimes it overflows.
</span>
</span>
</td>
</tr>
</tbody>
</table>
CSS
table {
table-layout: fixed;
word-wrap: break-word;
width: 50%;
max-width: 100%;
}
td {
border: 1px solid black;
}
.first {
width: 40%;
}
.second {
width: 60%;
}
.underline-hover:hover {
text-decoration: underline;
cursor: pointer;
}
img {
height: 20px;
width: 20px;
margin-top: 2px;
margin-left: 8px;
vertical-align: top;
float: right;
}
As you can see, if you hover over the user icon, the underline affect happens on the text. This is because both the text and the image are within the span that has the underline-hover class and the onClick handler applied.
What I want to have happen is that when a hover happens on the text, only the text is highlighted. When a hover happens on the icon, nothing happens. However, I still want the icon to be flush to the right and the text to wrap accordingly as it currently is displayed.
What I have tried is taking the img tag out of the inner span like so:
<span>
<span onClick={doSomething} class="underline-hover">
This is some clickable data. Sometimes it overflows.
</span>
<img src="pic.png" />
</span>
This satisfies the behavior but the float property of the img tag causes it to be removed from the flow of the page, causing the text and icon to jumbled together.
Any help achieving the behavior and look that I want would be greatly appreciated.
Your attempt was very close. Because you're floating the img right, it needs to be before the <span>.
<span>
<img src="pic.png" />
<span onClick={doSomething} class="underline-hover">
This is some clickable data. Sometimes it overflows.
</span>
</span>
Next, make a style for .underline-hover with a margin-right:20px; Currently the span fills the width of it's container, so the img isn't triggering the hover, the span is. We create a margin the same width as the floated img, and you should be good to go.

Icon left of multi-line heading

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/

Link with 2 lines text and image

How do i create a link like this with HTML and CSS:
It does not respond as i hoped it would.
What i try to accomplish is create a navigation link that hold a image on the left, and 2 lines of text right next to the image and not below the image.
html:
<div id="nav">
<img src="http://www.werkenbijavl.nl/images/WerkenBijAVL/icon-email.png" heigh="24px" width="24px" alt=""> Line 1<br><span>Line 2</span>
</div>
css:
nav a {
background: grey;
padding: 10px;
text-align: center;
text-decoration: none;
line-height: 24px;
vertical-align: middle;
}
nav img {
padding-right: 10px;
}
nav span {
font-style: italic;
}
Inline-block should fix your issues: http://jsfiddle.net/sZnaR/
The HTML:
<a href="#">
<img src="blah" />
<span class="text">
Line 1<br/>
Line 2
</span>
</a>
The CSS:
a {
display: block;
text-decoration: none;
}
a img {
display: inline-block;
width: 30px;
height: 30px;
}
a span {
display: inline-block;
}
Your text elements render as inline elements, and because of that, wrap underneath the image.
You're better off putting the image as a background image on the link using CSS then using Padding to align the text to the image, making sure you've allowed enough padding for the text to clear the image on the left. Also, use the background position to position the image to the right or wherever if you need it there. It also makes the HTML a lot cleaner and easier to read.
edit if you need dynamic images for each link you can always use an inline style to specify the background-image url.
You can also do this by floating it to the left.
Like this
<span style="line-height:15px;float:left">Line 1<br>Line 2</span>
Working Fiddle
HTML:
<div id="nav">
<a href="#">
<img src="http://www.werkenbijavl.nl/images/WerkenBijAVL/icon-email.png" heigh="24px" width="24px">
<div>
Line 1<br>
Line 2
</div>
</a>
</div>
CSS:
#nav img, #nav div{
float: left
}
This will make "Line 1", "Line 2" - and whatever lines you put in their - be always to the right of the image.
If you want text to wrap around the image, change your CSS to be:
#nav img{
float: left
}

Inline elements with wrapping text, not floated though and vertical aligned

I have a set of links which are stored within an unordered list. Inside each list item is:
The link which surrounds everything inside
An image on the left
Some text next to the image
An arrow next to the text to continue
The text could be any length, meaning the overall link could be any height. More importantly, the width of the overall link must be 100% (it's for a mobile phone so could be portrait / landscape).
To ensure that I do not need to set widths I have tried to avoid unnecessary containers, simply setting the image to be vertical align. The problem comes in that if my text is too long it wraps but appears below the image (makes sense just hoped it wouldn't), see here: http://jsfiddle.net/mP2fr/9/ (you may need to resize your browser window to see the effects). My solution was to put the text inside a and set to inline-block, but these defaults a width of 100% pushing it below the image. I can set a width which will bring it back inline (and allow for multiple lines) but this involves setting the width, see here: http://jsfiddle.net/mP2fr/7/
HTML 1:
<ul>
<li>
<a href="#">
<img src="http://www.mtlettings.co.uk/images/uploads/properties/191-9163_IMG_thumb.JPG" width="400" />
hello world asd ad asdasdg
</a>
</li>
</ul>
CSS 1:
li {
background: red;
}
a {
padding-right: 50px;
display: block;
background: url('http://www.perfectgetaways.co.uk/admin/system/preview/img_thumb_29706_125x125') no-repeat right center;
}
a img {
display: inline-block;
vertical-align: middle;
}
HTML 2:
<ul>
<li>
<a href="#">
<img src="http://www.mtlettings.co.uk/images/uploads/properties/191-9163_IMG_thumb.JPG" width="400" />
<span>
hello world asd ad asdasdg
</span>
</a>
</li>
</ul>
CSS 2:
li {
background: red;
}
a {
padding-right: 50px;
display: block;
background: url('http://www.perfectgetaways.co.uk/admin/system/preview/img_thumb_29706_125x125') no-repeat right center;
}
a img {
display: inline-block;
vertical-align: middle;
}
a span {
display: inline-block;
vertical-align: middle;
width: 160px;
background: aqua;
}
Got a solution, inspired by one of Anagio's comments. Involves setting the img and span to display as table-cells and the outer a tag to a display as a table. This positions the stuff side by side and allows for the text in the span tag to push down over multiple lines. Not great IE support as it breaks below IE8 but for my particular scenario which is a mobile app I'm satisfied. Here's the final code: http://jsfiddle.net/chricholson/xW3qr/2/
HTML:
<ul>
<li>
<a href="#">
<img src="http://www.mtlettings.co.uk/images/uploads/properties/191-9163_IMG_thumb.JPG" />
<span>
hello world asd ad asdasdg asdf asdf asdf asdfasdf
</span>
</a>
</li>
</ul>
CSS:
li {
background: red url('http://www.perfectgetaways.co.uk/admin/system/preview/img_thumb_29706_125x125') no-repeat right center;
}
a {
display: table;
}
a img {
margin: 0;
padding: 0;
display: table-cell;
vertical-align: middle;
width: 300px;
}
a span {
padding-right: 60px;
display: table-cell;
vertical-align: middle;
}

Cant vertically align text!

I know its extremely simple, but I have been coding all day and it doesn't seem to work.
I want the text to be vertically centered inside the box.. What am i doing doing?
http://jsfiddle.net/UAyNh/
UPDATE:
That worked for the text, but the buttons wont center. Check it out on Safari vs. Chrome.
http://jsfiddle.net/Bz9pB/
I give a container line-height equal to its height.
eg.
div.box
{
line-height: 40px;
height: 40px;
}
The only other way I know is to either use a table or replicate a table with CSS:
<div class="table">
<div class="row">
<div class="cell">
text
</div>
</div>
</div>
And
div.table{ display: table; }
div.row{ display: table-row; }
div.cell
{
display: table-cell;
vertical-align: middle;
}
Use line-height and make that equal to the height of the element (so long as your element only has one line, anyway):
height: 25px;
line-height: 25px;
JS Fiddle demo.
If the text will be on one line and the height of that line is similar to that in your example, you can solve it by setting the line-height:
height: 25px;
line-height: 25px;