Fix covering hovered table / hovering problem with table - javascript

I have a problem with creating table. I need to create a table with some of cells with hover/tooltip event. For example when I point to the cell, I need to show one column table with links, but when do this in that way I have problem with overlaping (I can't use links from first cell). For now I only tried to use CSS and HTML, but soltuion with JS is also accepted.
HTML:
<div class="ttip">
<a class="foo">FOO</a>
<table>
<tr>
<td><a href='bar'>Bar</a></td>
</tr>
<tr>
<td><a href='baz'>Baz</a></td>
</tr>
</table>
</div>
<div class="ttip">
<a class="foo">FOO2</a>
<table>
<tr>
<td><a href='bar2'>Bar2</a></td>
</tr>
<tr>
<td><a href='baz2'>Baz2</a></td>
</tr>
</table>
</div>
Style:
.ttip {
position: relative;
display: table;
}
.ttip>table {
position: absolute;
white-space: nowrap;
border-collapse: collapse;
display: none;
}
.ttip>table td {
border: 1px dotted #000;
padding: 2px;
}
.ttip:hover>table {
display: table;
}
Live:
https://jsfiddle.net/uLm0gjcn/3/
Regards

The FOO2 is rendered after the FOO , meaning when its displayed, its technically below FOO2 text. To fix that you need to apply z-index in your css here in .ttip>table
.ttip>table {
position: absolute;
white-space: nowrap;
border-collapse: collapse;
display: none;
z-index: 1;
}
This way, when the drop-down/tool-tip appears from FOO, it is rendered on top of FOO2.
Edit. Also, to make it not transparent, apply a background-color to css in .ttip>table. for example for a white background background-color: white;

Related

Expand last table column to fill container

How do you expand the last column of a table to fill the parent container without specifying a width for the container?
In this jsfiddle, I want the last column of the green table to fill the blue container. The width of the container should only be determined by its text.
.container{
background-color: #003388;
color: white;
display: inline-block;
}
table {
background-color: #008833;
color: white;
width:auto;
}
table tr td:last-child {
/* width:100%; */
}
Setting the width of the last td fills the entire page.
One possible approach is given below. It uses...
width: 100% rule (instead of width: auto) to make table fill the container
width: 1px; white-space: nowrap; combo trick to make all the columns define their width based on content width; without that rule it seems there's no simple way to override default behaviour of table-layout: auto sharing the whole width between columns equally.
max-width: 1px for the last column to ensure that inline-block container is not extended when that column grows, and text is wrapped instead
.container{
background-color: #003388;
color: white;
display: inline-block;
}
table {
background-color: #008833;
color: white;
width: 100%;
}
table td:not(:last-child) {
width: 1px;
white-space: nowrap;
}
table td:last-child {
max-width: 1px;
}
<div class="container">
long text long text long text long text long text long text
<table>
<tr>
<th>Product</th>
<th>Cardinality</th>
<th>Price per item</th>
</tr>
<tr>
<td>Apple</td>
<td>5</td>
<td>$2</td>
</tr>
<tr>
<td>Pear</td>
<td>3</td>
<td>$3</td>
</tr>
<tr>
<td>Sausage</td>
<td>10</td>
<td>$0.5</td>
</tr>
<tr>
<td>Pineapple</td>
<td>2</td>
<td>$8</td>
</tr>
<tr>
<td>Tomato</td>
<td>5</td>
<td>$1</td>
</tr>
<tr>
<td>Lightsaber</td>
<td>2</td>
<td>$99 999 999999999 99999999 99999999</td>
</tr>
</table>
</div>
Use fractional units fr to automatically take up the fraction you desire

How to style element to overlap scroll

I am working on an already existing project, with a pretty complex front end. I want to introduce a new element which should be a substitute for a dropdown. Basically it's a div bind with knockout to a collection.
The problem I have is that on a single page there are several divs inside which a more complex structure is rendered for each one, and inside one of this divs is my custom dropdown. The problem is that when I try to expand the dropdown (a class bind to a click event using jQuery) my "dropdown" is rendered up to the top of the div because of the fact that there is too much content and in order to preserve the entire page look and appearance there is no good way to use overflow: visible.
A snippet that pretty well introduce my problem is HERE :
$('.show-dropdown').click(function() {
if ($(this).next('.render-this').hasClass('hide-me')) {
$(this).next('.render-this').removeClass('hide-me');
} else {
$(this).next('.render-this').addClass('hide-me');
}
})
td {
position: relative;
}
#top-div {
width: 500px;
max-width: 500px;
border: 1px solid black;
max-height: 100px;
overflow-y: auto;
white-space: nowrap;
}
#bottom-div {
width: 500px;
max-width: 500px;
border: 1px solid black;
max-height: 100px;
overflow-y: auto;
}
.show-dropdown {
width: 120px;
height: 40px;
background-color: green;
}
.render-this {
position: absolute;
bottom: 10px;
z-index: 5;
width: 20px;
height: 150px;
background-color: red;
}
.hide-me {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="top-div">
<p>
lorem ipsum lorem ipsum lorem ipsum lorem ipsumlorem ipsumlorem ipsum lorem ipsum lorem ipsum
</p>
</div>
<div id="bottom-div">
<table class="w3-table">
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
</tr>
<tr>
<td><div class="show-dropdown"></div><div class="render-this hide-me"></div></td>
<td><div class="show-dropdown"></div><div class="render-this hide-me"></div></td>
<td><div class="show-dropdown"></div><div class="render-this hide-me"></div></td>
<td><div class="show-dropdown"></div><div class="render-this hide-me"></div></td>
<td><div class="show-dropdown">></div><div class="render-this hide-me"></div></td>
<td><div class="show-dropdown"></div><div class="render-this hide-me"></div></td>
</tr>
</table>
I've read a lot about this topic. My conclusion so far is that if you have overflow it is pretty much game over. However from the question HERE I see that with transform and maybe some other CSS it might be still possible to achieve something. Also, what I need is to render my dropdown completely, I was also thinking about using overflow: visible and some sort of JS created scroll, but haven't dig deep for this still.
Demo
https://jsfiddle.net/mg8zbr41/172/
(I hope this was the desired behaviour)
Explanation
The whole problem would have been solved if we were allowed to have overflow-x: auto and overflow-y: visible together. But we cannot do that (see this answer). So we use the following workaround.
If you want to have want the red div to pop out you cannot put
position: relative parent. So we remove that first
Now bottom becomes relative to parent relative element i.e. body but we don't want that so we also remove bottom
Now we have top, right, bottom, left all as auto. So the elements placed below the green box as it would have been if it was static. The only difference is it pops out of the bottom box
Now we want it to be 10px above the green box for that we use translateY(calc(100% + 10px) * -1)
Now this works till there's no scrolling. When the div is scrolled the red box stays there and doesn't move with its green box, we need to fix that
This can be easily fixed if we know how much is the div scrolled. Suppose the div is scrolled by 100px towards left we'll shift the red box towards left by 100px
We cannot find scrollLeft without JS. I personally don't like JS intervention for styling. We cannot avoid it but at least we can make it more semantic by using css variables for communication between JS and CSS.
We use JS to update a --scroll-left css variable on #bottom-div with the scrollLeft value
Once we have --scroll-left we can now add translateX(calc(var(--scroll-left,0px) * -1))
Also we don't want the red box to pop out of the box horizontally. We cannot fix this by overflow: hidden because that would require position: relative. So we use clip-path: inset(-999px 0px -999px 0px).
Finally we achieved want we wanted. Phew.
Demerits:
Horizontal repositioning will be laggy in Firefox because of Scroll Lined Effects. Same might be the problem in mobile browsers
See also:
https://css-tricks.com/popping-hidden-overflow/ Source of inspiration for my answer but both (solution in the article and my solution) are quite different but same core approach
You can add a wrapper div with relative position around the scrollable container and then your absolute positioned dropdown would bind to that element. As you can see in this example.
css:
.position-relative {
position: relative;
}
#top-div {
width: 500px;
max-width: 500px;
border: 1px solid black;
max-height: 100px;
overflow-y: auto;
white-space: nowrap;
}
#bottom-div {
width: 500px;
max-width: 500px;
border: 1px solid black;
max-height: 100px;
overflow-y: auto;
}
.show-dropdown {
width: 120px;
height: 40px;
background-color: green;
}
.render-this {
position: absolute;
bottom: 10px;
z-index: 5;
width: 20px;
height: 150px;
background-color: red;
}
.hide-me {
display: none;
}
html:
<div class="position-relative">
<div id="bottom-div">
<table class="w3-table">
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
</tr>
<tr>
<td>
<div class="show-dropdown"></div>
<div class="render-this hide-me"></div>
</td>
<td>
<div class="show-dropdown"></div>
<div class="render-this hide-me"></div>
</td>
<td>
<div class="show-dropdown"></div>
<div class="render-this hide-me"></div>
</td>
<td>
<div class="show-dropdown"></div>
<div class="render-this hide-me"></div>
</td>
<td>
<div class="show-dropdown">></div>
<div class="render-this hide-me"></div>
</td>
<td>
<div class="show-dropdown"></div>
<div class="render-this hide-me"></div>
</td>
</tr>
</table>
</div>
</div>
js
$('.show-dropdown').click(function() {
if ($(this).next('.render-this').hasClass('hide-me')) {
$(this).next('.render-this').removeClass('hide-me');
} else {
$(this).next('.render-this').addClass('hide-me');
}
})
Then you can adjust the top, left, right, bottom properties as you wish.
If you change your CSS as follows, you can get this to work as you would like:
Remove the position:relative; from your td.
Use a different approach to make the #bottom-div expend to it's content, using display: table;, and also apply the position:relative; to it.
all other css rules stay the same.
So, this is your new css:
#top-div {
width: 500px;
max-width: 500px;
border: 1px solid black;
max-height: 100px;
overflow-y: auto;
white-space: nowrap;
}
#bottom-div {
width: 500px;
max-width: 500px;
border: 1px solid black;
max-height: 100px;
position: relative;
display: table;
}
.show-dropdown {
width: 120px;
height: 40px;
background-color: green;
}
.render-this {
position: absolute;
bottom: 10px;
z-index: 5;
width: 20px;
height: 150px;
background-color: red;
}
.hide-me {
display: none;
}
Here is a link to a Fiddle with the new css.

