Automatically stretching elements to fit in parent container using css - javascript

I'm trying to make a vertical navigation bar inside a box with fixed height. How can I make the buttons dynamically change height equally to fit inside the box? Here's a jsfiddle to demonstrate what I mean.
http://jsfiddle.net/0w3f2fm1/
So now if I am to add a sixth or a seventh button, they will be evenly stretched to fit nav container. Is it possible to make it with css only, or should javascript/jquery intervene?
Note: They will be added using back-end php/mysql application, not by code.
Also note, that the height I currently have is done using padding because I want the text to be centered inside the button.
Thanks

The problem in you question is you have given parent height in fixed size and you want child elements to be stretched to fill the parent.
So you have to give the height of li in percentages.
about vertical centering of text you can use either display:table-cell, vertical-align:middle properties however using tables for layout is not a best practice.
So Im using positions to center align the text.
Here is the jsbin:
http://jsbin.com/jirozicifedo/2/
Here is the dynamic solution (Javascript):
http://jsbin.com/batuyoxupofu/1/edit

I recommend to use html + css instead of javascript.
And since the new function of SO isn't working yet, link here: http://codepen.io/anon/pen/pHhEo
Code here:
<style>
table {
width: 200px;
height: 400px;
}
table tr {
vertical-align: middle;
}
table tr td {
padding-left: 20px;
}
table tr td:hover {
background-color: #000;
color: #fff;
cursor: default;
}
</style>
<table>
<tr>
<td>Button 1</td>
</tr>
<tr>
<td>Button 2</td>
</tr>
<tr>
<td>Button 3</td>
</tr>
<tr>
<td>Button 4</td>
</tr>
<tr>
<td>Button 5</td>
</tr>
</table>
If you change the height, the button's height will also change automatically.

You could use Flex-box to achieve the basic idea of what you are describing:
http://css-tricks.com/snippets/css/a-guide-to-flexbox/
It's super-easy to center things (both direction) and it's really, well, flexible and also it has a ton of option as to how to distribute content.
The only draw-back is that it isn't great for compatibility with older browser. It's fairly well-supported for newer ones though (it is a strong canditate to be added as a standard), depends what exactly it is going to be used for....
Fast to learn too.
===========EDIT, see comments========
html:
<body>
<div class="container">
<div class="item">Button1</div>
<div class="item">Button2</div>
<div class="item">Button3</div>
<div class="item">Button4</div>
</div>
</body>
For CSS:
body {
height: 30em;
border: 2px solid #ff00ff;
}
.container {
height:100%;
width: 10em;
display: flex;
flex-direction: column;
justify-content:center;
}
.item {
flex-grow: 1;
flex-direction: column;
border: 2px solid black;
}
Borders just to show extent of the blocks, if you want to try it in a browser. I checked and seems all new browser (including IE) support this.
Oh, and other thing you might decide you want after all: They don't have to be of equal size, you can easily set proportions for them.
If you id="itemX" for each button, you can use the following to set any ratios you want:
#item1 {
flex-grow: 1;
}
#item2 {
flex-grow: 2;
}
#item3 {
flex-grow: 1;
}
So in that case, #item2 will use 2/4 of the available container (so in this case, the full height of the container), and the other ones 1/4 each...

Related

Fixing overflow issues when the width of the column is unknown

