I have a nested shopping-type list that is grouped by type (and has descriptions for each item).
What I'm wanting to do is have the last type scrolling in the list, until the point that it would scroll off the top of the list.
A list ma开发者_如何学JAVAy declared as
<div id="items">
<item-type>Type A</item-type>
<description>a</description>
<description>b</description>
<description>c</description>
<item-type>Type B</item-type>
<description>d</description>
<description>e</description>
<description>f</description>
<description>g</description>
<description>h</description>
</div>
I'm using element types so that I can use #items > item-type:last-of-type
in CSS3 to select the last element.
#items {
word-wrap: break-word;
overflow: auto;
height: 100%;
}
#items > * {
display: block;
}
#items > item-type:last-of-type {
position:absolute;
bottom: 100px;
}
So the only point now, is how do I keep it (effectively) position: relative; top: 0
to position: absolute; top: 0
using only CSS3?
I'm using FF4 and HTML5, so you can go all out; this won't be supported on older browsers. Also, using calc()
is fine.
The valid view options are be something like:
______________________________________
Type A a Type B
a b e
b c f
c Type B g
d h
---------------------------------------
Where the lines are the visible area, and each column shows how it would appear given a certain amount of data (progression left to right)
If I understand the problem correctly, you want to create something like the iPhone Contacts list. Looking at the solution someone already built it uses JavaScript. Also, I've thought about it and gone through all the CSS3 specs but cannot determine anything that could be used here to achieve the same affect without JavaScript.
I knocked up a small demo, but again this uses JavaScript. I just don't think it's possible with pure CSS, although I'm sure someone will correct me if that's not the case :-)
HTML
<div id="items">
<item-type>Type A</item-type>
<description>a</description>
<description>b</description>
<description>c</description>
<item-type>Type B</item-type>
<description>d</description>
<description>e</description>
<description>f</description>
<description>g</description>
<description>h</description>
<description>i</description>
<description>j</description>
<description>k</description>
<description>l</description>
</div>
CSS
#items {
word-wrap: break-word;
overflow: auto;
height:100px;
border:1px dashed red;
width:200px;
}
#items > * {
display: block;
}
#items > item-type {
border:1px dashed blue;
background-color:#fff;
width:180px;
}
JavaScript (jQuery 1.6+)
var itemsTop = $('#items').position().top;
var itemTypeHeight = $('item-type').height();
var itemTypeBottom = itemsTop + itemTypeHeight;
$('#items').scroll(function() {
$('item-type').each(function() {
$(this).css({position:''});
if ($(this).position().top < itemsTop + itemTypeHeight) {
$(this).css({position:'fixed',top:itemsTop});
}
});
});
I think it's not possible for the following reasons (which may or may not be related):
- When in normal viewing, a
relative
position is needed; at the top of the visible area, it would need to change toabsolute
- you could use
calc()
andmin()
ormax()
with the visible height, the current element's height and the current scroll position; except that none of these calculated properties are available to css - Another idea is making more absolute positioning of the 2nd item level, but there's no way of referencing the absolute-parent's height as well as the absolute-grandparent's height.
I think the first point is the easiest way to convince myself that it's not possible. The other two convince me that combinations of fancy css functions and absolute positioning are sunk as well.
精彩评论