Fixed height for bootstrap pre-scrollable DIV

In my application I have to display bootsatarp grid for database records. Since the number of records count are large enough to view without full page scrolling I wrap my table with bootstrap pre-scrollable div and it gave me the functionality to scroll the table. However all the time DIV size is half of the browser windows. I tried almost every stack overflow posts and suggestions and simply they not work for me. I also tried to fix this with support of java script and it also failed.
This is my HTML code
<div class="col-md-9">
<div class="pre-scrollable">
<table class="table table-bordered table-hover header-fixed" id="sometable">
<thead>
<tr>
<th>EMP_No</th>
<th>Name</th>
<th>Designation</th>
<th>Department</th>
<th>Type</th>
<th>#Days</th>
<th>Start Date</th>
<th>End Date</th>
<th>Half day</th>
<th>Status</th>
</tr>
</thead>
<tbody>
</tbody>
<?php //php code for print the table
?>
</div>
</div>
I populate above table with the results of PHP code. I have not idea how to set this DIV's height to fixed value or full value of the browser windows.below are the CSS that are use
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: center;
padding: 1px;
}
thead th {
text-align: center;
background-color: #3498db;
}
tr:nth-child(even) {
background-color: #dddddd;
}
</style>
This is the result web page
There is a max-height property set for the .pre-scrollable div in the bootstrap css file.
.pre-scrollable {
max-height: 340px;
overflow-y: scroll;
}
That might be the source of your problem.
For simplicity you can use css viewport dimensions. Something like this:
<div class="pre-scrollable" style="max-height: 75vh">
<table>...</table>
</div>
where "75vh" is 75% of visible height.
Twitter bootstrap - Fixed layout with scrollable sidebar will help... As the example on linked page will show you need to set the height of the div not table.
<style type="text/css">
body, html {
height: 100%;
overflow: hidden;
}
.navbar-inner {
height: 40px;
}
.scrollable {
height: 100%;
overflow: auto;
}
.max-height {
height: 100%;
}
.no-overflow {
overflow: hidden;
}
.pad40-top {
padding-top: 40px;
}
</style>

