I'm trying to create a block which may or may not have a scrollbar, with a header that does not scroll. The trick is that the width of the header should be affected by the presence of a scrollbar.
I'm worried that this is one of those CSS use cases which should be trivial, but might, in fact, be impossible. Anyone willing to prove me wrong?
Here are a few pointers
http://davidchambersdesign.com/css-fixed-position-headers/
and there involve tables with fixed header and scrolling body
http://imar.spaanjaars.com/357/a-scrollable-table-with-a-fixed-header
http://anaturb.net/csstips/sheader.htm
You cannot do this with CSS alone. We must use javaScript. With jQuery you can do the following
var cw = $('#container').innerWidth(),
cs = $('#container').scrollTop();
$('#header').css({
'width': cw + "px"
});
$('#container').scroll(function() {
$('#header').css({
'top': $('#container').scrollTop(),
})
})
Check working example at http://jsfiddle.net/VswxL/2/
I haven't figured out how to do this with CSS alone. So, here's a solution which uses JavaScript (here, jQuery), but only runs when he content changes. If the size of your wrapper depends on the size of the window, you may also need to run it on resize. Here's the heart of it:
$.fn.fitTo = function(target){
var $el = $(this);
$(target).bind('refit', function(){
$el.width(this.clientWidth);
});
}
Call $header.fitTo($content) to bind the header to a custom refit event on the element with the content. Now, whenever the content changes such that a scroll bar may have appeared or disappeared, do…
$content.trigger('refit');
…and the width of the header is reset to the clientWidth of the element containing content. The header must be outside the scrolling element.
Working example
Related
I am using the Select2 control in a bootstrap grid, but when i select a values from the drop down which is a bigger value (here i mean the width), it expands and overrides the width specified by the "col-md" class of bootstrap
though there are many workarounds mentioned on a similar issue
https://github.com/t0m/select2-bootstrap-css/issues/42
but none of them worked for me
please guide. how can i restrict the width to that of its container element
I've also tried various suggested workarounds with no effect. In addition, I needed the select2 control to resize correctly when the window was resized so I defined a reset_select2_size function which is invoked with each resize. Though not shown here, this function should also be invoked whenever any change in a UI component requires resetting the select2 size within that component (for example when a hidden div containing a select2 becomes visible).
This isn't pretty by any standard, but until the bug will be fixed is seems to work fine for me,
function reset_select2_size(obj)
{
if (typeof(obj)!='undefined') {
obj.find('.select2-container').parent().each(function() {
$(this).find('.select2-container').css({"width":"10px"});
});
obj.find('.select2-container').parent().each(function() {
var width = ($(this).width()-5)+"px";
$(this).find('.select2-container').css({"width":width});
});
return;
}
$('.select2-container').filter(':visible').parent().each(function() {
$(this).find('.select2-container').css({"width":"10px"});
});
$('.select2-container').filter(':visible').parent().each(function() {
var width = ($(this).width()-5)+"px";
$(this).find('.select2-container').css({"width":width});
});
}
function onWindowResized( event )
{
reset_select2_size();
}
window.addEventListener('resize', onWindowResized );
In that case Use fixed width and use overflow:auto then u can retrict the with of the div or any tag
I found a workaround to fix the issue,
on the input-group i changed the Display from table to Block , and that worked :)
I have an a tag that I am using to specify the section on an HTML page where I want to move when a link is clicked:
<a name="ourServicesSection"></a>
This works fine, the only problem is that I have a fixed navbar on top of the page. So, when I click the link it moves to the section of the page, but a slice of it is covered up by the navbar. Is there a way I can "offset" the move by the size of the navbar? How would I do that?
Thanks
Putting a margin/padding at the top of whatever element you're scrolling to seems to be the common practice. Or move up the achor destination.
You can use Javascript (jQuery) to handle the scroll with offset or reposition element using margin
If you are willing to use jQuery, something like this would work.
$('a[href^="#"]').on('click', function(e) {
e.preventDefault();
var scrollTo = $(this).attr('href');
var pageOffset = $(scrollTo).offset().top - ($(window).height() / 2);
$(document).scrollTop(pageOffset);
});
Example: http://jsfiddle.net/vDQaT/
On my aspx page, I have two left and right portions. I want to show always left side (which is actually a 'div' containig treeview) while scrolling the right side (which are actual contents of page). Thanks
You need to put position: fixed; on the div element. That will anchor it to the viewport.
Hi I found the best solution! As always JQUERY saving my life !!
Just put a Div called as you wan, I've chosen the same in the example below: #scrollingDiv.
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script>
$().ready(function() {
var $scrollingDiv = $("#scrollingDiv");
$(window).scroll(function(){
$scrollingDiv
.stop()
.animate({"marginTop": ($(window).scrollTop() )}, "slow" );
});
});
</script>
I took that code from a website, it works and it's pretty easy to understand.
Fast forward to 2020, and it is now possible to do this with CSS.
<div style="position: sticky; top: 0;"> Tree view </div>
The user npas explains this quite nicely:
top is the distance to the viewport top the div should stay at when you scroll. Specifying top is mandatory. (…)
The sticky div will act like a normal div in all ways except when you scroll past it, then it will stick to the top of the browser.
Here's a jsfiddle to give you an idea.
MDN documentation
Supported by all modern browsers
You need to set the position of the div to Fixed in CSS. See this link for more information. You will need to set position using the top and left in css as well so it knows where to fix it!
The problem is that when the block moves, it gets attention and ability to concentrate on reading.
To remedy this using this function.
This code is perfect :
(change "220" and "46px" if necessary)
var $scrollingDiv = $("#scrollingDiv");
$(window).scroll(function(){
if ($(window).scrollTop()>220) {
$scrollingDiv
.css("position",'fixed' )
.css("top",'46px' )
} else {
$scrollingDiv
.css("position",'' )
.css("top",'' )
}
});
I'm doing some documentation where I make heavy use of anchors for linking between pages on a wiki.
see here:
http://code.google.com/p/xcmetadataservicestoolkit/wiki/ServicesExplained#Platform_Data_Structures
The feature that really makes this work well is when the browser shows the anchor at the absolute top of the pane. When it gets confusing is when linking to an anchor shows the anchor half-way down the page since the page is scrolled down all the way
see here:
http://code.google.com/p/xcmetadataservicestoolkit/source/browse/trunk/mst-common/src/java/xc/mst/utils/Util.java#227
My solution in the wiki (first link) was to put a blank image at the bottom of the page simply to make the browser show the anchor right at the top. Is there a better way to do this? Is there a way to do it in the second link (in which I can't add a blank image)?
Putting a blank image at the bottom of your page is a bad idea, since it will expand your document to a unnecessary height.
You could throw in some javascript to apply an effect to the anchor you just travelled to, to highlight it wherever it is.
Without altering the height of your document (i.e. adding extra padding at bottom), you'll always have this issue.
However, using bit of JS/jQuery, the user experience can be improved considerably:
On clicking a named anchor:
Instead of jumping in a flash (broswer's default behavior), add a smooth scroll
add an highlight to indicate current selection (this helps tremendously in 2nd case as the user can clearly see what is current)
Created a demo to illustrate the concepts: http://jsfiddle.net/mrchief/PYsyN/9/
CSS
<style>
.current { font-weight: bold; }
</style>
JS
function smoothScroll(elemId) {
// remove existing highlights
$('.current').css({backgroundColor: "transparent"}).removeClass('current');
var top = $(elemId).offset().top;
// do a smooth scroll
$('html, body').animate({scrollTop:top}, 500, function(){
// add an highlight
$(elemId).animate({backgroundColor: "#68BFEF" }, 500, function () {
// keep tab of current so that style can be reset later
$(elemId).addClass('current');
});
});
}
// when landing directly
if (document.location.hash) {
smoothScroll(document.location.hash);
}
$('a[href*="#"]').click(function() {
// utilizing the fact that named anchor has a corresponding id element
var elemId = $(this).attr('href');
smoothScroll(elemId);
});
You can create a absolutre positioned pseudo-element with a great height to targeted block using just the following CSS (for the second link in your post:
#nums td:target a::before {
content: '';
position: absolute;
height: 700px;
}
The height must be around the height of the viewport, so the best solution is to create these styles on the fly using js. But if you don't wan't to use js, just use height: 1000px or more — if you don't mind a gap at the bottom of course.
The best part: it's only CSS and there would be no gap when no anchors are targeted.
Edit: just a sneak peek into the future: if the vw/vh units would come to other browsers (now it's only in IE9), this could be awesomely done with just CSS using height: 100vh :)
You could use Javascript / jQuery to create a white div that has the necessary height needed to put your element at the top of the browser window, and you could even remove this upon scrolling away.
However I would highly recommend against doing so as this will expand your page where it isn't needed. It's a lot smarter to simply style the tag upon going there (through Javascript / jQuery) so it pops out to the viewer, for instance by setting the font-weight to bold or changing the background-color.
I would probably use a combination of jQuery and PHP for this:
PHP(somewhere right after your <body> element):
<?php
$anchor = explode('#', $_SERVER['REQUEST_URI']);
$anchor = $anchor[1];
echo '<div id="selected-anchor" anchor="'.$anchor.'"></div>';
?>
And then the jQuery:
<script type="text/javascript">
$(function(){
$('#selected-anchor').css('background-color', '[Whatever highlight color you want]');
});
</script>
Hope this helps.
I have a web page that displays a long line graph inside a div with overflow-x: scroll.
This works well as a web page allowing the use to scroll back and forward through the graph.
However, when printing the page the scroll position is reset to zero.
Is there a way to overcome this?
I think you're going to have to specify an alternate CSS for printing where you somehow need to remove the overflow:
<link rel="stylesheet" type="text/css” href="sheet.css" media="print" />
However, maybe there is an approach with JavaScript or even Flash? If I understand correctly, you only want to have a part of the graph printed (the one "selected" by the user?) and not the full one? I'm pretty sure that's not possible with plain HTML/CSS, but I strongly believe that Flash or maybe JavaScript/AJAX (to only load a part of the image at a time) can solve it.
You can't do this in plain CSS -- you will have to reimplement the scrolling using your Javascript UI library of choice to get what you want.
The user state of the scrollbar isn't used when printing (think about it, if you're scrolled 3 screens down a page and hit "print" does it make sense for the browser to only print the part of the document that's in your window at the time?). However, if you use JS, which actually manipulates the DOM (i.e. sets the x-position offset to -293 if the person has scrolled right 293 pixels, just like style="left: -293px; overflow: hidden;" in CSS), then it will show up as such in printed documents.
My suggestion is, unless the graphs are very wide, just skip all of this nonsense and use a printer stylesheet with width: 100% for the graph's <div> so the graph just shrinks to page width.
A simple approach would be to have some javascript which posts back to your page with the user's selected scroll position on a link saying something like 'setup for printing'. Then the server side returns a page with the graph relatively positioned at the scroll position with overflow:hidden to clip the graph appropriately.
Of course this would not work for users with javascript disabled - if you want to support this you would need the user to specify the scroll position in something like a text input element and submit button which you hid with javascript when enabled.
You need to temporarily turn the scroll position of the parent into a negative margin of the child, and put that parent as overflow:hidden.
Here's how to do it in Javascript (which is the only way, css cannot do that)
Note that you will need something to execute printDone() after the printing to restore everything as normal. You could trigger it with a wheel event e.g. because the user will only have a problem when trying to scroll. Or you can just put a button as I did, and show it only when printGo() is called.
<html>
<head>
<style>
#wrapper {
width:800px;
overflow-x:scroll;
}
#content {
width:2000px;
border:2px solid red;
}
#media print { /* This overwrites the css when printing */
#wrapper {
overflow-x:hidden;
}
}
</style>
</head>
<body>
Print<br>
I'm done printing!
<div id=wrapper>
<div id=content>
Hello this is my content.
</div>
</div>
<script>
var wrapper = document.getElementById('wrapper');
var content = document.getElementById('content');
var scrollPos;
function printGo(){
scrollPos = wrapper.scrollLeft; // Save scroll position
wrapper.scrollLeft = 0;
wrapper.style.overflowX = 'hidden'; // Optional since css does it
content.style.marginLeft = -scrollPos+'px'; // Put it as a negative margin of child instead
window.print();
}
function printDone(){
wrapper.scrollLeft = scrollPos; // Restore scroll position
wrapper.style.overflowX = 'scroll'; // Optional since css does it
content.style.marginLeft = '';
}
</script>
</body></html>