I am working on displaying data from a database on a web page.
My problem is that some of the data is very long and does not contain spaces (think very long path names), so it overflows the table without wrapping.
Currently the widths of the columns are determined using table-layout:auto, because I am working with a lot of different databases and tables, so I do not want to hard code the widths.
Therefore, when I try and use overflow:wrap, it just breaks the other columns into one-letter-wide messes.
Here are some of my ideas (none of which I can get to work):
Use table-layout:auto to calculate the suggested widths, set the widths to be those values, and then set overflow:wrap.
Tell the browser to break at characters other than just spaces, i.e. '/'.
Only set overflow:wrap if a column is longer than a certain amount.
I am currently using CSS and a little bit of JavaScript.
Any other ideas?
You have to use:
max-width and overflow-x properties in your css
.table tr td {
max-width: 100px;
overflow-x: hidden;
border: 1px solid #ff0000;
}
<table class="table">
<tr>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
</tr>
<table>
Some simple solutions that come to mind:
Use ellipses with manually triggered expansion for lines > N chars
/a/really/long/file/name/that/is/really/just/too/l... [expand]
This can work when the data you're showing doesn't really need to be visible all the time, and the user can choose to view all of it if they are interested. With this one, you don't need to worry about what type of information each cell has.
Data-specific column widths
If you know the type of data that will appear in your columns, you can define a mapping to resize the widths of the columns.
This requires some extra work to get the column types and configure the mappings, and then resizing the columns.
{ dataTypeWidths: { default: 'auto', filename: '300px' } }
You can set a max-width combined with overflow-x: hidden and text-overflow: ellipsi, i think that will resolve your problem.
td {
max-width: 200px;
overflow-x: hidden;
text-overflow: ellipsis;
border: 1px solid black;
}
<table>
<tr>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit.Integertellusmassa,fringillaacquamnec,temporconguelectus.Sedimperdietaclacusidtempus.Sedutfelisaduiiaculistemporinasapien.Integervelliberomi.Morbiutenimsagittis,sollicitudinipsumin,ullamcorpersapien.Phasellusidfelisatligulatristiquehendrerit.Nuncsitametipsumidquamtinciduntfacilisis.Pellentesquehabitantmorbitristiquesenectusetnetusetmalesuadafamesacturpisegestas.Namsitametdictumeros.</td>
<td>Pellentesquefermentummattisleo,sedblandittortorhendreritnec.Vestibulumeuturpislacus.Fusceliberorisus,dignissimegetsodalesnon,dictuminsem.Quisqueblanditmiante,eutristiqueorciporttitorsitamet.Donecpretium,eratetaccumsanfringilla,velitjustotristiqueorci,sedfringillaquamrisusnonenim.Praesenthendreritmassaultriceseratmalesuadapretium.Aeneansitametnuncsodales,vehiculaeroseget,ornarelorem.Proinquisfermentumsapien,utvehiculafelis.Duisquiseleifendleo.Suspendisseinnequefringilla,tristiquelectuseu,fermentumdiam.Nuncmassalectus,aliquamidmassaeu,pretiumullamcorperlectus.Aliquamfeugiatexegetornaretincidunt.Donectristiqueeratseddiamvehiculaauctor.Proinorcijusto,consecteturegetcursusut,pellentesquevelleo.Nampulvinarrisusetnislfacilisisaliquam.</td>
<td>Inhachabitasseplateadictumst.Craspulvinarsuscipitfelis,ullamcorperpulvinarlorem.Vivamuspulvinarinterdumlibero.Maurisvenenatisaugueodio,aultriceserossuscipitvel.Donecutfelissitameteratconsecteturbibendumegetetnulla.VestibulumanteipsumprimisinfaucibusorciluctusetultricesposuerecubiliaCurae;Crastempus,magnavelelementumlobortis,ipsummassaporttitorarcu,mollisvehiculaanteenimvitaelectus.Fuscemolliseumagnaapretium.Praesentegestasaugueanuncultricies,ataliquamodiodignissim.Insagittismaurisest,sedlacinialeoornareeu.VestibulumanteipsumprimisinfaucibusorciluctusetultricesposuerecubiliaCurae;Namrisusaugue,gravidasedullamcorperin,feugiatetdolor.Maurisposuerenuncquam,necdignissimmassagravidatincidunt.Quisquesemperdiamlibero,intemporlectusullamcorperut.</td>
<td>Suspendissevenenatisaliquamsapientinciduntconsequat.Aliquamveldiamegetsapienvehiculadapibus.Namblanditamagnaquisiaculis.Orcivariusnatoquepenatibusetmagnisdisparturientmontes,nasceturridiculusmus.Orcivariusnatoquepenatibusetmagnisdisparturientmontes,nasceturridiculusmus.Quisquelacinianunclorem,ultriciesvolutpatduifinibusquis.Praesentmalesuada,odioeuconsequatgravida,nisllacussagittismagna,sitametultriciesquamtellusporttitorelit.Fusceduilorem,viverraquisipsumet,pulvinaraliquamaugue.Donecinterdumscelerisquequamidfaucibus.Sedmollistinciduntquam,ideleifenddiammaximusa.Sedvitaemagnanonlectushendreritlacinia.Donecvenenatisauguevitaepulvinarpulvinar.Etiamposuereapurusetplacerat.Pellentesquefinibusdictumimperdiet.Crascursusfelisvelpellentesquerutrum.</td>
</tr>
<table>
What about using the:
word-break: break-word;
this will keep the columns widths and will show all the data
.table tr td {
max-width: 100px;
overflow-x: hidden;
border: 1px solid #ff0000;
word-break: break-word;
}
<table class="table">
<tr>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
<td>Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,quisnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconsequat.</td>
</tr>
<table>
Code snippet copied from #MrMins answer and updated.

