I'm trying to put together a navigation bar using a table:
There are n links to different parts of the website
There is one "logout" link, which is an icon of fixed size
What I'd like to do is the following. The available width for the whole bar (which is known in advance) minus the required width of the icon should be divided equally among the cells containing the n links for navigation (ignoring the size of the links inside, this is not a problem).
Currently, I'm performing this computation in PHP and use to achieve this. However, this does not comply with the XHTML 1.0 Strict standards. According to the W3C validator, I should use CSS to set the width of the column. Problem is: I don't know how to do this, and if it is at all possible. Probably this problem is a hint that I shouldn't be using tables for this, but I have no other ideas at the time.
How can I achieve the effect, using tables or something else, in an XHTML Strict and CSS compliant way?
First off, scrap the tables. Your links are not tabular data.
Basics
Start off with this:
CSS
ul.navbar
{
padding-right: 25px;
list-style:none;
}
ul.navbar li
{
margin: 0px;
padding: 0px;
border: 0px;
display: block;
float: left;
}
ul.navbar li.icon
{
margin-right: -25px;
width: 25px;
float:right
}
HTML
<ul class="navbar">
<li>Home</li>
<li>FAQ</li>
<li>Contact</li>
<li class="icon"></li>
</ul>
Equal width
The icon li should be hugging the right edge. Now, there are a few ways you can acheive the equal spacing. One way would be to have these classes, and apply them to the ul, with either php or jquery:
CSS
ul.navbar.links1 li
{
width:100%;
}
ul.navbar.links2 li
{
width:50%;
}
ul.navbar.links3 li
{
width:33%;
}
ul.navbar.links4 li
{
width:25%;
}
ul.navbar.links5 li
{
width:20%;
}
jQuery
$(function()
{
var n = $("ul.navbar").children().length-1;
//Get the number of links: -1 because of logout
$("ul.navbar").addClass("links"+n);
});
Alternatively, you could just directly modify the width with jQuery or PHP. Up to you. Either way, you should use percentages.
$(function()
{
var n = $("ul.navbar").children().length-1;
//Get the number of links: -1 because of logout
$("ul.navbar").width((100/n)+"%");
});
The easiest way would be to put the links into little boxes (all the same size). Since CSS has no way to make calculations, you must still set the width of the boxes but by using CSS, you can do this once. Use DIV for the boxes. The class for the boxes must say display: inline; so they behave like words in text (the browser will place them next to each other on a line).
After that, you just calculate the width per box in PHP and send this width in a little piece of inline CSS in the header of the HTML page. That way, all boxes will have the same width and they will all be in the same line.
For an example how to create a navigation bar with CSS, look at the source code of the page you're reading just now.
Related
TL;DR : Before you read anything, the desired end-result is illustrated in the image below, otherwise refer to the JSFiddle. Preferably, I would like to only use CSS and not modify the DOM structure.
The icons must be aligned completely to the right (hence the .pull-right), but the icons must be stacked vertically (Sometimes some icons must not appear, so they are .hidden, like the .fa-undo icon in the second row).
(When I say 'the icons' i mean the <i> tags and the <img> tag)
The icons must not make the textarea go down (no margin on top of the textarea).
Hopefully, the WIDTH of the textarea would be dynamic and not statically put to width: 90%; for example. It should take as much width as possible, without interfering with the vertical icon stack.
Here is the end result that I want (in a perfect world this would be done using CSS and the same HTML DOM I provided)
In general, images that are UI elements, and not content, should be CSS backgrounds, not inline images. You then use class names to control the image content.
You should be doing this, or something similar:
td.fr {
background-image:url(/images/fr.gif);
background-repeat:no-repeat;
background-position: top right;
}
The same should go for your buttons. Use <button> and style the background.
Not exactly what you wanted I'm afraid, but this is how I'd achieve that result:
fiddle
<div class="pull-right icons">
<img src="http://www.convertnsftopst.net/images/gb.gif" class="pull-right" />
<i class="fa fa-reply"></i>
</div>
td .icons{
width:20px;
text-align:center;
}
Here is the end result that I want (in a perfect world this would be done using CSS and the same HTML DOM I provided)
I was unable to do it without adding another pull-right container, I fear that doing it with only CSS would end up being an odd hack
Fixed here : http://jsfiddle.net/QTXxp/2/
What was lacking when I asked this question was the clear:right; and the use of <div> (or display: block;)
Here is the CSS (if you're too lazy to open the JSFiddle) with the addition of the boostrap class pull-right on the div.icons
textarea.hover-edit {
width: 90% !important;
}
div.icons {
width: 10% !important;
}
div.icons > div > i.fa {
margin-top: 4px;
margin-right: 4px;
}
div.icons > div.action-icon-right {
float:right;
clear:right;
}
How to reduce the gap between two video tag, I have tried with margin and padding its not worked any help are appreciated
DEMO
My HTML
<div class="videoTest">
<video controls="controls"></video>
<video controls="controls"></video>
<video controls="controls"></video>
<video controls="controls"></video>
</div>
My CSS
.videoTest > video{
border:1px solid red;
margin:0;
padding:0;
}
The <video> element is an inline element by default. That's why there are gaps between them representing the whitespaces and/or line-breaks in your markup.
.videoTest > video {
display: inline-block;
border:1px solid red;
margin:0;
padding:0;
}
.videoTest {
font-size: 0;
}
By using font-size: 0, the line-breaks and whitespaces are being kind of ignored and you get rid of the gaps. Their size is set to 0.
Updated Fiddle
This is a common workaround when working with inline-blocks and is in some situations superior to floats when it comes to centering for example.
try this
http://jsfiddle.net/Ng6XU/5/
.videoTest > video{
border:1px solid red;
margin:0px;
padding:0;
float:left;
}
TRY THIS CSS :
.videoTest > video{
border:1px solid red;
margin:0;
padding:0;
float:left;
}
I have found the link which gives various method to solve this issue, may be helpful to some one Reference : http://css-tricks.com
Published April 21, 2012 by Chris Coyier
Here's the deal: a series of inline-block elements formatted like you normally format HTML will have spaces in between them.
In other words:
<nav>
One
Two
Three
</nav>
nav a {
display: inline-block;
padding: 5px;
background: red;
}
Will result in:
Often highly undesirable (check the link for the output)
We often want the elements to butt up against each other. In the case of navigation, that means it avoids the awkward little unclickable gaps.
This isn't a "bug" (I don't think). It's just the way setting elements on a line works. You want spaces between words that you type to be spaces right? The spaces between these blocks are just like spaces between words. That's not to say the spec couldn't be updated to say that spaces between inline-block elements should be nothing, but I'm fairly certain that is a huge can of worms that is unlikely to ever happen.
Here's some ways to fight the gap and get inline-block elements sitting directly next to each other.
Remove the spaces
The reason you get the spaces is because, well, you have spaces between the elements (a line break and a few tabs counts as a space, just to be clear). Minimized HTML will solve this problem, or one of these tricks:
<ul>
<li>
one</li><li>
two</li><li>
three</li>
</ul>
or
<ul>
<li>one</li
><li>two</li
><li>three</li>
</ul>
or with comments...
<ul>
<li>one</li><!--
--><li>two</li><!--
--><li>three</li>
</ul>
They're all pretty funky, but it does the trick.
Negative margin
You can scoot the elements back into place with negative 4px of margin (may need to be adjusted based on font size of parent). Apparently this is problematic in older IE (6 & 7), but if you don't care about those browsers at least you can keep the code formatting clean.
nav a {
display: inline-block;
margin-right: -4px;
}
Skip the closing tag
HTML5 doesn't care anyway. Although you gotta admit, it feels weird.
<ul>
<li>one
<li>two
<li>three
</ul>
Set the font size to zero
A space that has zero font-size is... zero width.
nav {
font-size: 0;
}
nav a {
font-size: 16px;
}
Matt Stow reports that the font-size: 0; technique has some problems on Android. Quote: "Pre-Jellybean does not remove the space at all, and Jellybean has a bug whereby the last element randomly has a tiny bit of space." See research.
Also note, if you're sizing fonts in ems, this zero font size thing can be an issue, since ems cascade the children would also have zero font size. Rems would be of help here, otherwise any other non-cascading font-size to bump it back up.
Another weirdness! Doug Stewart showed me that if you use #font-face with this technique, the fonts will lose anti-aliasing in Safari 5.0.x. (test case) (screenshot).
Just float them instead
Maybe they don't need to be inline-block at all, maybe they can just be floated one way or another. That allows you to set their width and height and padding and stuff. You just can't center them like you can by text-align: center; the parent of inline-block elements. Well... you kinda can but it's weird.
Just use flexbox instead
If the browser support is acceptable to you and what you need out of inline-block is centering, you could use flexbox. They aren't exactly interchangeable layout models or anything, but you might get what you need out of it.
Since the video tag defaults as an inline-block element, simply make the video tag a block element in CSS. Bob's your uncle.
video {display: block;}
In my case, I was using 640x480 for the video size. I changed it to 640x360 and that removed the white space above the video.
I would say that in my case setting this css helped:
height:auto;
I'm trying to stray away from using tables to form the layout of my content, and I can think of two alternatives that I'd like to better learn: (1) styling list items to be side-by-side, and (2) using div blocks that float onto the same line. Both of these would have their own uses for what I'm working on.
I'm already using div tags to form the entire layout of my three-column template, but what I need to do now is a bit different. In case it helps, my project can be found here.
In short, here's my question; how would I style a div so that the width of it is 50% of the width of the area it occupies, rather than 50% of the width of the page?
As for my other question, what would be the best approach to styling list items so that they are side-by-side? I'm working on a registration script now, and instead of using a table with "Username" on the left and the input text on the right, I can use two list items.
It's late and I've been working on this project of mine for about 8 hours straight now, so I apologize if I'm asking anything confusing. Feel free to ask me any questions about what I'm trying to do.
Thanks, friends. :)
When you use percentage units for widths and heights, it is relative to the first ancestor element which has defined a width or height. Therefore, all you need to do is set up a div which is as wide as two columns:
<div class="columnContainer">
<div class="column">
Column 1
</div>
<div class="column">
Column 2
</div>
</div>
.columnContainer {
width: 800px;
}
.column {
float: left;
width: 50%;
}
There's a lot more fiddling about required than just the code above, but that's the basics. As Gabriel said, you might get a lot of value out of using a CSS framework like 960.gs
ok, so to help you out best I am going to point you to http://960.gs this is a great tool for prototyping this sort of scenario and getting solid reliable code. On to your actual issue, you probably want to set:
width: 50%;
float: left;
display: block;
on the elements you want split. Good luck.
For the width, any relative sizing is relative to the parent, so put it as a child inside the element you want to be half of. For the list items... use display: inline; or float: left;
Inline list are simple but have some drawbacks, you cant set height or width for example.
ul li {
display:inline;
}
If you need block elements you need to float list items and floats can be tedious sometimes, for example you need to take care of clearing [uod]l element.
ul {
overflow:hidden;
}
ul li {
float:left;
display:block;
}
You probably want to remove margins and paddings on list itself in both cases.
ul {
margin:0;
padding:0;
}
How can I vertically align items in an unordered list to work in IE6 and 7?
I can't just set line-height to the full height because I have both 1 row items and 2 row items.
My code is:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<style type="text/css">
ul {
list-style: none;
border: 1px solid black;
height: 40px;
}
li {
float: left;
margin-right: 10px;
height: 40px;
width: 46px;
}
a {
}
</style>
</head>
<body>
<ul>
<li>
item1
</li>
<li>
two lines
</li>
</ul>
</body>
</html>
You cannot float your items to the left and expect them to vertically line up....
Remove
float: left;
From the LI style...
if i understand correctly you want to use the float to shrink wrap the li?
If thats the case you need to set
li {clear:left;}
So the lis are below each other, not next to each other. You can also use inline-block if you want the li to shrink wrap to the content.
Also, depending on the goal of this, it might be approproate to use a table, depending on what it will be used for.
Sorry if this isn't a proper answer, but it may help clear things up:
Why are you using floats instead of display: inline for your list items?
The rows essentially be the same height. So there is no way to effectively "merge cells" in table speak. You should set the line height to the height of the "two line" items and then use the vertical-align property to align them.
If I understand correctly, you want a horizontally displayed list where each item has a set width and height, but the text inside is vertically centred, and there may be items that have two lines of text.
If you know pre-rendering which items will be two lines you can apply the a CSS class that sets the line-height: 40px; only on those items with a single line. This is not normally the case thought, so the best way to go is to use JS to dinamically alter the line-height after the list has been rendered.
See this jsfiddle: http://jsfiddle.net/UEsAS/2/
In essence, alter your CSS to not set a height on the lis (this will cause them to be have a lower height if they are one-line, which is how you can detect which ones to alter). Then run the following (assuming jQuery):
$(function() {
var maxHeight = 40;
$('li').each(function(i, el) {
if ($(el).height() < maxHeight) {
$(el).css('line-height', maxHeight + 'px');
}
});
});
I have several NAV Bars. Each NAV Bar is of the pattern;
a | a
such that where the literal "|" occurs, it's always has a sibling a on the left.
where a is an html anchor element and "|" is a literal separator of interest.
What css can I use to capture that literal "|"? The idea is that I want to set it display:None for print media.
Thanks for any help.
My recommendation would be to use an unordered list
<ul class="myNav">
<li><a>My Nav</a>
<li class="last"><a>Another nav</a>
</ul>
And then float the list items left, and then put a border on one side of each list item. Now the CSS below isn't exact, but it gives the general idea
.myNav li {float:left;border-right:1px solid black;}
.myNav li.last {border-right:0}
That should look similar, and be 100% css for seperators.
CSS selects html elements. | is not an html element, it's a text node, you can't access it. However, you can probably use background images on the anchors instead, and make them the divider. That or wrap spans around the divider and target them.
<span class="divider">|</span>
or
#nav a { background:url(/images/divider.gif) no-repeat top left; }
#nav li.last a { background-image:none; }
I didn't mention borders because they would rely on the height of the element being applied to and assumed you wanted more control, more customized but you could of course use those.
You need hooks to select anything with CSS. If the "|" characters aren't marked up in some way, you can't select them. Put them in span elements, or, better yet, replace them with background images, and define your navigation as a real list.
Yeah, you'd have to surround them, with say a span element. Then give those spans a class of "pipe" or something. Then use the CSS class "pipe" to set the display to none for printing.
You could position the parent element outside but the a elements inside the viewport. Something like this:
div {
position: relative;
top: -10em;
}
div a {
position: relative;
top: 10em;
}
But you should better use a list for your navigation and format that:
<ul id="nav">
<li>first</li>
<li>second</li>
<li>third</li>
</ul>
#nav, #nav li {
list-style: none;
margin: 0;
padding: 0;
}
#nav li {
float: left;
}
If you just need a simple text divider, using the content property is a fast, semantic way to achieve this.
<div id="nav">
Nav1
Nav2
</div>
#nav a + a:before { content: '|'; }
Note that content and adjacent sibling selectors (the + in the selector above) don't work in older browsers like IE6, but since this is just a divider, it shouldn't be a huge concern.
Edit: Note that this will make the | appear inside the link, so you should use a list instead (that is also the correct way to mark this up anyway).