I'm creating vertically auto scrolling divs using jquery with animation... I have finished creating it but the only problem is when I scroll down the window to the middle of list div where divs are scrolling, it pushes the window up to the scrolling list div. I don't know what the problem is. However when I try to give the list div width in pixels, it is not pushing up...
Try to scroll down to the middle of the scrolling list div. You will understand what the problem is. Thanks...
setInterval(function(){
$('#list').stop().animate({scrollTop:40}, 400, 'swing', function(){
$(this).scrollTop(0).find('div:last').after($('div:first', this));
});
}, 1000);
* {
box-sizing: border-box;
}
body {
height: 1000px;
}
#list {
overflow: hidden;
width: 100%;
height: 250px;
background: red;
padding: 10px;
margin-top: 100px;
}
#list div {
display: block;
height: 30px;
padding: 10px 10px;
margin-bottom: 10px;
background: yellow;
}
.item:last-child {
margin-bottom: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
</div>
What an odd bug. From what I can tell, because of the removal/insertion of the first element to the end of the list, this results in Chrome re-rendering the list causing the change in your scrollY offset.
Personally, I can think of two ways to address the issue.
1) Remove the div (#list) from the DOM flow.
Note: This requires wrapping your #list element in a containing element.
Because your removing/appending elements to your #list element, this is causing a reflow to occur (???). Initially, I thought using position: absolute would address this, as you're no longer affecting the DOM flow. However, even position: absolute still causes the scroll position to jump.
I then looked at position: fixed, which DOES work (as it's basically sitting on top of everything) - This obviously isn't going to work as you want the list to scroll with the page! So, how can we get around this??
transform to the rescue!
Let's take advantage of a transform quirk! Usually, when an element is position: fixed, it's relative to the viewport. However, if an ancestor element has a transformation, the element that is fixed positioned will be relative to the transformed element. Let's give this a shot!
As I mentioned, you'll need to apply a wrapping/containing element to transform. In the code snippet below, I've wrapped your #list element with a new div#transformed.
CSS changes are straight forward and look like:
#transformed { transform: translateZ(0); }
#list { position: fixed; }
And that is it! Check out the snippet below to see it in action.
setInterval(function(){
$('#list').stop().animate({scrollTop:40}, 400, 'swing', function(){
$(this).find('div:last').after($('div:first', this));
});
}, 1000);
* {
box-sizing: border-box;
}
body {
height: 1000px;
}
#transformed {
transform: translateZ(0);
}
#list {
position: fixed;
overflow: hidden;
width: 100%;
height: 250px;
background: red;
padding: 10px;
margin-top: 100px;
}
#list div {
display: block;
height: 30px;
padding: 10px 10px;
margin-bottom: 10px;
background: yellow;
}
.item:last-child {
margin-bottom: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="transformed">
<div id="list">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
</div>
</div>
2) Sliding a layer
As for the second way to address the issue, this is more a discussion/opinion on how to approach this (so, unfortunately can't provide code).
Rather than manipulate the scrollTop, I would look into a "sliding" layer approach (either using transformY or top).
You'll find JS-based carousels take a similar approach (funny enough, carousels tend to either use a scroll-offset approach - as similar to this question, or a "sliding" layer approach! They just tend to do it horizontally)
As for the layer you manipulate, again I would suggest removing it from the DOM flow (so position: absolute). In theory, manipulating this layer shouldn't affect the scroll offset...
Anyway, hope this was helpful and the position: fixed approach works for you :)
Edit
Regarding your comment, you can achieve a "downward" scroll by reversing your setInterval logic. However, instead of scrolling and then moving the item that just scrolled out to the bottom of the list, you will need to move the element you want to scroll in to the top of the list, offset the scrollTop, and then scroll in.
Here's a snippet that demonstrates:
setInterval(function(){
$('#list')
.find('div:first')
.before($('div:last', '#list'))
.end()
.scrollTop(40)
.stop()
.animate({scrollTop:0}, 400, 'swing');
}, 1000);
* {
box-sizing: border-box;
}
body {
height: 1000px;
}
#transformed {
transform: translateZ(0);
}
#list {
position: fixed;
overflow: hidden;
width: 100%;
height: 250px;
background: red;
padding: 10px;
margin-top: 100px;
}
#list div {
display: block;
height: 30px;
padding: 10px 10px;
margin-bottom: 10px;
background: yellow;
}
.item:last-child {
margin-bottom: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="transformed">
<div id="list">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
</div>
</div>
Edit # 2:
Regarding up/down buttons, you can easily achieve that by combining the two scripts we've written so far! Here's are two snippets that animates up/down when you click (the first will scroll each time you click, and the second snippet will change the animation direction):
function animateList(direction) {
if (direction === 'down') {
$('#list')
.find('div:first')
.before($('div:last', '#list'))
.end()
.scrollTop(40)
.stop()
.animate({scrollTop:0}, 400, 'swing');
} else {
$('#list')
.animate({scrollTop:40}, 400, 'swing', function(){
$(this)
.find('div:last')
.after($('div:first', this));
});
}
}
$('button').on('click', function () {
var direction = $(this).attr('id');
animateList(direction);
});
* {
box-sizing: border-box;
}
body {
height: 1000px;
}
#transformed {
transform: translateZ(0);
}
#list {
position: fixed;
overflow: hidden;
width: 100%;
height: 250px;
background: red;
padding: 10px;
margin-top: 100px;
}
#list div {
display: block;
height: 30px;
padding: 10px 10px;
margin-bottom: 10px;
background: yellow;
}
.item:last-child {
margin-bottom: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="transformed">
<div id="list">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
</div>
</div>
<button id="up">Scroll Up</button>
<button id="down">Scroll Down</button>
And the snippet that changes the direction:
var interval;
function animateList(direction) {
// Reset interval
if (interval) {
clearInterval(interval);
}
if (direction === 'down') {
interval = setInterval(function () {
$('#list')
.find('div:first')
.before($('div:last', '#list'))
.end()
.scrollTop(40)
.stop()
.animate({scrollTop:0}, 400, 'swing');
}, 1000);
} else {
interval = setInterval(function () {
$('#list')
.animate({scrollTop:40}, 400, 'swing', function(){
$(this)
.find('div:last')
.after($('div:first', this));
});
}, 1000);
}
}
$('button').on('click', function () {
var direction = $(this).attr('id');
animateList(direction);
});
// Initial animation
animateList('up');
* {
box-sizing: border-box;
}
body {
height: 1000px;
}
#transformed {
transform: translateZ(0);
}
#list {
position: fixed;
overflow: hidden;
width: 100%;
height: 250px;
background: red;
padding: 10px;
margin-top: 100px;
}
#list div {
display: block;
height: 30px;
padding: 10px 10px;
margin-bottom: 10px;
background: yellow;
}
.item:last-child {
margin-bottom: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="transformed">
<div id="list">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
</div>
</div>
<button id="up">Scroll Up</button>
<button id="down">Scroll Down</button>
I have converted your inner divs to a unordered list. I added an overflow-y:scroll initially, which also worked, but changed it to overflow-y:hidden on seeing your comment. I found but both work. If you scroll down the page and then scroll back up, it doesn't 'start again' (unless it's had the time to iterate though all 10 list items). You may need to adjust the css/box height to get the red border at the bottom, but I'll leave this to you
Hope this helps
Overflow-hidden:
setInterval(function() {
$('#ulList').stop().animate({
scrollTop: 40
}, 400, 'swing', function() {
$(this).scrollTop(0).find('li:last').after($('li:first', this));
});
}, 1000);
* {
box-sizing: border-box;
}
body {
height: 1000px;
}
#list {
overflow-y:hidden;
width: 100%;
height: 250px;
background: red;
padding: 10px;
margin-top: 100px;
}
#list ul {
margin: 10px 10px;
padding: 10px 0px;
}
#list ul li {
display: block;
height: 30px;
margin-bottom: 10px;
background: yellow;
}
.item:last-child {
margin-bottom: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<ul id="ulList">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
</ul>
</div>
Overflow:scroll
setInterval(function() {
$('#ulList').stop().animate({
scrollTop: 40
}, 400, 'swing', function() {
$(this).scrollTop(0).find('li:last').after($('li:first', this));
});
}, 1000);
* {
box-sizing: border-box;
}
body {
height: 1000px;
}
#list {
overflow-y:scroll;
width: 100%;
height: 250px;
background: red;
padding: 10px;
margin-top: 100px;
}
#list ul {
margin: 10px 10px;
padding: 10px 0px;
}
#list ul li {
display: block;
height: 30px;
margin-bottom: 10px;
background: yellow;
}
.item:last-child {
margin-bottom: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<ul id="ulList">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
</ul>
</div>
Related
I am trying to show the .right-text1 element (which is inside .right-container div) when the mouse hovers over .project1 element (which is inside .left-container div). However, I am unable to code it with CSS since selectors work only inside the current parent div.
I have the following code:
.left-container {
float: left;
width: 25%;
}
.left-container li {
list-style: none;
padding: 10px;
font-size: 20px;
border: 2px solid;
margin-top: 5px;
}
.right-container {
width: 74%;
float: right;
margin-top: 16px;
height: 200px;
}
.right-text1,
.right-text2,
.right-text3,
.right-text4 {
border: 2px solid;
padding: 5px;
height: 50%;
margin-bottom: 3px;
}
/* This is where I try to show RIGHT-TEXT1 upon hovering on PROJECT1 div,
but the selector does not work due to trying to access .right-text1 but it is outside the current DIV */
.project1:hover~.right-text1 {
display: none;
}
<div class="left-container">
<ul>
<div class="project1">
<li>Project 1</li>
</div>
<div class="project2">
<li>Project 2</li>
</div>
<div class="project3">
<li>Project 3</li>
</div>
<div class="project4">
<li>Project 4</li>
</div>
</ul>
</div>
<div class="right-container">
<div class="right-text1" style="background-color: tomato;">
Information about Project 1
</div>
<div class="right-text2" style="background-color: teal;">
Information about Project 2
</div>
<div class="right-text3" style="background-color: green;">
Information about Project 3
</div>
<div class="right-text4" style="background-color: yellow;">
Information about Project 4
</div>
</div>
It is imperative to keep the format, where the two containers reside next to each other and 25% and 74% width stays.
It might be super easy, but I am learning CSS for a week now and this stumbled me.
Any help would be greatly appreciated.
As explaned in the comments, you'll need JS for that.
Here a sample that adds a class on mouse enter, and remove it on mouse leave, mimicking the hover effect.
document.querySelectorAll('[data-project]').forEach(project => {
const name = project.dataset.project
const infoElement = document.querySelector(`[data-project-info="${name}"]`)
// Mouse enter
project.addEventListener('mouseenter', () => {
infoElement.classList.add('is-hovered')
})
// Mouse leave
project.addEventListener('mouseleave', () => {
infoElement.classList.remove('is-hovered')
})
})
.left-container {
float: left;
width: 25%;
}
.left-container li {
list-style: none;
padding: 10px;
font-size: 20px;
border: 2px solid;
margin-top: 5px;
}
.right-container {
width: 74%;
float: right;
margin-top: 16px;
height: 200px;
}
.right-text1,
.right-text2,
.right-text3,
.right-text4 {
border: 2px solid;
padding: 5px;
height: 50%;
margin-bottom: 3px;
display: none;
}
.right-text1.is-hovered,
.right-text2.is-hovered,
.right-text3.is-hovered,
.right-text4.is-hovered {
display: block;
}
<div class="left-container">
<ul>
<div class="project1" data-project="1">
<li>Project 1</li>
</div>
<div class="project2" data-project="2">
<li>Project 2</li>
</div>
<div class="project3" data-project="3">
<li>Project 3</li>
</div>
<div class="project4" data-project="this-text-matches-here">
<li>Project 4</li>
</div>
</ul>
</div>
<div class="right-container">
<div class="right-text1" style="background-color: tomato;" data-project-info="1">
Information about Project 1
</div>
<div class="right-text2" style="background-color: teal;" data-project-info="2">
Information about Project 2
</div>
<div class="right-text3" style="background-color: green;" data-project-info="3">
Information about Project 3
</div>
<div class="right-text4" style="background-color: yellow;" data-project-info="this-text-matches-here">
Information about Project 4
</div>
</div>
I m creating ticker in which the divs will be scrolling infinitely vertically on next/prev buttons ... I have created it but there is a small issue in it .. when i click on prev button the divs scrolls upward on first click and after that it scrolls downward and same goes for next button as well ..Someone help please
var buttons = $('.next-prev');
$(buttons).each(function(){
$(this).click(function(){
var id = $(this).attr('id');
if(id=="next"){
$('#scroll-div').stop().animate({scrollTop:40},400,'swing',function(){
$(this).scrollTop(0).find('div:last').after($('div:first', this));
});
}
else {
$('#scroll-div').stop().animate({scrollTop:40},400,'swing',function(){
$(this).scrollTop(40).find(' div:first').before($(' div:last', this));
});
}
})
})
* {
box-sizing: border-box;
}
#scroll-div {
overflow: hidden;
width: 300px;
height: 250px;
background: green;
padding: 10px;
}
#scroll-div div {
display: block;
height: 30px;
padding: 10px 10px;
margin-bottom: 10px;
background: cyan;
}
.item:last-child {
margin-bottom: 0px;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<button class="next-prev" id="next">
up
</button>
<button class="next-prev" id="prev">
down
</button>
</div>
<div id="scroll-div">
<div>div 1</div>
<div>div 2</div>
<div>div 3</div>
<div>div 4</div>
<div>div 5</div>
<div>div 6</div>
<div>div 7</div>
<div>div 8</div>
<div>div 9</div>
<div>div 10</div>
</div>
var buttons = $('.next-prev');
$('#scroll-div').prepend($('#scroll-div').find('div:last-child')); // prepend last element
$('#scroll-div').scrollTop(40); // scroll div to position 40 so first (div 10) not visible
$(buttons).each(function(){
$(this).click(function(){
var id = $(this).attr('id');
if(id=="next"){
$('#scroll-div').append($('#scroll-div').find('div:first-child')); //do modification first
} else {
$('#scroll-div').prepend($('#scroll-div').find('div:last-child'));
}
$('#scroll-div').stop().animate({scrollTop:40},400,'swing'); // then scroll
})
})
* {
box-sizing: border-box;
}
#scroll-div {
overflow: hidden;
width: 300px;
height: 250px;
background: green;
padding: 10px;
}
#scroll-div div {
display: block;
height: 30px;
padding: 10px 10px;
margin-bottom: 10px;
background: cyan;
}
.item:last-child {
margin-bottom: 0px;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<button class="next-prev" id="next">
up
</button>
<button class="next-prev" id="prev">
down
</button>
</div>
<div id="scroll-div">
<div>div 1</div>
<div>div 2</div>
<div>div 3</div>
<div>div 4</div>
<div>div 5</div>
<div>div 6</div>
<div>div 7</div>
<div>div 8</div>
<div>div 9</div>
<div>div 10</div>
</div>
Here's a bit of code for something, like a carousel.
The problem is I can't switch to the 2nd card when I first press the Right arrow. I think it's because the function doesn't know that cardStack left property equals -20px. But when I add this bit of code, var l = cardStack.left;, into a function, it works fine. But afaik it's not a good idea to mention document. every time I call a function. I need your advice
var cardStack = document.getElementById('allCards');
var l = cardStack.left;
document.onkeydown = cardsShifting;
function cardsShifting(e) {
switch (e.keyCode) {
case 37:
shiftCard('left');
break;
case 39:
shiftCard('right');
break;
}
}
function shiftCard(direction) {
if (direction === 'right') {
l = l - 640;
if (l >= -5780) {
cardStack.style.left = l + 'px';
} else {
l = -20;
cardStack.style.left = l + 'px';
}
}
}
#allCards {
position: relative;
width: 6400px;
height: 400px;
left: -20px;
display: inline-block;
}
#currentCardWindow {
position: absolute;
width: 600px;
height: 420px;
top: 50%;
left: 50%;
margin-top: -200px;
margin-left: -300px;
overflow: hidden;
box-sizing: border-box;
}
.card {
position: relative;
width: 600px;
height: 400px;
float: left;
margin: 0 20px;
}
<div id="currentCardWindow">
<div id="allCards">
<div class="card">card 1</div>
<div class="card">card 2</div>
<div class="card">card 3</div>
<div class="card">card 4</div>
<div class="card">card 5</div>
<div class="card">card 6</div>
<div class="card">card 7</div>
<div class="card">card 8</div>
<div class="card">card 9</div>
<div class="card">card 10</div>
</div>
</div>
When you are doing cardStack.style.left you're not actually looking at the CSS but rather at the style attribute on the element. Fortunately, there is a way to look at the CSS! We can use getComputedStyle.
The window.getComputedStyle() method returns an object that reports the values of all CSS properties of an element after applying active stylesheets and resolving any basic computation those values may contain. Individual CSS property values are accessed through APIs provided by the object or by simply indexing with CSS property names.
With this you can do window.getComputedStyle(cardStack) to get all the CSS styles and then on to that you can add getPropertyValue("left") to just look at the left property. This returns -20px but we want to ignore the px we can do this with parseInt.
I've put it all together in this snippet.
var cardStack = document.getElementById('allCards');
var l = parseInt(window.getComputedStyle(cardStack).getPropertyValue("left"));
document.onkeydown = cardsShifting;
function cardsShifting(e) {
switch (e.keyCode) {
case 37:
shiftCard('left');
break;
case 39:
shiftCard('right');
break;
}
}
function shiftCard(direction) {
if (direction === 'right') {
l = l - 640;
if (l >= -5780) {
cardStack.style.left = l + 'px';
} else {
l = -20;
cardStack.style.left = l + 'px';
}
}
}
#allCards {
position: relative;
width: 6400px;
height: 400px;
left: -20px;
display: inline-block;
}
#currentCardWindow {
position: absolute;
width: 600px;
height: 420px;
top: 50%;
left: 50%;
margin-top: -200px;
margin-left: -300px;
overflow: hidden;
box-sizing: border-box;
}
.card {
position: relative;
width: 600px;
height: 400px;
float: left;
margin: 0 20px;
}
<div id="currentCardWindow">
<div id="allCards">
<div class="card">card 1</div>
<div class="card">card 2</div>
<div class="card">card 3</div>
<div class="card">card 4</div>
<div class="card">card 5</div>
<div class="card">card 6</div>
<div class="card">card 7</div>
<div class="card">card 8</div>
<div class="card">card 9</div>
<div class="card">card 10</div>
</div>
</div>
I hope you find this helpful.
I have a div as so:
<div class="country">
<div class="cty_popover">
<p>TITLE</p>
<ul>
<li>NAME 1</li>
<li>NAME 2</li>
</ul>
</div>
<img src="resources/images/map-marker.png" alt=" ">
</div>
And this jQuery:
$(document).ready(function(){
$('.country img').hover(function() {
$(this).parents('.cty_popover').fadeIn(800);
},
function() {
$('.cty_popover').fadeOut(300);
});
});
I know this line is wrong in the jQuery:
$(this).find('.cty_popover').fadeIn(800);
I need to target:
.cty_popover
from within the function:
$('.country img').hover
So basically my question is:
How do I target .cty_popover using $(this)? I need to move up from the 'img' to target it, but not sure how?
I have a lot of these .cty_popover divs and that's why I want to use $(this) so I don't target them all.
Anyone any ideas why I can't get this working?
Thanks
As the img is a sibling of the cty_popover, you can target it using the prev() function - see a demo below:
$(document).ready(function() {
// hide all `cty_popover` sections initially
$('.cty_popover').hide();
// hover listener
$('.country img').hover(function() {
$(this).prev('.cty_popover').fadeIn(800);
}, function() {
$(this).prev('.cty_popover').fadeOut(300);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="country">
<div class="cty_popover">
<p>TITLE</p>
<ul>
<li>NAME 1</li>
<li>NAME 2</li>
</ul>
</div>
<img src="http://placehold.it/200x200">
</div>
Since the img node is a sibling of the cty_popover node, replacing this line
$(this).parents('.cty_popover').fadeIn(800);
with this should work
$(this).siblings('.cty_popover').fadeIn(800);
Here's an example
You should use siblings: https://api.jquery.com/siblings/
See this example working on your HTML:
$(document).ready(function(){
$('.country').children('img').hover(function() {
$(this).siblings( '.cty_popover').fadeIn(800);
},
function() {
$('.cty_popover').fadeOut(300);
});
});
.country {
position. relative;
width: 300px;
}
.country > img {
width: 100%;
display: block;
}
.country .cty_popover {
display: none;
position: absolute;
left: 10px;
top: 10px;
background: rgba(255,255,0,.9);
padding: 5px;
border-radius: 5px;
width: 285px;
}
.country .cty_popover:after {
content: "";
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-top: 20px solid rgba(255,255,0,.9);
position: absolute;
bottom: -20px;
left: 50%;
margin-left: -10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="country">
<div class="cty_popover">
<p>TITLE</p>
<ul>
<li>NAME 1</li>
<li>NAME 2</li>
</ul>
</div>
<img src="https://placeimg.com/300/200/tech" alt=" ">
</div>
I am working on treeview component for left side menu (see screenshot):
All items in tree view must be selectable. I set width 100% for items and when I select item in tree width of highlighted region is less than left side panel:
But width of highlighted region to be equal to width of left side panel. I know that it can be achieved with margin and padding manipulations for highlighted region e.g.:
{
margin: 0 -400px;
padding: 0 400px;
}
But it leads to horizontal scrollbar:
Are there any "clever" ways to make highlighted region stretch to the container(left side panel)?
Each child should fit inside its parent when width: 100% and/or max-width: 100% Some, like LI, do not.
To get the result you want each item needs rules:
white-space: nowrap (so it won't wrap to next line)
overflow: hidden (to chop off excess text)
width: 100% (to stretch to parent)
See below snippet for two examples: with UL/LI and DIV's
html,
body {
/*UPDATE*/
box-sizing: border-box;
height: 100%;
width: 100%;
overflow: hidden
}
*,
*:before,
*:after {
box-sizing: inherit
}
/* { outline: 1px dotted red } /* for debug */
ul,
li {
list-style: none;
margin: 0;
padding: 0;
}
.side-panel {
max-width: 200px;
padding: 4px;
border: 1px solid rgba(0, 0, 0, .2)
}
ul,
.treeview {
max-width: 100%;
text-align: right;
}
li,
.item {
height: 23px; /*ADD*/
width: 100%;
white-space: nowrap;
overflow: hidden;
margin: 5px 0; /*ADD*/
}
li:hover,
.item:hover { /*ADD*/
height: 23px;
text-align: left;
border: 1px dashed cornflowerblue;
cursor: pointer
}
li:nth-child(even),
.item:nth-child(odd) {
background: rgba(0, 255, 0, 0.1)
}
li:nth-child(odd),
.item:nth-child(even) {
background: rgba(0, 0, 255, 0.1)
}
<div class="side-panel">
<h3>example with UL/LI</h3>
<ul>
<li>some item 1</li>
<li>some item 2</li>
<li>some item 3</li>
<li>some item 4fgdfg g</li>
<li>some item 5 sad d fd</li>
<li>some item 6 sdtresertg zdf dfsfd</li>
<li>some item 7</li>
</ul>
</div>
<div class="side-panel">
<h3>example with DIV's</h3>
<div class="treeview">
<div class="item">some item 1</div>
<div class="item">some item 2</div>
<div class="item">some item 3</div>
<div class="item">some item 4fgdfg g</div>
<div class="item">some item 5 sad d fd</div>
<div class="item">some item 6 sdtresertg zdf dfsfd</div>
<div class="item">some item 7</div>
</div>
</div>