How to split <table> into multiple <div>?

I am working with a large amount of data table (many lines many columns). The solution that I chose to use is putting my table into a overflow:scoll div. I would like to be able to see the 1st row even when scrolling down.
Is it possible to do it in html ? Otherwise, is there any trick like js trick?
I'm assuming you want something like this?
https://jsfiddle.net/s07w38me/
No JavaScript really required. You can simply position: absolute the contents of a div inside each th.
e.g.
CSS
th div {
position: absolute;
background: transparent;
color: #fff;
padding: 9px 25px;
top: 0;
margin-left: -25px;
line-height: normal;
border-left: 1px solid #800;
}
HTML
<table>
<thead>
<tr class="header">
<th>
Table attribute name
<div>Table attribute name</div>
</th>
<th>
Value
<div>Value</div>
</th>
<th>
Description
<div>Description</div>
</th>
</tr>
</thead>
<!-- ...etc... -->
PS: This could be done a lot better, but this example above is a fork based on an existing JSfiddle I found.
Check out jQuery.floatThead (demos available) which is very cool, can work with DataTables too, and can even work inside an overflow: auto container.
The first row that you want to remain visible should be position:fixed and to set it to the top of that div top:0. Now your other columns would be overlapped by the position:fixed one, so make sure you give your scrollable div a padding-top equal to the height of the fixed column

How to make content in DIV align vertically

<div id="content">ABC<div>UUU</div></div>
I just want to find some way to align vertically in middle for div#content. Actually I have some solutions. First one is using line-height, however it can not work if there's another div in the div#content. And vertical-align:middle I think just works for table? Is there any other usable solutions?
I try the vertical-align:middle and display:table-cell, the other issue comes,
the width cannot works, i give that div a big width, that can fill out the screen(1438px), but now the width is also that number but just fill out the 1/3 width of screen.
The table-cell seems like make every cell in the screen, but i just want to give them specified length for table cell.
use this for your requirement
#content {display:table-cell; vertical-align:middle}
With display:table-cell declared on your element, vertical align will work.
#content {
display:table-cell;
vertical-align:middle
}
See thorough explanation on vertical alignment for both normal and inline DIVs at http://phrogz.net/css/vertical-align/index.html
Expounding upon other answers using display:table-cell;vertical-align:middle... Table cells cannot have 100% width, but their containers can!
Using a CSS Table
Items with a table display accept dynamic widths:
#existingContainer {
display: table;
width: 100%;
}
#content {
display: table-cell;
vertical-align: middle;
height: 100px; /* example */
}
Say, with sample HTML:
<div id="existingContainer">
...
<div id="content">ABC<div>UUU</div></div>
...
</div>
Using a Clearing Div
Alternatively, putting your table-cell directly into a block element will ensure no inline elements sit beside it:
<div id="newContainer">
<div id="content">ABC<div>UUU</div></div>
</div>
With sample CSS:
#newContainer {
display: block;
}
#content {
display: table-cell;
vertical-align: middle;
height: 100px; /* example */
}

Vertical Alignment

