Fix position if row is below a certain height - html

Is it possible to fix the position of a table, such that it "scrolls along" with the page, but only after a certain value?
What I'm trying to achieve is similar to the header on this site: http://tf2trends.com/ (click show all, then scroll down)

This can be done using JavaScript and CSS with any type of element:
Have a div cling to top of screen if scrolled down past it
http://css-tricks.com/snippets/jquery/persistant-headers-on-tables/

Try this:
//keep element in view
(function($)
{
$(document).ready( function()
{
var elementPosTop = $('#floatguy').position().top;
$(window).scroll(function()
{
var wintop = $(window).scrollTop(), docheight = $(document).height(), winheight = $(window).height();
//if top of element is in view
if (wintop > elementPosTop)
{
//always in view
$('#floatguy').css({ "position":"fixed", "top":"10px" });
}
else
{
//reset back to normal viewing
$('#floatguy').css({ "position":"inherit" });
}
});
});
})(jQuery);​
html:
<div>
Content before floating text<br/>
Content before floating text<br/>
Content before floating text<br/>
</div>
<div id="floatguy">
<span>Floating Header</span>
</div>
<div id="longguy">
Other text <br/>
Other text <br/>
Other text <br/>
</div>
jsFiddle example

Here is the method used by the website referenced in the question, implemented without using frameworks (and with excessive comments to try to explain what's going on). This is not the best/easiest/simplest method to get the effect, but I hope it is useful to see that website's approach in pure js from a learning standpoint. (Only tested in Chrome 19.0 and Firefox 13.0, both on a mac.)
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Table With Scrolling Head</title>
<style type='text/css'>
#scrollTable{
margin-top:100px; /* not necessary for scrolling, just to give a little padding */
}
#scroller {
z-index: 100; /* this number needs to be larger than any other z-index on the page */
}
</style>
</head>
<body>
<table id='scrollTable'>
<thead id='scroller'>
<tr>
<th>I don't leave the screen</th>
</tr>
</thead>
<tbody>
<tr><td>I do!</td></tr>
<tr><td>I do!</td></tr>
<!-- ... add more <tr><td>I do!</td></tr> lines to make the page long enough to scroll -->
<tr><td>I do!</td></tr>
</tbody>
</body>
<script type='text/javascript'>
function getDistFromTop(e){
/* get the offset of element e from the top (including the offset of any elements it is nested in)*/
y = e.offsetTop;
e = e.offsetParent;
while (e != null){
y = y + e.offsetTop;
e = e.offsetParent;
}
return y;
}
function scroll() {
var scroller = document.getElementById('scroller');
var tab = document.getElementById('scrollTable');
if (window.pageYOffset > getDistFromTop(tab)){ /* if the page has been scrolled farther than the distance the table is from the top... */
scroller.style.position = 'fixed'; /* fix the position of scroller so it doesn't move with the page */
scroller.style.top = '0px'; /* put scroller on the top of the page */
tab.style.paddingTop = '20px'; /* add padding to the top of the table; this is done to make the table body stay where it is expected (otherwise it would move because scroller, the table header, has become fixed) */
} else { /* if the page scrolls back so that the whole table is on the page, reset everything to their original values so the page behaves "normally" */
scroller.style.position = 'relative';
scroller.style.top = '';
tab.style.paddingTop = '0px';
}
}
window.onscroll = scroll;
</script>
</html>

Yes, you can easily achieve this functionality by using some CSS class and jQuery or JavaScript programming.
You have to call a function in a certain scroll value, which you will get easily by jQuery and then change the CSS for your table or div which is called position:fixed;top:0;

Related

debug nasty horizontal scroll

