I have a row of evenly-spaced navigation items, which looks like this:
The currently selected menu item is bold-italic. The designer wants the others to turn bold-italic on hover. When this happens, it makes the text of that item wider, which nudges all the other items over because they are displayed inline with a fixed margin. I have to get rid of the nudging.
What's the right way to fix this behavior? I have a couple ideas using javascript:
Onload, wrap the text up in divs and set the width of each div to the width of the text.
Onload, take the positions of each of the menu items relative to the div, then set their positions to absolute with the resulting coordinates (this would be okay because they are always in the same absolute position within the nav div).
These both seem a little hackish, and it's a pretty simple problem so I thought there must be an easier way.
I'm using jQuery if it makes a difference.
The following is a fairly minimal HTML page that will reproduce the issue:
<head>
<style type="text/css">
body {
background: black;
font-family: sans-serif;
}
a {
margin: 0px 20px;
font-size: 16px;
color: white;
text-decoration: none;
}
a:hover {
font-weight: bold;
font-style: italic;
}
</style>
</head>
<body>
<a id="projectslink" href="#projects">Projects</a>
<a id="innovationslink" href="#innovations">Innovations</a>
<a id="newslink" href="#news">News</a>
<a id="aboutlink" href="#about">About</a>
<a id="contactlink" href="#contact">Contact</a>
<a id="breathlink" href="#">Breath*</a>
</body>
I don't think there is an elegant solution to this time-old CSS problem... I can think of two "hackish" CSS solutions to choose from:
Give the items display: block-inline and a fixed width (in em, of course, to prevent font scaling / zoom problems). Width will differ from item to item if the padding should look consistent.
Hide the text and replace replace it with images.
In my opinion, your first solution (setting fixed width onload) isn't that bad. It "feels right" not to mess with position and is, at the very least, much less hackish than the alternatives.
To clarify, this is how I would implement your first solution:
HTML: no change
CSS: no change
JavaScript:
$(function() {
$('a').each(function() {
var menuItem = $(this);
menuItem.css({
'display': 'inline-block',
'width': menuItem.outerWidth(true),
'margin': 0,
'text-align': 'center'
});
});
});
As you can see:
There is no need to wrap the menu items in a div (just set display: block-inline from JS);
Each separate item can be kept centered by setting the width to the computed outerWidth() (which includes margin, padding and border width), clearing the margin and setting text-align to center.
Live example on JSFiddle.
Here's my solution:
http://jsfiddle.net/pRhKF/10/
Obviously you would have to adapt that to make it fit in to your own code. It makes all the as have the width they will have when the text is made bold by momentarily bolding them and then un-bolding them. Unfortunately I also had to use the hover event binder to achieve the mouse over effect, but maybe you can find a way around doing that...
Personally I like to give my nav some list markup, then give the anchor elements block display with a width:
http://jsfiddle.net/9AEnv/
I float the li, but you can also give them a display: inline-block if you want to avoid floats.
For posterity, this is the solution I ended up with: http://jsfiddle.net/jmcdon10/UdJZ5/
Mostly based on #Max's answer (which itself was a reworking of my first proposed solution), but using css hover instead of jQuery's hover event binder.
Related
It seems I've stumbled on an annoying Internet Explorer 11 layout bug. (Ugh, I thought these days were behind us.)
In the following example, the padding on the right table cell disappears when you hover over it in IE11:
http://jsfiddle.net/xx4Z4/
This seems to arise because of an incredibly specific CSS scenario:
The element uses display: table-cell
The element uses percentage-based padding, e.g., padding: 0 5%
A subelement adds text-decoration: underline when the parent element is hovered over
If you change any of those three things, the problem goes away.
This seems to be an IE11 bug, but I'm wondering: Can anyone think of a workaround for this problem without abandoning display: table-cell and percentage-based padding?
Again a IE11 problem that seems so unusual. I see that the percentage padding is not even calculated and is not applied in the layout. However the text is still padded according to the padding percentage. So i would assume the text is positioned with the padding but after the positioning the percentage padding is "disabled".
I can't tell you why this happens. But if you really want to fix these you might want to use these quick fixes.
Use margin
Because the percentage bug only occurs on the padding of a table-cell, you can actually use a margin on the span itself.
span
{
margin-left: 10%;
}
and ofcourse reset the padding of the sides:
div.table-cell {
display: table-cell;
padding: 20px 0;
}
This "solution" is not as dynamic as with percentage padding on the table-cell itself.
Why not?
It's because the percentage takes is value from it's parent element, the table-cell. Where as the table-cell did take it's percentage value based on the tabel. Now when you would just use left-margin: 5%;. It would be half of the space as it should be. This is because it take the 10% on the table-cell width. Where the table-cell width is table width devided by its cells(table width / table cell).
So to fix that i did 5 times the amount of cells (5 * 2 in this case), which would result in the right percentage.
However this is not dynamic when you want to add more cells.
jsFiddle
Use border
Use border which its position is "reserved" before the padding is resetted.
Reserved border
span
{
border-bottom: 1px solid transparent;
}
Change property that doesn't need re-calculation of position; color
div.table-cell-bug:hover span
{
border-bottom-color: black;
}
Now note that there will still be no padding in the layout. As soon as a property is assigned which has not been calculated before the padding did reset(the same time the text position is determed) the positions will be re-calculated.
jsFiddle
I hope one of these quick fixes work for you.
I see you sended a bug report to MS. Keep us up-to-date when you get a reply, i would appreciate it :)
Strange, no one mentioned to set table-layout:fixed; It's really important, otherwise the padding/width won't be calculated correctly on IE (and some other weird side-effects, depending on the use case), especially when you are using images inside it.
<style>
.table { display:table; table-layout:fixed; }
.table-cell { display:table-cell; }
</style>
<div class="table">
<div class="table-cell"></div>
<div class="table-cell"></div>
<div class="table-cell"></div>
</div>
Adding invisible top and bottom borders seems to fix the problem.
a {
border: solid rgba(0,0,0,0);
border-width: thin 0;
}
This prevents the anchors from moving on hover or focus.
I use rgba(0,0,0,0) instead of transparent for better compatibility with old IE which displays transparent in colour while rgba is rendered invalid and not displayed at all.
We had a similar scenario where none of the solutions above worked.
Instead we animate the width of our affected div after the page has loaded:
if (!!navigator.userAgent.match(/Trident\/7\./)){
$("#karina-rosner2").animate({'width': '20.1%'},1);
$("#karina-rosner2").animate({'width': '20%'},1);
}
This forces IE11 to recalculate the div's relative padding value and solved our problem well.
This can be "helpfully" solved by setting the paddding css-rules like this ->
element:hover,
element:active,
element:focus {
// padding example
padding-left: 1.5%;
}
Rememeber to set this only for IE since it can make all normal browser behave like a disco.
EDIT: Flexbox works for IE 10 and above so this "solution" is only needed for ie 9 and below.
These are all really good answers, and the media query option works well to identify only IE which has this problem with display:table-cell
What I did that I found worked well was employ vertical-align as a great way to direct the text contained within the display:table-cell element to where I wanted it to reside. Usually vertical-align doesn't do much to formatting, UNLESS it is in a table.
Here is my simplified HTML:
<li id="table-cell-element">
<a href="#">
<img src="event.png"/>
<small>Register for Event</small>
</a>
</li>
And here is the CSS:
#media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
li {vertical-align:middle; display:table-cell; width:15%; font-size:1.2em; line-height:1.2em; padding:2%; margin:0;}
li a {display:inline-block;}
li img {display:inline-block; vertical-align:middle; padding-right:5px; float:left; max-with:30px;}
small {display:block; font-size:60%; font-weight:bold; color:#333;}
}
You may also have to adjust the li a:hover {line-height} depending on what is in your CSS for those elements
Also, if you want this to work for IE 9 and below I suggest using conditional comments that add an "ie" class to the <html> tag and then create an IE9 style sheet. Thankfully the styling required for IE9 is relatively the same. But I only tested through IE9 and I am uncertain of your results for IE8 and IE7.
I know that transitions for the display property don't work, but I was wondering if there is a work around for this. I tried the visibility property but it doesn't seem to suit the task I am trying to achieve, or maybe I did it wrong. As you can see, I am displaying different text when you hover over the anchor tag by setting the span to display: none;. Animating the opacity won't be a good solution because the element being animated will still occupy the space it held. Is there maybe a workaround in Javascript or jQuery? Here is the code. I left out the transition property and its prefixes for brevity. The animation I want is for it to switch slowly between the two, i.e. One fades out, the other fades in. There doesn't have to be an overlap, but it doesn't matter if there is.
HTML
<div class="navbar">
<ul>
<li><a id="menu1" href="index.html"><i class="fa fa-home"></i><span> Home</span><span class="show"> Welcome Home</span></a></li>
</ul>
</div>
CSS
.show, a:hover span {
display: none;
}
a:hover .show {
display: inline;
}
You could try using jquery slide transitions when you hover over the anchor element. Check out http://api.jquery.com/slideToggle/
An example is
$("#menu1").hover(function () { $("#menu1 span").slideToggle("slow"); }, function(){ $("#menu1 span").slideToggle("slow"); });
You can try that on hover the object floats and animate the opacity. Making it float wont make him occupy the space.
Cheers J
I'm not really sure where to start on this, but I have a menu done in jquery. When you hover over right now, it does some fade in/out effects to the text, and links are manually handeled.
I wanted to add a simple line, maybe done in css? to go under each li a item when you are hovering as well, sliding to the li you hover over, not just appearing.
I just have no idea where to start with something like that, as I've never really done it before without an image (preferrably). It would of coarse need to start somewhere and move alone the ul and stop wherever it is when you leave the div with your mouse, and I'd like to keep it on when you click a link. I'm not asking anyone to make this for me though (unless you feel like it), just to get pointed on the right direction. I've seen some free codes with menus that do this, and attempted to use them, or model off them, but it woulnd't work with my menu.
Fiddle
I did this a while ago, maybe it is what you need. It will calculate the width of the anchor element you are hovering and grow an underliner element (a div) to both its width and position
//underliner
$('#menu a').hover(function(){
var position = $(this).position(); var width = $(this).width();
$('#underliner', '#menu').animate({width: width,left: position.left}, 200 );
});
$('#menu').hover(function(){
$('#underliner', '#menu').animate({opacity: 1}, 200).show();
}, function () {
$('#underliner', '#menu').animate({opacity: 0}, 200).hide();
});
CSS for the underline-element (change height and bg color as you seem fit)
#underliner {
display: none;
position: relative;
height: 5px;
line-height: 5px;
font-size: 1px;
background-color: #44c8f5;
width: 1px;
opacity: 0;
filter: alpha(opacity=0);
}
HTML
<div id="menu">
<ul>
list items with <a href>'s
</ul>
<div id="underliner"></div>
</div>
edit: I tried merging it with your code, but as you did not include the html, I had to guess how your 'navibar' was laid out. Anyway, try this fiddle: http://jsfiddle.net/c_kick/DuWcz/
plz see the below link :
Long File Name Inside A Div
when you see those long file names with firebug you will find a span that tell us ->
.FileName {
float: left;
width: 438px;
}
we have predefined width for this span!
q#1 : so why we have overflow in that div and how can i fix that ?
q#2(important) : is it possible to make that file name scrollable without showing scroll bars ?
edit
(with jquery or javascript or css)
thanks in advance
You have an overflow because this text can't break (there are no spaces):
R1DA029_APP_SW_1212_2395_GENERIC_KT_REDBROWNBLUE_CID52_49_DB3210
You could change the span's into div's and give them a height and an overflow:hidden.
Html:
<div class="FileName">R1DA029_APP_SW_1212_2395_GENERIC_KT_REDBROWNBLUE_CID52_49_DB3210 asangsm.com.rar</div>
Css:
.FileName{
float: left;
width: 438px;
height: 20px;
overflow: hidden;
}
I don't think it's possible to make that file name scrollable without showing scrollbars.
If you don't want a scrollbar, but do want to scroll, then the most apparent solution would be to use some javascript. If you're into jquery, here's some:
http://www.net-kit.com/jquery-custom-scrollbar-plugins/
I've tried one of them (http://www.demo.creamama.fr/plugin-scrollbar/), setting the div containing the text to overflow: hidden; and the div containing the scrollbar to display: none; to mimic your situation, and that gives me a scrollable div with no scrollbar.
However, I think from a UI point of view it's not the best idea to have a scrollable section without a scrollbar. At least something should light up (as with the Mac OS Lion scrollbars) indicating you can, or are, scrolling. You could style one of the javascript solutions out there to make this happen, for instance with a tiny scrollbar or indicator.
Short of using CSS3's marquee, I can see no simple solution. You would have to use Javascript.
As per avoiding the line break, you can use white-space: nowrap;.
Is there an easy way to have an HTML <textarea> alternate its row colors
to improve editing?
I don't mind if the solution is pure CSS or if it requires JavaScript.
textarea {
background-image: linear-gradient(#F1F1F1 50%, #F9F9F9 50%);
background-size: 100% 4rem;
border: 1px solid #CCC;
width: 100%;
height: 400px;
line-height: 2rem;
margin: 0 auto;
padding: 4px 8px;
}
Found this on codepen. Working for me.
If I understand correctly that you want the colors alternating WITHIN the textarea (as in each line)?
I would suggest the easiest method is to use a background image in your textarea's and have the rows of the alternate colors the same height as the font-size/line-height to create the illusion of alternate rows, then just repeat the background image.
Additional Solution
However, it seems that using that method, the background doesn't scroll along with each line.
The best technique I can come up with is to use a jQuery plugin called 'autoResize' by James Padolsey. What this does is removes the scrollbars and as your text nears the bottom of the textarea, the textarea height is increased accordingly.
Now, that can cause problems since you could potentially have VERY long textareas depending on how much text the user writes but I've created a fix for this.
What we can do is wrap the textarea in a div and set the overflow-y (vertical) to scroll and the overflow-x (horizontal) to hidden. What this does is now give us a "fake" scrollbar on our textarea, creating the illusion that it's scrollable so our background now appears as if it scrolls up and down with the text too.
You will have to adjust the width/height/margins/borders/paddings etc accordingly and maybe check for cross browser compatibility, but this should help set you on the right track and get you going.
Here is a link to an example I have created using the above method:
http://jsfiddle.net/HelloJoe/DmPLH/
CSS supports an nth child syntax now. Check out the MDN docs for an example of changing the background-color of only every other list item inside an unordered list:
HTML:
<p>NBA players with most championships:</p>
<ul>
<li>Bill Russell</li>
<li>Sam Jones</li>
<li>Tom Heinsohn</li>
<li>K. C. Jones</li>
<li>Satch Sanders</li>
<li>John Havlicek</li>
<li>Jim Loscutoff</li>
<li>Frank Ramsey</li>
<li>Robert Horry</li>
</ul>
CSS:
li:nth-child(even) {
background-color: lightyellow;
}
RESULT:
An example of making every other line in a textarea a different color by using CSS' nth-child syntax
SOURCE:
https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child