How to expand input field to the right in a header bar

I have a header bar with left-aligned items, center items and right-aligned items. In the center, I have multiple items and a search input field. When the search field gets focus, I'm making it wider by animating the width. Right now, because the items are centered, it's animating both left and right to center the content. How can I change this so it keeps the alignment and expands the width to the right?
I'm not using Bootstrap.
I'm currently using a table for the header bar content. I'm open to changing that, but if there's a way to do it with the current design, that would be preferred.
Here's a JSFiddle...click in the search field to see what's happening: https://jsfiddle.net/L60g0j64/1/
EDIT: I've updated it with the suggested solution below. My only issue is that the red container surrounding the input should expand also.
HTML/CSS/JS Snippet
$('#search').focus(function() {
$(this).val("");
$('#hidden_content').css('display','inline');
$(this).animate({width: '180px'}, 200);
});
$('#search').blur(function() {
$(this).val('Search');
$('#hidden_content').css('display','none');
$(this).animate({width: '120px'}, 200);
});
.header-navbar {
cursor: pointer;
white-space: nowrap;
background-color: #1f2127;
color: #cbcbcb;
min-width: 0;
text-overflow: ellipsis;
z-index: 299;
top: 0px;
left: 0px;
width: 100%;
height: 32px;
float: none;
position: fixed;
border-spacing: 0px;
}
td.cell-center {
text-align: center;
}
.cell-center table {
margin: 0 auto;
}
.header-table {
height: 32px;
border: none;
border-spacing: 0px;
}
td.header_rtd {
padding-right:12px;
}
td.header_ltd {
padding-left:12px;
}
.search-wrapper {
max-width: 124px;
background-color: red;
padding:4px;
}
.hidden_content{
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="header-navbar" id="header" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<table class="header-table" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class='header_rtd'>left1</td>
<td class='header_rtd'>left2</td>
</tr>
</table>
</td>
<td width=100% class='cell-center'>
<table class="header-table" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class='header_rtd'>center</td>
<td class='header_rtd'>center</td>
<td><div class="search-wrapper">
<input class="search" id="search" style="width: 120px;" type="text" size="60" value="Search"/>
<div class='hidden_content' id='hidden_content'>
hidden content
</div>
</div></td>
</tr>
</tbody>
</table>
</td>
<td>
<table class="header-table" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class='header_ltd'>right1</td>
<td class='header_ltd'>right2</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
One quick solution would be to give the parent element a max-width equal to the initial width of the element. In doing so, the element will still be centered relative to the initial width because the input element's animated width will not effect the width of the parent element.
Updated Example
.search-wrapper {
max-width: 124px;
}
As a side note, you don't need jQuery/JS to animate the width, you can simply use a CSS transition along with the :focus pseudo-class.
Updated Example
.search-wrapper input.search {
transition: 1s width ease;
width: 120px;
}
.search-wrapper input.search:focus {
width: 180px;
}

Trying to make fixed table headers with horizontal scroll bar. How to set overflow: auto, but keep margins transparent?

I am trying to make a table with fixed headers and horizontal scrolling functionality, but to do so I need to make the "section"'s top margin transparent in what I have here:
html, body {
margin:0;
padding:0;
height:100%;
}
.section {
position: relative;
border: 1px solid #000;
padding-top: 37px;
background: #500;
margin-top: 37px;
}
.container {
margin-top: -37px;
overflow-y: auto;
height: 200px;
}
table {
border-spacing: 0;
width:100%;
}
td + td {
border-left:1px solid #eee;
}
td, th {
border-bottom:1px solid #eee;
background: #ddd;
color: #000;
padding: 10px 25px;
}
th {
height: 0;
line-height: 0;
padding-top: 0;
padding-bottom: 0;
color: transparent;
border: none;
white-space: nowrap;
}
th div {
position: absolute;
margin-top:-37px;
background: transparent;
color: #fff;
padding: 9px 25px;
top: 0;
margin-left: -25px;
line-height: normal;
border-left: 1px solid #800;
}
th:first-child div {
border: none;
}
<div class="section">
<div class="container">
<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>
<tbody>
<tr>
<td>align</td>
<td>left, center, right</td>
<td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the alignment of a table according to surrounding text</td>
</tr>
<tr>
<td>bgcolor</td>
<td>rgb(x,x,x), #xxxxxx, colorname</td>
<td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the background color for a table</td>
</tr>
<tr>
<td>border</td>
<td>1,""</td>
<td>Specifies whether the table cells should have borders or not</td>
</tr>
<tr>
<td>cellpadding</td>
<td>pixels</td>
<td>Not supported in HTML5. Specifies the space between the cell wall and the cell content</td>
</tr>
<tr>
<td>cellspacing</td>
<td>pixels</td>
<td>Not supported in HTML5. Specifies the space between cells</td>
</tr>
<tr>
<td>frame</td>
<td>void, above, below, hsides, lhs, rhs, vsides, box, border</td>
<td>Not supported in HTML5. Specifies which parts of the outside borders that should be visible</td>
</tr>
<tr>
<td>rules</td>
<td>none, groups, rows, cols, all</td>
<td>Not supported in HTML5. Specifies which parts of the inside borders that should be visible</td>
</tr>
<tr>
<td>summary</td>
<td>text</td>
<td>Not supported in HTML5. Specifies a summary of the content of a table</td>
</tr>
<tr>
<td>width</td>
<td>pixels, %</td>
<td>Not supported in HTML5. Specifies the width of a table</td>
</tr>
</tbody>
</table>
</div>
</div>
https://jsfiddle.net/byB9d/6212/
Thanks in advance to anyone with suggestions!
P.S. I would like a pure css solution, please!
I decided to remove most of your css to (hopefully) give a clearer answer to this question. I did however not change any of your html.
Fiddle with code
x-scrolling and width
This method relies on using the "table" as a container for "thead" and "tbody". "table" will determine the scrolling along the x-axis. Therefore it has "overflow-x: auto". This way the "thead" can stay positioned above the "tbody" while scrolling the table. (will be explained later)
This element also determines the width the table will take up on your webpage.
In order for the content to scroll horizontally we have to make sure the total width of "tbody" and "thead" is longer than the width of "table".
Finally you should also add the same width to your cells so the headers appear properly above your data. I did this by applying a width to "tr th:nth-child(1), tr td:nth-child(1)" (for each column).
y-scrolling and height
We want the "thead" to stay positioned on top of our table. Even when we scroll. Therefore we simply convert it to a block element.
The "tbody" is another story. we want to be able to vertically scroll it. Therefore we add "overflow-y: auto" and also set a fixed height for the element (otherwise it will just drop down and not scroll).
The total height of the table will be the height of "thead" and "tbody". The "table will adapt its size to fit it."
The CSS (html is the same as it is in the question post)
td, th {
border-bottom:1px solid #eee;
background: #ddd;
color: #000;
padding: 10px 25px;
}
th div{display: none;} /*why is this html even here!?!?*/
table {
display: block;
position: relative;
border: 1px solid #000;
width: 75%;
border-spacing: 0;
margin: auto;
overflow-x: auto;
}
thead{
display: block;
position: relative;
width: 700px; /*total width of columns*/
}
tbody{
display: block;
position: relative;
height: 250px;
overflow-y: auto;
width: 700px; /*total width of columns.*/
}
tr th:nth-child(1), tr td:nth-child(1){
width: 100px;
}
tr th:nth-child(2), tr td:nth-child(2){
width: 150px;
}
tr th:nth-child(3), tr td:nth-child(3){
width: 450px;
}
PS: I assume this is what you were trying to ask.

Categories