I think i got myself entangled in a CSS maze. I notice a horizontal scroll on my site in desktop browsers (firefox and chromium), when in responsive mode. Tested in android, and it seems ok.
The website is cv.pixyz.net
To debug it, I tried all of the following:
Looking for elements getting bigger than the parent's space.
I thought the container with #id was the problem, because web developer toolbar shows that closer to the edges of the screen, but removing that, didn't solve this
Used this to see if anything gets out of bounds. some elements stand out, but still can't solve the scroll
I tried these 2 snippets:
// snippet 1
var docWidth = document.documentElement.offsetWidth;
[].forEach.call(
document.querySelector('body *'),
function(el) {
console.log(el);
// console.log(el.offsetWidth);
// console.log(docWidth);
if (el.offsetWidth > docWidth) {
console.log(el);
}
}
);
// snippet 2
var all = document.getElementsByTagName("*"), i = 0, rect;
for (; i < all.length; i++) {
rect = all[i].getBoundingClientRect();
if (rect.right < 0) all[i].style.outline = "1px solid green";
}
but there's no effect either: no logs registered, no border changed
started removing other elements in the page. Even doing this, I still get scroll:
<!DOCTYPE html>
<!-- domActual = <?php echo $ambiente; ?> -->
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Sobre mim... # Luis Aguiar</title>
</head>
<body>
<nav class="container">
<h2 class="nome">Sobre mim... / Luis Aguiar</h2>
<a class="dominio" href="http://www.cv.pixyz.net">cv.pixyz.net</a>
<ul>
<li>
ID
</li>
<li>
Dev
</li>
</ul>
</nav>
<footer>
<p>Todos os direitos reservados # Luis Aguiar</p>
</footer>
</body>
</html>
I also tried this to check abnormal widths: (http://wernull.com/2013/04/debug-ghost-css-elements-causing-unwanted-scrolling/):
* {
outline: 1px solid blue!important;
opacity: 1 !important;
visibility: visible !important;
}
Does anyone know what is causing this, or have any other idea for debugging?
The problem appears to be the following line :
<section id="dev">
[...]
<li class="job"> /* 2nd li element */
[...]
<p class="url">https://www.demarca.eu/</p> /* <- This line */
The URL has no breaking spaces, so once the window reaches the width of the URL string it can't wrap the string and therefore the scrollbar gets added.
The options you have are:
Shorten the text:
Consider whether you need to display the full URL including https:// - maybe instead include it as a link? e.g.:
<p class="url">www.demarca.eu</p>
Use lowercase: the CSS changes the text to uppercase, which adds to the width of the string.
Wrap the URL: forcing the string to wrap is often the best option, but it doesn't suit a url so well because urls can't have spaces. However if you do want to make it wrap, you can create the following CSS class and add it to the element:
.wrap { word-wrap: break-word; }
I don't really know what it was, but after reboot, was ok (... but i cleaned the cache!). The situation persisted even without css and barebones HTML. After this, i did what you said, just in case (and because it looks nicer!). Thanks for the support!

Go to last div added inside div [duplicate]

I am creating a chat using Ajax requests and I'm trying to get messages div to scroll to the bottom without much luck.
I am wrapping everything in this div:
#scroll {
height:400px;
overflow:scroll;
}
Is there a way to keep it scrolled to the bottom by default using JS?
Is there a way to keep it scrolled to the bottom after an ajax request?
Here's what I use on my site:
var objDiv = document.getElementById("your_div");
objDiv.scrollTop = objDiv.scrollHeight;
This is much easier if you're using jQuery scrollTop:
$("#mydiv").scrollTop($("#mydiv")[0].scrollHeight);
Try the code below:
const scrollToBottom = (id) => {
const element = document.getElementById(id);
element.scrollTop = element.scrollHeight;
}
You can also use Jquery to make the scroll smooth:
const scrollSmoothlyToBottom = (id) => {
const element = $(`#${id}`);
element.animate({
scrollTop: element.prop("scrollHeight")
}, 500);
}
Here is the demo
Here's how it works:
Ref: scrollTop, scrollHeight, clientHeight
using jQuery animate:
$('#DebugContainer').stop().animate({
scrollTop: $('#DebugContainer')[0].scrollHeight
}, 800);
Newer method that works on all current browsers:
this.scrollIntoView(false);
var mydiv = $("#scroll");
mydiv.scrollTop(mydiv.prop("scrollHeight"));
Works from jQuery 1.6
https://api.jquery.com/scrollTop/
http://api.jquery.com/prop/
alternative solution
function scrollToBottom(element) {
element.scroll({ top: element.scrollHeight, behavior: 'smooth' });
}
smooth scroll with Javascript:
document.getElementById('messages').scrollIntoView({ behavior: 'smooth', block: 'end' });
If you don't want to rely on scrollHeight, the following code helps:
$('#scroll').scrollTop(1000000);
Java Script:
document.getElementById('messages').scrollIntoView(false);
Scrolls to the last line of the content present.
My Scenario: I had an list of string, in which I had to append a string given by a user and scroll to the end of the list automatically. I had fixed height of the display of the list, after which it should overflow.
I tried #Jeremy Ruten's answer, it worked, but it was scrolling to the (n-1)th element. If anybody is facing this type of issue, you can use setTimeOut() method workaround. You need to modify the code to below:
setTimeout(() => {
var objDiv = document.getElementById('div_id');
objDiv.scrollTop = objDiv.scrollHeight
}, 0)
Here is the StcakBlitz link I have created which shows the problem and its solution : https://stackblitz.com/edit/angular-ivy-x9esw8
If your project targets modern browsers, you can now use CSS Scroll Snap to control the scrolling behavior, such as keeping any dynamically generated element at the bottom.
.wrapper > div {
background-color: white;
border-radius: 5px;
padding: 5px 10px;
text-align: center;
font-family: system-ui, sans-serif;
}
.wrapper {
display: flex;
padding: 5px;
background-color: #ccc;
border-radius: 5px;
flex-direction: column;
gap: 5px;
margin: 10px;
max-height: 150px;
/* Control snap from here */
overflow-y: auto;
overscroll-behavior-y: contain;
scroll-snap-type: y mandatory;
}
.wrapper > div:last-child {
scroll-snap-align: start;
}
<div class="wrapper">
<div>01</div>
<div>02</div>
<div>03</div>
<div>04</div>
<div>05</div>
<div>06</div>
<div>07</div>
<div>08</div>
<div>09</div>
<div>10</div>
</div>
You can use the HTML DOM scrollIntoView Method like this:
var element = document.getElementById("scroll");
element.scrollIntoView();
Javascript or jquery:
var scroll = document.getElementById('messages');
scroll.scrollTop = scroll.scrollHeight;
scroll.animate({scrollTop: scroll.scrollHeight});
Css:
.messages
{
height: 100%;
overflow: auto;
}
Using jQuery, scrollTop is used to set the vertical position of scollbar for any given element. there is also a nice jquery scrollTo plugin used to scroll with animation and different options (demos)
var myDiv = $("#div_id").get(0);
myDiv.scrollTop = myDiv.scrollHeight;
if you want to use jQuery's animate method to add animation while scrolling down, check the following snippet:
var myDiv = $("#div_id").get(0);
myDiv.animate({
scrollTop: myDiv.scrollHeight
}, 500);
I have encountered the same problem, but with an additional constraint: I had no control over the code that appended new elements to the scroll container. None of the examples I found here allowed me to do just that. Here is the solution I ended up with .
It uses Mutation Observers (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) which makes it usable only on modern browsers (though polyfills exist)
So basically the code does just that :
var scrollContainer = document.getElementById("myId");
// Define the Mutation Observer
var observer = new MutationObserver(function(mutations) {
// Compute sum of the heights of added Nodes
var newNodesHeight = mutations.reduce(function(sum, mutation) {
return sum + [].slice.call(mutation.addedNodes)
.map(function (node) { return node.scrollHeight || 0; })
.reduce(function(sum, height) {return sum + height});
}, 0);
// Scroll to bottom if it was already scrolled to bottom
if (scrollContainer.clientHeight + scrollContainer.scrollTop + newNodesHeight + 10 >= scrollContainer.scrollHeight) {
scrollContainer.scrollTop = scrollContainer.scrollHeight;
}
});
// Observe the DOM Element
observer.observe(scrollContainer, {childList: true});
I made a fiddle to demonstrate the concept :
https://jsfiddle.net/j17r4bnk/
Found this really helpful, thank you.
For the Angular 1.X folks out there:
angular.module('myApp').controller('myController', ['$scope', '$document',
function($scope, $document) {
var overflowScrollElement = $document[0].getElementById('your_overflow_scroll_div');
overflowScrollElement[0].scrollTop = overflowScrollElement[0].scrollHeight;
}
]);
Just because the wrapping in jQuery elements versus HTML DOM elements gets a little confusing with angular.
Also for a chat application, I found making this assignment after your chats were loaded to be useful, you also might need to slap on short timeout as well.
Like you, I'm building a chat app and want the most recent message to scroll into view. This ultimately worked well for me:
//get the div that contains all the messages
let div = document.getElementById('message-container');
//make the last element (a message) to scroll into view, smoothly!
div.lastElementChild.scrollIntoView({ behavior: 'smooth' });
small addendum: scrolls only, if last line is already visible. if scrolled a tiny bit, leaves the content where it is (attention: not tested with different font sizes. this may need some adjustments inside ">= comparison"):
var objDiv = document.getElementById(id);
var doScroll=objDiv.scrollTop>=(objDiv.scrollHeight-objDiv.clientHeight);
// add new content to div
$('#' + id ).append("new line at end<br>"); // this is jquery!
// doScroll is true, if we the bottom line is already visible
if( doScroll) objDiv.scrollTop = objDiv.scrollHeight;
Just as a bonus snippet. I'm using angular and was trying to scroll a message thread to the bottom when a user selected different conversations with users. In order to make sure that the scroll works after the new data had been loaded into the div with the ng-repeat for messages, just wrap the scroll snippet in a timeout.
$timeout(function(){
var messageThread = document.getElementById('message-thread-div-id');
messageThread.scrollTop = messageThread.scrollHeight;
},0)
That will make sure that the scroll event is fired after the data has been inserted into the DOM.
This will let you scroll all the way down regards the document height
$('html, body').animate({scrollTop:$(document).height()}, 1000);
You can also, using jQuery, attach an animation to html,body of the document via:
$("html,body").animate({scrollTop:$("#div-id")[0].offsetTop}, 1000);
which will result in a smooth scroll to the top of the div with id "div-id".
Scroll to the last element inside the div:
myDiv.scrollTop = myDiv.lastChild.offsetTop
You can use the Element.scrollTo() method.
It can be animated using the built-in browser/OS animation, so it's super smooth.
function scrollToBottom() {
const scrollContainer = document.getElementById('container');
scrollContainer.scrollTo({
top: scrollContainer.scrollHeight,
left: 0,
behavior: 'smooth'
});
}
// initialize dummy content
const scrollContainer = document.getElementById('container');
const numCards = 100;
let contentInnerHtml = '';
for (let i=0; i<numCards; i++) {
contentInnerHtml += `<div class="card mb-2"><div class="card-body">Card ${i + 1}</div></div>`;
}
scrollContainer.innerHTML = contentInnerHtml;
.overflow-y-scroll {
overflow-y: scroll;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="d-flex flex-column vh-100">
<div id="container" class="overflow-y-scroll flex-grow-1"></div>
<div>
<button class="btn btn-primary" onclick="scrollToBottom()">Scroll to bottom</button>
</div>
</div>
Css only:
.scroll-container {
overflow-anchor: none;
}
Makes it so the scroll bar doesn't stay anchored to the top when a child element is added. For example, when new message is added at the bottom of chat, scroll chat to new message.
Why not use simple CSS to do this?
The trick is to use display: flex; and flex-direction: column-reverse;
Here is a working example. https://codepen.io/jimbol/pen/YVJzBg
A very simple method to this is to set the scroll to to the height of the div.
var myDiv = document.getElementById("myDiv");
window.scrollTo(0, myDiv.innerHeight);
On my Angular 6 application I just did this:
postMessage() {
// post functions here
let history = document.getElementById('history')
let interval
interval = setInterval(function() {
history.scrollTop = history.scrollHeight
clearInterval(interval)
}, 1)
}
The clearInterval(interval) function will stop the timer to allow manual scroll top / bottom.
I know this is an old question, but none of these solutions worked out for me. I ended up using offset().top to get the desired results. Here's what I used to gently scroll the screen down to the last message in my chat application:
$("#html, body").stop().animate({
scrollTop: $("#last-message").offset().top
}, 2000);
I hope this helps someone else.
I use the difference between the Y coordinate of the first item div and the Y coordinate of the selected item div. Here is the JavaScript/JQuery code and the html:
function scrollTo(event){
// In my proof of concept, I had a few <button>s with value
// attributes containing strings with id selector expressions
// like "#item1".
let selectItem = $($(event.target).attr('value'));
let selectedDivTop = selectItem.offset().top;
let scrollingDiv = selectItem.parent();
let firstItem = scrollingDiv.children('div').first();
let firstItemTop = firstItem.offset().top;
let newScrollValue = selectedDivTop - firstItemTop;
scrollingDiv.scrollTop(newScrollValue);
}
<div id="scrolling" style="height: 2rem; overflow-y: scroll">
<div id="item1">One</div>
<div id="item2">Two</div>
<div id="item3">Three</div>
<div id="item4">Four</div>
<div id="item5">Five</div>
</div>

Responsive site menu

http://nggalaxy.ru/en/about-us/ - here is the example of exact behaviour to be implemented. When you scroll down the page, the side menu disappears and appears on top of the page.
How it can be realized using bootstrap for example?
Thank you.
Here is an example of raw Javascript + jQuery making this happen:
<script type="text/javascript">
$(window).scroll(function(){
var a = 112;
var pos = $(window).scrollTop();
if(pos > a) {
$("menu").css({
position: 'fixed'
});
}
else {
$("menu").css({
position: 'absolute',
top:'600px'
});
}
});
</script>
This will add a CSS style if the user scrolled 112 pixel down. Like this you can create all styles for your menu.
In General: Use javascript to check on what scroll-position the user is, and append the styles or classes.

How can you z-index text / div behind a scrolling fixed nav header?

I want to put the div behind the scrolling header like it is for the footer.
The footer is
#rt-footer-surround {
color: #686868;
background-color: #2E244E;
height: 40px;
width: 100%;
z-index: 900;
bottom: 0;
left: 0;
padding: 10px;
position: fixed;
}
but I cannot replicate it for the header.
the site in question is here:
site with z-index issue
To use the z-index style, you must also use either position:fixed;, position:absolute;, ,or position:relative; on the same object you wish to style.
Then, you can simply use a div to represent your header, footer, and main content section as follows:
<div class="head"></div>
<div class="mainbody"></div>
<div class="foot"></div>
Or alternatively, you can use the <head>,<main> and <footer> tags instead of divs. As far as coding and visuals are concerned, there is no difference.
Also, you don't have to put a massive number on the z-index. As long as one element's z-index is greater than another one's, that element will always be layered above, whether it is 900 over 1, or 2 over 1.
Ok here is what I came up with to solve the problem. Jquery.
Essentially my question was asking for this in the first place.
If you have content in a div you can place a nav bar in that div as a position:relative i.e. relative to that div.
What you cannot do via css is have the content in that div scroll up and stay underneath the nav bar you created. Furthermore when the nav menu area scrolls beyond the top of the screen it will then disappear.
So the jquery code I used does two things. It allows you to take a nav menu bar i.e. width 600px / height 50px and place it in its relative position anywhere you like. Furthermore, when it reachs the top of a users screen it will stop/halt and allow that to be the menu that is visible while everything else scrolls underneath that menu area.
Now, I don't think this is anything really new from Jquery but what is ultra convenient is that you can define a menu nav bar in any div position you want. Have a regular menu at the top and another menu perhaps below a slider or some content further down the page.
I will share the code if that is ok with SO... I paid for it myself.
Oh and here are two websites I have employed it on.
http://isaerudition.com/study-pages &
This is for a client I am preparing his website...
// JavaScript Document
/* jQuery(document).ready(function(){
if(jQuery('header,div,p,span,h1,h2,h3,h4,a').hasClass('isa-scroll-fixed')){
var el = jQuery('.isa-scroll-fixed'),
elTop = jQuery(el).offset().top;
elLeft = jQuery(el).offset().left;
//alert(elTop);
jQuery(document).scroll(function(){
var height = jQuery(window).height();
var scrollTop = jQuery(window).scrollTop();
if(scrollTop>=elTop){
//add fixed
jQuery(el).addClass('scroll_fixed').css("left",elLeft+"px");
}else{
//clear fixed
jQuery(el).removeClass('scroll_fixed').attr('style','');
}
})
}
})
*/
// JavaScript Document
/* jQuery(window).load(function(){
if(jQuery('header,div,p,span,h1,h2,h3,h4,a').hasClass('isa-scroll-fixed')){
var el = jQuery('.isa-scroll-fixed'),
elTop = jQuery(el).offset().top;
elLeft = jQuery(el).offset().left;
//alert(elTop);
var scrollTop = jQuery(window).scrollTop();
scrollFixed(el,elTop,elLeft);
}
}) */
var setInter = null;
var session = null;
setInter = setInterval(function(){
if(jQuery('header,div,p,span,h1,h2,h3,h4,a').hasClass('isa-scroll-fixed')){
var el = jQuery('.isa-scroll-fixed');
session = jQuery(el).attr('set-scroll');
//alert(session);
if(session == '2'){
jQuery(el).attr('set-scroll','2');
}else{
jQuery(el).attr('set-scroll','1');
}
if(session == '1'){
setValue(el);
}
}
}, 200);
function setValue(el){
var setScroll = jQuery(el).attr('set-scroll');
elTop = jQuery(el).offset().top;
elLeft = jQuery(el).offset().left;
//alert(elTop);
jQuery(el).attr('set-scroll','2');
scrollFixed(el,elTop,elLeft);
};
function scrollFixed(el,elTop,elLeft){
jQuery(document).unbind('scroll').scroll(function(){
//alert(elTop);
var height = jQuery(window).height();
var scrollTop = jQuery(window).scrollTop();
if(scrollTop>=elTop){
//add fixed
jQuery(el).addClass('scroll_fixed').css("left",elLeft+"px");
}else{
//clear fixed
jQuery(el).removeClass('scroll_fixed').attr('style','');
}
})
}