Please take a look at this: http://sources.freehosting.bg/landing.html
I am trying to vertically align #content so it looks good on larger (1920x1200) and smaller (1024x768) resolutions. By that I mean it does not have a scrollbar.
As you see there is plenty of free space so a scrollbar is unneeded.
The only solution I came up with is to calculate the height of #content with JS and to set a padding, but I realize it is the lamest possible solution.
Please advise me on how to achieve that.
See if this fiddle is what you are looking for. Simple solution IMO.
It works by forcing the containing div to behave as a table-cell, and making use of the vertical-align: middle style. It doesn't require you to know the heights of any elements at all.
Code used in the fiddle are below.
HTML:
<div class="a">
text inside div a
<div class="b">
text inside div b
</div>
</div>
The important styles are:
display: table-cell
vertical-align: middle
The rest are only there for demonstration. CSS:
div.a {
border: 1px solid red;
}
div.b {
border: 1px solid blue;
height: 200px;
display:table-cell;
vertical-align:middle;
}
If your content height is fixed put a div before the content
<div id="distance"></div>
<div id="content">
Vertically centered :D
</div>
and style it like:
html, body {
height:100%;
margin:0;
padding:0;
}
div#distance {
width:1px;
height:50%;
margin-bottom:-300px; /* half of website height */
float:left;
}
div#content {
text-align:left;
margin:auto;
position: relative;
width: 950px;
height: 600px;
clear: left;
}
​
The only way I know of that works using pure CSS, no JS and no hacks requires you to know the height of the thing you're trying to position:
<html>
<head>
<style type="text/css">
/* Give your document height */
body, #content {
height: 100%;
}
/* Give your element height */
.thing {
width: 20px;
height: 300px;
background: #000;
}
/* Position thing */
#content .thing {
position: absolute;
top: 50%;
margin-top: -150px; /* half the height of the thing */
}
</style>
</head>
<body>
<div id="content">
<div class="thing"></div>
</div>
</body>
</html>
EDIT: Updated height of item, container id. Still works just fine.
There is one way to do this without javascript and without knowing the height of the content - but purists will not like it. Then again, sometimes it doesn't matter if it's not approved by the trendy people. Sometimes all you need is to get the job done because you boss wants it that way.
And the solution is: use a table (told you purists wouldn't like it). Do layout the old school way and abuse the fact that HTML specifies lots of capabilities to tables.
A table cell is the only HTML element that has a vertical alignment attribute that does what most people expect it to do. Just give the table 100% width and height (so that is expands with the window size) and use cell alignment to position the content you want.
I've only ever had to use this trick once and it still makes me feel dirty* but when you really need it it works better than anything else.
*note: I'm a purist myself but understand that sometimes a man's got to do what a man's got to do.

How can I center align a div without knowing the width?

I've looked this up and the outlook seems bleak. I'm not interested in using a table. I have 6 or so 'a element' inline-blocks that make up a menu. It's slick, except all the 'a elements' are set to width: auto; to accommodate their text. Without an explicit width, I'm not able to center align them. I have a container div and a child div that wraps around my 'a elements'.
Any thoughts?
Thanks
Mike
You could set the style of the a element to margin: 0 auto, but that doesn't work in IE6. In IE6, you should set the wrapper div to text-align: center, and (optionally) set the text-alignment for the a element back to text-align: left
<div style="width: auto; margin-left: auto; margin-right: auto">
div content
</div>
will align center on the page
the div element will take all the width space of the container element if it isn't set a width value.
So if you want to center a div you must set a width...
A solution to your problem (if I have understand it) can be:
<div style="text-align:center;"><span>[... yours content ...]</span></div>
where your div has became a span and a new div puts the span in the center.
Hope this can help you!
Bye,
Alberto
My advice is this answer - however someone commented that it wouldn't work in IE6. Here's how to make this work:
<div id="container">
<div id="centeredBlock">centered</div>
</div>
#container {
text-align: center;
}
#centeredBlock {
margin: 0 auto;
text-align: left;
width: 50%;
}
You need to set margin: 0 auto; on the outer container div, add text-align: center; on the inner div; and use an unordered list to build your menu in the first place.
Without setting an explicit width, the <div> tag will automatically expand to 100% of the width of its parent. Therefore, setting margin: 0 auto; will make it center -- with 0px on both the left and right.
here a nice workaround for centering a div with no width:
http://www.kensfi.com/how-to-align-center-a-div-with-no-width-declared/
Here is also a good example for the situation: http://www.cssplay.co.uk/menus/centered.html
If you need it centered and dynamically shrinking/expanding to accommodate the content without knowing the width, then your only option really is using a table. It is the only elastic element in HTML repertoire.
<table style="margin-left:auto;margin-right:auto;">
<tr>
<td>
Whatever...
</td>
</tr>
</table>
P.S. You can have a div to shrink dynamically as well by setting the float property to float:left or float:right. So it will stick to the left or the right, but you can't have it centered this way.

Categories