I am trying to create tabs that resize a bit similar to how Chrome tabs does. But I am not sure how and if it is even possible to do without JavaScript.
I don't care about browser support, I only want to see if it can be done with pure html and css/css3.
Here is the spec:
The tabs are never wider than the text inside them
When the right most tab reaches the right side of the window on resize, the tabs should start shrinking (ideal is that this happens to the widest tab first)
the active tab should never shrink
As the tabs shrink, the text should be hidden by ellipsis
the tabs will stop at a min-width that I set (so they can't go to zero width).
Can this be made with something like display: box; and box-flex: 1; properties perhaps? I haven't managed to make it yet. I have already made it with JavaScript. But the performance is not as good as I want it to (this is a BIG wep app).
So, any CSS-Gods out there up for it? If there is a way to do it with very limited use of JavaScript, I am also interested.
Thanks all!
You can get pretty close to Chrome's actual behavior with the flexbox...
body {
font: 12px/130% 'Lucida Sans', 'Lucida Sans Unicode', 'Lucida Grande', sans-serif;
}
ul {
background-color: #eee;
display: -webkit-box;
padding: 10px 10px 0 10px;
}
ul li {
-webkit-box-flex: 1;
background: #ddd;
padding: 10px 15px 6px 15px;
white-space: nowrap;
overflow: hidden;
max-width: 150px;
min-width: 50px;
border: solid #ccc 1px;
border-bottom: none;
border-radius: 5px 5px 0 0;
text-overflow: ellipsis;
}
http://jsfiddle.net/a656n/
​However, your specs are impossible in CSS only. I'd also suggest that keeping the active tab 'unshrunk' breaks conventions because your tabs will change position every time you click on them.
I improved on Duopixels anwer by using one extra <span> element and display: table-cell instead of the flexbox implementation. This way you achieve better cross-browser support/fallback. http://jsfiddle.net/w34nm/ (Tested in IE8+, Firefox 10, Chrome 17)
PS: you should probably use JavaScript to set the right width values on the list items
Well, first of all, your desired functionality is not how tabs in Chrome work, they simply remain a fixed size until there is not enough room, and then they shrink uniformly to fit. (According to MDN, You could accomplish this:
To make XUL elements in a containing box the same size, set the
containing box's equalsize attribute to the value always. This
attribute does not have a corresponding CSS property.
)
Also, a visual representation of what you are looking for would be very helpful, I found some of the demands rather confusing.
Nonetheless, I've scrapped together this. Let me know if it is at all close.
ul{
display: -webkit-box;
width:500px;
background:lightgray; text-align:left;}
li{background: gray; text-align:center; height:24px; -webkit-box-flex: 1; min-width:30px; max-width:100px; overflow:hidden; text-overflow: ellipsis; }
Related
It seems there is some magic around the <button>element that I don't understand.
Consider this markup:
<button class="button">Some Text</button>
<div class="button">Some Text</div>
And this CSS:
.button{
background: darkgrey;
height: 40px;
border: 2px solid grey;
width: 100%;
box-sizing: border-box;
font-size: 14px;
font-family: helvetica;
text-align: center;
margin-bottom: 20px;
/*I'm aware I could use this to center it*/
/*line-height: 40px;*/
}
What makes the text in the button element vertically centered? Webkit seems to predefine a -webkit-box-align with a value of center for the <button> element. If I set that to initial the text is no longer aligned to the center. But that doesn't seem to be the full magic, since on the other hand I had no luck centering the text on the div using the -webkit-box-align property.
Here is a fiddle: http://jsfiddle.net/cburgdorf/G5Dgz/
I know this is a couple of years old, but I'll add my thoughts after some investigation in to issue while writing a reset stylesheet for a project.
NOTE** This is based on looking through the Firefox source because it was the easiest to obtain and read through. However, based on similar behaviour in other browsers the implementation is probably similar.
Firstly, the main issue here is that <button> elements - atleast in Firefox - are built with an internal element between the <button> tag and it's children. In Firefox it's called moz-button-content and isn't something that can be reached with CSS and has been set to display block without inheriting the height of the button, you can see this style declaration in the useragent stylesheet:
From "source/layout/style/res/forms.css"
*|*::-moz-button-content {
display: block;
/* Please keep the Multicol/Flex/Grid/Align sections below in sync with
::-moz-scrolled-content in ua.css and ::-moz-fieldset-content above. */
/* Multicol container */
-moz-column-count: inherit;
-moz-column-width: inherit;
-moz-column-gap: inherit;
-moz-column-rule: inherit;
-moz-column-fill: inherit;
/* Flex container */
flex-direction: inherit;
flex-wrap: inherit;
/* -webkit-box container (aliased from -webkit versions to -moz versions) */
-moz-box-orient: inherit;
-moz-box-direction: inherit;
-moz-box-pack: inherit;
-moz-box-align: inherit;
/* Grid container */
grid-auto-columns: inherit;
grid-auto-rows: inherit;
grid-auto-flow: inherit;
grid-column-gap: inherit;
grid-row-gap: inherit;
grid-template-areas: inherit;
grid-template-columns: inherit;
grid-template-rows: inherit;
/* CSS Align */
align-content: inherit;
align-items: inherit;
justify-content: inherit;
justify-items: inherit;
}
Because you can't affect any of the styles on this element, you are forced to add you styling on the <button> tags. This leads into the second issue - The browser is hard coded to vertically position the content of the button.
From "source/layout/forms/nsHTMLButtonControlFrame.cpp"
// Center child in the block-direction in the button
// (technically, inside of the button's focus-padding area)
nscoord extraSpace =
buttonContentBox.BSize(wm) - contentsDesiredSize.BSize(wm);
childPos.B(wm) = std::max(0, extraSpace / 2);
// Adjust childPos.B() to be in terms of the button's frame-rect:
childPos.B(wm) += clbp.BStart(wm);
nsSize containerSize = (buttonContentBox + clbp.Size(wm)).GetPhysicalSize(wm);
// Place the child
FinishReflowChild(aFirstKid, aPresContext, contentsDesiredSize,
&contentsReflowInput, wm, childPos, containerSize,
ReflowChildFlags::Default);
Given these two issues you can start to see how the button force the content to be centered, consider:
<button> tag
+------------------------+ ^
| button extra space | |
| | |
+------------------------+ |
|| ::moz-button-content || | button height
|| display: block; || |
+------------------------+ |
| | |
| button extra space | |
+------------------------+ v
If you give the button a height - like the 48px from your fiddle, the text will be centered because the moz-button-content element is display block and will only have the height of the content (most likely the line-height of the content by default) and when put next to another element you get this behaviour:
* {
box-sizing: border-box;
margin: 0;
border: 0;
padding: 0;
font-family: san-serif;
background: none;
font-size: 1em;
line-height:1;
vertical-align: baseline;
}
button, a {
height: 3em;
}
button {
background: red;
}
a {
display:inline-block;
background: green;
}
<button>Button content</button>
<a>Link Content</a>
This bug and this bug in the Firefox issue tracker was about a close as I could find to any actually documented bug. But the threads give the impression that despite this not appearing in any actual spec, the browsers have just implemented it this way "because the other browsers are doing it that way"
There is a work-around to the issue if you actually want to change the default behaviour, but it doesn't completely solve the problem and YMMV depending on your implementation.
If you insert a wrapper <span> with display: block as the only child of the button and put all your content inside it you can use it to skip over the moz-button-content element.
You will need to make this <span> element have height: inherit so it correctly fills the height of the button and then add your normal button styling to the <span> instead, you will get basically behaviour you want.
* {
box-sizing: border-box;
margin: 0;
border: 0;
padding: 0;
font-family: san-serif;
background: none;
font-size: 1em;
line-height:1;
vertical-align: baseline;
}
button, a {
height: 3em;
}
button {
background: red;
}
button::-moz-focus-inner {
border: 0;
padding: 0;
outline: 0;
}
button > span {
display: block;
height: inherit;
}
a {
display:inline-block;
background: green;
}
button.styled > span , a.styled{
padding: 10px;
background: yellow;
}
<button><span>Button content</span></button>
<a><span>Link Content<span></a><br/>
<button class="styled"><span>Button content</span></button>
<a class="styled"><span>Link Content<span></a>
It's also worth mentioning the appearance CSS4 rule (Not yet available):
While this is not a viable option (as of the 5th January) yet. There is a proposal to redefine the appearance rule in the CSS4 draft that might actually do the right thing an remove all assumptions made by the browser. I only mention it for completeness because it may become useful in the future.
UPDATE - 30/08/2016
You should actually use a <span> instead of a <div>, as div's aren't valid children for <button> elements. I have updated the answer to reflect this.
You could use padding.
For example
padding: 20px 10px;
I think that the only reason for this behaviour is that Google Chrome or browsers in general will take the default styles from your operating system.
For example, if you compare the button or scrollbar on Google Chrome run in windows 7 and windows 8:
In windows 7, the button will have a horizontal gradient line in the center of your button
In windows 8, the scrollbar are able to fade in and fadeout on click
This is just my opinion but hope that it can give you some ideas :)
You can use display:table-cell;
vertical-align: middle; as an alternate method.
On Mozilla Firefox I got the -moz-appearance property :
-moz-appareance: button;
In the HTML5 draft, there is a Rendering section, but doesn't details the placement :S
Button elements by default centers child elements vertically. It isn't done in a conventional CSS way, and therefor isn't trivial to override.
The best solution I have found is setting the button to flex column.
button {
height: 100px;
display: flex;
flex-direction: column;
}
span {
height: 20px;
width: 100px;
background-color: blue;
display: block;
}
<button>
<span></span>
</button>
Some answers suggested adding an inner wrapper, and setting it's height to inherit. This might not work for elements that have their height calculated dynamically.
In case you need to get rid of this behavior you can just add span as a child of button. Works better than trying to trick all the browsers.
I'm working on a project to upgrade a system to use the button tag rather than regular submit buttons. For the formatting of the buttons, I have the following CSS classes:
button::-moz-focus-inner {
border: none; /* overrides extra padding in Firefox */
}
button {
background: transparent url('images/greenrightbutton.png') no-repeat scroll top right;
color: #FFFFFF;
display: block;
font: normal 12px arial, sans-serif;
height: 25px;
padding-right: 8px; /* sliding doors padding */
padding-top: 0px;
padding-bottom: 0px;
padding-left: 0px;
margin: 0px;
text-decoration: none;
border: 0px;
overflow: visible;
}
#loginbox button {
float: right;
}
button span {
background: transparent url('images/greenleftbutton.png') no-repeat top left;
display: block;
line-height: 18px;
padding: 4px 5px 5px 12px;
margin: 0px;
border: 0px;
}
They work absolutely perfectly in every browser except IE8.
In IE8, the buttons work in most places, but then I find a page where the two background images don't quite line up and no amount of tweaking padding, line spacing etc fixes it.
Does anyone know why this might be the case?
Demo page: http://test6.placement.co.uk/demo/test.asp
---Update---
After some fairly extensive testing and trying things, I've now got a pretty fair idea of what's causing the problem in page 1, but no idea how to fix it, while another page with the same issue has a completely different cause (which I haven't found) but where I HAVE stumbled on a fix...
The problem on the first page appears to relate to a ul entered further up the page. Take that out and everything behaves - unfortunately, that's not an option as the ul is part of user-entered content, so I'm scratching my head about that. Particularly given...
Page 2 has no uls to cause an issue, but randomly sticking two break tags in just before my button code resolves the problem.
Naturally, THAT fix doesn't work on page 1.
I'm just about ready to give in and find some alternative way of rendering these buttons, because whatever the actual problem is, it's clearly so deep in either my CSS or my basic HTML that I'm probably never going to find it.
I don't see any difference between IE8 and other browser. Could you pleas mention bit more clear what you want to do?
When I declare this style for a div:
#fbInner{
position: absolute;
margin: 11.2% 9.7% 0% 26.4%;
width: 63.5%;
height: 54.6%;
overflow: visible;
/*max-height: 190px;
max-width: 490px;*/
font-size: 11px;
font-family: "lucida grande",tahoma,verdana,arial,sans-serif;
color: #FFF;
/*border: solid 2px gray;*/
}
Chrome sets every margin right except of the margin top, which is set much smaller than in other browsers ... strange, all other margins are displayed like it should ...
What is the reason for that?
Is there a workaround that still uses percentages?
Seeing as this is an x-browser css question, resetting the css styles would be a valuable first step - maybe even the solution. You haven't disclosed any HTML code, so I can't know what other tags or styles are affecting #fbInner
In any case, here is the "meyerweb reset" stylesheet: http://meyerweb.com/eric/tools/css/reset/
Link it topmost in your HTML file. It will probably break your site, but that's a good thing. At least it should be equally broken in all browsers now. When you've fixed the look of your page, it should work properly in most/all browsers.
In order to make all my links looks like buttons, I've done that in my CSS:
a {
color: #06A;
text-decoration: underline;
margin: 10px 20px;
padding: 10px 20px;
/*background-color: #EEE;*/
border: #BBB solid 1px;
}
They look fine, however, they seem to mix-up, that is they are being positioned as if they had no padding or margins.
Take a look here, if you still don't see my point: http://picasaweb.google.com/lh/photo/1yjC0oyQUbBlo_2D4RqjLZsCgnyUSAKTKup5o2EMfkM?feat=directlink
<a> is by nature and definition an inline element, meaning that it can't be given widths, height, paddings or margins (along with a few other styles).
To change that, simply add display: block; which will turn it into a block level element enabling paddings, margins etc.
If you want something that will stay in the flow but be able to accept these styles, use display: inline-block;. This also applies to other inline elements like <span>.
The easiest solution is to set the line-height correctly (without changing display).
Use "display: block" to make padding and margin have a effect.
Try styling your links with display: inline-block;.
You may want to consider using the float style:
<a style='float:left' href='#' />
...which will let you do all the fun stuff and "help" position your anchors as a bonus.
(If you want things to stop floating, put clear:both )
#snowflake's question-level comment got me thinking.
It might help you to know that there are those who believe that using a list for this sort of content is better than marking up plain anchor tags (after all, this is a list of genres, is it not?).
The code for this would look a bit like this:
HTML:
<ul class="genrelist">
<li>Fantasy</li>
<li>Children's Literature</li>
<li>Speculative Fiction</li>
<li>Absurdist Fiction</li>
<li>Fiction</li>
<li>Word I can't read</li>
</ul>
CSS:
.genrelist {
list-style-type: none;
overflow: hidden;
}
.genrelist li {
/*background-color: #EEE;*/
border: #BBB solid 1px;
display: inline;
float: left;
margin: 10px 20px;
padding: 10px 20px;
}
.genrelist li a {
color: #06A;
text-decoration: underline;
}
The code above would display like this (full-size image):
I'd like to use an unordered list for displayign a horizontal navigation. This nav has to be a fixed width.
Markup:
<ul id="page-nav">
<li>RRSP Basics</li>
<li>Contribution Rules</li>
<li>Ways to Fund Your RRSP</li>
<li>Investment Options</li>
</ul>
And the CSS (so far):
#page-nav { width: 423px; height: 57px; margin: 0; padding: 0; }
#page-nav li { list-style: none; float: left; display: block; height: 35px; margin: 13px 8px 0 8px; padding: 9px 14px 0 14px; text-align: center; }
#page-nav li a { color: #1f1f1f; font-size: 10px; white-space: pre-line; }
If firefox, using white-space: pre-line breaks the words as necessary to fit the ul width. This doesn't work in IE6 or IE7, and I need to hit those browsers. In IE, the lis push down to the next line instead of breaking the words in the anchors. is not an option either as this will be content managed at some point.
How can I make the anchors break the words to fit the space available? I can't specify a common width for the list items, so that's not an option.
And how it should look:
Thanks.
Try Listamatic:
Can you take a simple list and use different Cascading Style Sheets to create radically different list options? The Listamatic shows the power of CSS when applied to one simple list.
Pick a list, you should be able to find an unordered list menu there that works.
pre-wrap and pre-line are not supported in IE < 8. So im not sure what an alternative is without resorting to a table :-(
This is untested, but setting a width on your li should do the trick.