How can I set a <td> width to visually truncate its displayed contents?

I'm trying to set a column width of a table, which works fine until it gets to the point where child elements would be visually truncated ... then it won't size any smaller. ("visually truncated"-what doesn't fit appears to be hidden behind the next column)
Here is some sample code to demonstrate my problem:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<script language="javascript" type="text/javascript">
var intervalID = null;
function btn_onClick()
{
// keep it simple, only click once
var btn = document.getElementById("btn");
btn.disabled = true;
// start shrinking
intervalID = window.setInterval( "shrinkLeftCell();", 100);
}
function shrinkLeftCell()
{
// get elements
var td1 = document.getElementById("td1");
var td2 = document.getElementById("td2");
// initialize for first pass
if( "undefined" == typeof( td1.originalWidth))
{
td1.originalWidth = td1.offsetWidth;
td1.currentShrinkCount = td1.offsetWidth;
}
// shrink and set width size
td1.currentShrinkCount--;
td1.width = td1.currentShrinkCount; // does nothing if truncating!
// set reporting values in right cell
td2.innerHTML = "Desired Width : ["
+ td1.currentShrinkCount
+ "], Actual : ["
+ td1.offsetWidth + "]";
// Stop shrinking
if( 1 >= td1.currentShrinkCount)
window.clearInterval(intervalID);
}
</script>
</head>
<body>
<table width="100%" border="1">
<tr>
<td id="td1">
Extra_long_filler_text
</td>
<td id="td2">
Desired Width : [----], Actual : [----]
</td>
</tr>
</table>
<button id="btn" onclick="btn_onClick();">Start</button>
</body>
</html>
I've tried setting the width in different ways including
td1.offsetWidth = td1.currentShrinkCount;
and
td1.width = td1.currentShrinkCount + "px";
and
td1.style.width = td1.currentShrinkCount + "px";
and
td1.style.posWidth = td1.currentShrinkCount;
and
td1.scrollWidth = td1.currentShrinkCount;
and
td1.style.overflow = "hidden";
td1.width = td1.currentShrinkCount;
and
td1.style.overflow = "scroll";
td1.width = td1.currentShrinkCount;
and
td1.style.overflow = "auto";
td1.width = td1.currentShrinkCount;
I realize, I could probably use DIV's, but I'd prefer not to since the table is being generated from a bound control, and I don't really want to get into rewriting asp.net controls.
Having said that, I thought as a last ditch effort, I could at least wrap each 'td1's contents with a DIV, and the overflow would take care of things, but even replacing
<td id="td1">
Extra_long_filler_text
</td>
with
<td id="td1" style="overflow:hidden;">
<div style="margin=0;padding:0;overflow:hidden;">
Extra_long_filler_text
</div>
</td>
didn't work.
Does anybody know how I can set a width to visually truncate its contents?
BTW-My target browser is IE7. Other browsers are not important right now, since this is an internal app.
I just tried adding table-layout: fixed; to the <table> and it worked for me on IE7.
In a fixed table layout, the horizontal layout only depends on the table's width, the width of the columns, and not the content of the cells
Check out the documentation.
CSS Solution
"Truncate" may not be the word you are looking for. You may just want to hide the overflowing characters. If that is the case, look into the css-property "overflow," which will hide any content extending past the declared limits of its container.
td div.masker {
height:25px;
width:100px;
overflow:hidden;
}
<td>
<div class="masker">
This is a string of sample text that
should be hidden when it reaches out of the bounds of the parent controller.
</div>
</td>
Javascript Solution
If you are indeed wanting to truncate the text within the container, you will have to remove one character from the right, test the width of the parent, and continue to remove characters and testing the parent width until the parent width matches the declared width.
while (parent.width > desiredWidth) {
remove one char from right-side of child-text
}
<td id="td1" style="overflow-x:hidden;">
Should be
<td id="td1" style="overflow:hidden;">
overflow-x is a Microsoft CSS attribute, which is now part of CSS3. I would stick with the older overflow attribute.
EDIT:
As Paolo mentions you also need to add table-layout:fixed; and specify the width of the table. A full example follows.
<html>
<head>
<style>
table
{
table-layout:fixed;
width:100px;
}
td
{
overflow:hidden;
width:50px;
border-bottom: solid thin;
border-top:solid thin;
border-right:solid thin;
border-left:solid thin;
}
</style>
</head>
<body>
<table>
<tr><td>Some_long_content</td><td>Short</td></tr>
</table>
</body>
</html>
As far as I know, a table cell will always stretch to accommodate its contents.
Have you thought about using Javascript to dynamically truncate the data in table cells that have more than a certain amount of content? Alternatively, you could do this more easily server side.
You could use jQuery or plain javascript to surround the content of your cell(s) with div tags and set a fixed width and overflow:hidden on those instead. Not beautiful, but it'd work.
ETA:
<td><div style="width:30px;overflow:hidden">Text goes here</div></td>
Since the DIV is the bounding element, that's where the width should be set.