I'm trying to create a table where each cell has additional description that is displayed underneath it on hover.
I want to display the description directly under the cell only when hovered.
The description should be left aligned with the cell unless it extends beyond the bounds of the table at which point it should become right aligned with the end of the table.
I have been able to make things left aligned however I have failed to find a way to ensure the description doesn't extend beyond the end.
The Code (https://jsfiddle.net/9en4v2as/3/):
.description {
display: none;
}
table {
position: relative;
}
td:hover .description {
display: block;
position: absolute;
white-space: nowrap;
background-color: red;
}
td:last-child:hover .description {
right: 0;
}
<table border=1>
<tr>
<td>
<div class="value">Value1</div>
<div class="description">Description of Value1</div>
</td>
<td>
<div class="value">Value2</div>
<div class="description">Description of Value2</div>
</td>
<td>
<div class="value">Value3</div>
<div class="description">Description of Value3</div>
</td>
<td>
<div class="value">Value4</div>
<div class="description">Unknown description length</div>
</td>
<td>
<div class="value">Value5</div>
<div class="description">Description of Value5</div>
</td>
<td>
<div class="value">Value6</div>
<div class="description">Description of Value6</div>
</td>
</tr>
</table>
With jquery
$(document).ready(function(){
//get width table
var w_table = $("table").width();
var w_description;
$("table td").hover(function(){
//sum width td
var w_td = 0;
//get hover position
var pos = $(this).index();
$("table td").each(function(i){
//sum width td until hover position
w_td = w_td + $(this).width();
if(i==pos)
return false;
});
//get description width
w_description = $(this).find(".description").width();
//if width description+width td > width table
if(w_description+w_td > w_table)
$(this).find(".description").css("right",w_table-w_td-30);
});
});
Test here
Related
I am trying to create a tree with a three elements. Main Element, -> children, -> children.
I got pretty far, I can even collaps entire portions of the table. The problem however is, when I collabs row two.
At first, the table looks like this:
Which is fine. I have three <td> in one row.
However, if I show the second row (clicking on my blue arrow),
this is the result:
So, what happens is that the second <tr> then pushes the elements of the second <td> so much forward, that "SubKategorie_1 DELETE" has enough room to fit before "Hauptkategorie_1" begins, which is in a different table row.
I am pretty sure that all I need is a css attribute.
Ill give you the code shortend:
<table class="mainTable">
#{
var position = 0;
for (int i = 0; i < Model.MainNodes.Count(); i++)
{
string catId = "CatId" + i.ToString();
string classToHideCatId = "classToHideCatId" + i.ToString();
<tr class="mainCatRow">
<td>
<div>
<img src="#Url.Content("~/Content/images/icons/icon-open.png")" id="#catId" class="buttonLayoutMain" />
</div>
</td>
<td>
<div class="mainCat">
#Model.MainNodes[i].name
</div>
<td>
Delete
</td>
</tr>
<!--subcategory-->
<tr class="tr2">
<td>
<div class="#classToHideCatId">
<table class="subTable">
...
</table>
</div>
</td>
</tr>
}
}
</table>
With some basic CSS:
.MainDiv{
padding: 20px;
}
.mainTable{
background-color: green;
}
.mainCat {
font-size: 20px;
}
.mainCatRow{
background-color:orange;
}
.subCat {
margin-left: 40px;
font-size: 18px;
}
.tr2{
background-color:gray;
}
.subsubTable {
margin-left: 80px;
}
Question:
How can I make my table have differnt lenght rows?
I am trying to make a table with drop-down info tabs that appear when you scroll over a term.
My initial approach was to make these info tabs not display with display : none css rule, then
when the user hovers the mouse over the corresponding text, the the info tab appears by altering display property to display: block.
My problem is that I can't figure out how to override the default behavior for the containing/parent element, and the table resizes to fit the newly appeared element, then resizes back to normal when the user scrolls away. I experimented with z-index (setting the td to z-index: 1 and info tab to z-index:2) as well as visibility:hidden -> visibility:visible vs display:none -> display:block, but no luck with either of those. I also tried setting the max height of the td element to 200px, but it seems to grow past that regardless.
Here is the source code for what i have so far:
/* In an attempt to prevent row from expanding automatically */
td {
max-height: 100px;
}
.card-body {
display: none;
border: 2px solid black;
height: 300px;
width: 400px;
z-index: 2;
}
.card-trigger:hover+.card-body {
display: inline-block;
position: relative;
top: 0px;
right: 15px;
}
.card-body:hover {
display: block;
}
.card-body .game-info {
display: none;
}
.card-body .dd-trigger:hover+.game-info {
display: block;
}
<h3>Ratings by som bol</h3>
<p>sort by release date (asc/desc), rating amout, game category, game creator, game console</p>
<input type="text" placeholder="filter by game title, categories, creators, consoles, console makers">
<div>Search hints</div>
<table class="table">
<thead>
<tr>
<th>Game title</th>
<th>your rating</th>
<th>Average rating</th>
<th></th>
</tr>
</thead>
<tbody>
<!-- Row 1 -->
<tr>
<td>
<a class="card-trigger" href="#">Some Videogame</a>
<div class="card-body">
<img src="#" alt="picture of the game in question" />
<h3><a [routerLink]="">Game title</a></h3>
<p>Some stuff happens and you have fun</p>
<span class="dd-trigger">Show more info</span>
<ul class="game-info">
<li>Average Rating: </li>
<li>Average Review Score: </li>
</ul>
</div>
</td>
<td>
your rating : 2
</td>
<td>
average rating : 3
</td>
<td><button>Delete rating</button></td>
</tr>
<!-- Row 2 -->
<tr>
<td>
<a class="card-trigger" href="#">Some Videogame</a>
<div class="card-body">
<img src="#" alt="picture of the game in question" />
<h3><a [routerLink]="">Game title</a></h3>
<p>Some stuff happens and you have fun</p>
<span class="dd-trigger">Show more info</span>
<ul class="game-info">
<li>Average Rating: </li>
<li>Average Review Score: </li>
</ul>
</div>
</td>
<td>
your rating : 2
</td>
<td>
average rating : 3
</td>
<td><button>Delete rating</button></td>
</tr>
<!-- row 3 -->
<tr>
<td>
<a class="card-trigger" href="#">Some Videogame</a>
<div class="card-body">
<img src="#" alt="picture of the game in question" />
<h3><a [routerLink]="">Game title</a></h3>
<p>Some stuff happens and you have fun</p>
<span class="dd-trigger">Show more info</span>
<ul class="game-info">
<li>Average Rating: </li>
<li>Average Review Score: </li>
</ul>
</div>
</td>
<td>
your rating : 2
</td>
<td>
average rating : 3
</td>
<td><button>Delete rating</button></td>
</tr>
</tbody>
</table>
In order to prevent parents from resizing to fit the contained element, you must do three things:
Set parent position to relative
Set child position to absolute (and position in appropriate place using top, bottom, left, right)
Set child element z-index higher than that of parent. We do this to prevent any parent styles from overlapping with child styles. It essentially makes the child element look like it is sitting on top of the parent element.
the html is a trivial example of a table with one row. the css hides the contained child div by default, and sets the display to block when hovering, in addition to default styles and the positioning/z-index mentioned above
table, th, td {
border: 1px solid black;
}
.pop-up {
display: none
}
td {
position: relative;
}
td:hover > .pop-up {
display: block;
}
.pop-up {
width: 500px;
height: 100px;
background: red;
border: 1px solid black;
position: absolute;
left: 50px;
z-index: 1;
}
click here to see full example
want to display the following:
where the "..." button in the first row (Web Project) is completely right-aligned to the red line (with a little padding to it)
where the Input field in the 2nd row (Root Namespace) is filling up the space to the right until the red line (with a little padding to it)
where the 2 buttons in the 3rd row (Connection String) are completely right-aligned to the red line (with a liddle padding to it).
I have tried the following but it does not do it correctly - and it only works with a certain width - If I increase or decrease the width, things are getting ugly:
decreasing the width:
My current HTML looks like this:
<div id = "ProjectSelector" width = 100%>
<table width = "100%" style = "padding-bottom: 10px;">
<tr>
<td style="white-space: nowrap; width: 140px;">Web Project (.csproj)</td>
<td style="width: 99%;" ><input id = "webproj" style="width: 97%"/><button id="webproj_browse">...</button></td>
</tr>
<tr>
<td>Root Namespace</td>
<td style="width: 99%;"><input id = "rootnamespace" style="width: 99%"/></td>
</tr>
<tr>
<td>Connection String</td>
<td style="width: 99%;"><select id = "connectionstring" style = "width: 87%"></select><button id="newConnection">New Connection</button><button id="connstringDelete">Delete</button></td>
</tr>
</table>
</div>
Question: How to format the table and the content of 2nd column to accomplish this properly?
the title of your question describes a typical flex behavior. You may use inside your table a flex container :
.flex {
display: flex;
}
.flex-1 {
flex-grow: 1;
}
<div id="ProjectSelector" width=1 00%>
<table width="100%" style="padding-bottom: 10px;">
<tr>
<td style="white-space: nowrap; width:0;">Web Project (.csproj)</td>
<td>
<div class="flex"><input id="webproj" class="flex-1" /><button id="webproj_browse">...</button></div>
</td>
</tr>
<tr>
<td>Root Namespace</td>
<td>
<div class="flex"><input id="rootnamespace" class="flex-1" /></div>
</td>
</tr>
<tr>
<td>Connection String</td>
<td>
<div class="flex">
<select id="connectionstring" class="flex-1"></select><button id="newConnection">New Connection</button><button id="connstringDelete">Delete</button></div>
</td>
</tr>
</table>
</div>
It can also be build with grid or flex without a table.
For infos & demo , an example mixing grid and flex, i would probably not use this HTML structure H + P at first :
* {
margin: 0;
}
.flex {
display: flex;
}
.flex-1 {
flex-grow: 1;
}
#ProjectSelector {
display: grid;
grid-template-columns: auto 1fr;
grid-gap: 0.25em;
;
}
p {
grid-column: 2;
}
<div id="ProjectSelector">
<h4>Web Project (.csproj)</h4>
<!-- title that matches your structure or else can be plain text -->
<p class="flex"><input id="webproj" class="flex-1" /><button id="webproj_browse">...</button></p>
<h4>Root Namespace</h4>
<p class="flex"><input id="rootnamespace" class="flex-1" /></p>
<h4>Connection String</h4>
<p class="flex">
<select id="connectionstring" class="flex-1"></select><button id="newConnection">New Connection</button><button id="connstringDelete">Delete</button></p>
</div>
<!DOCTYPE html>
<html>
<style>
#media only screen and (max-width: 600px) {
p {
background-color:powderblue;
}
}
.row {
display: flex;
flex-wrap: wrap;
padding: 0 4px;
}
.column {
padding: 0 4px;
flex: 20%;
}
I'm not sure if this is actually doing anything
.onclick{
width: 20px;
height: 20px;
}
</style>
<body>
I want these two onclicks to be next to each other
<table style="width:100%">
<tr>
<p id="demo" onclick="myFunction1()">Click me.</p>
</tr>
</tr>
<p id="funct" onclick="myFunction2()">Click me.</p>
</tr>
</table>
This part details what the functions do
<script>
function myFunction1() {
if (document.getElementById("demo").innerHTML == "Click me."){
document.getElementById("demo").innerHTML = "YOU CLICKED ME!";
}
else{
document.getElementById("demo").innerHTML = "Click me.";
}
}
function myFunction2() {
if (document.getElementById("funct").innerHTML == "Click me."){
document.getElementById("funct").innerHTML = "YOU CLICKED ME!";
}
else{
document.getElementById("funct").innerHTML = "Click me.";
}
}
</script>
</body>
</html>
You see your paragraphs in the different rows because you placed them in different rows of your table.
Just change into
<table style="width:100%">
<tr>
<td>
<p id="demo" onclick="myFunction1()">Click me.</p>
</td>
<td>
<p id="funct" onclick="myFunction2()">Click me.</p>
</td>
</tr>
</table>
and they will be placed in the same row.
In HTML tables:
<tr> tag starts a new row
</tr> tag ends current row
<td> tag starts a new box in current row
</td> tag ends current box in current row
Anyway, though it's not the object of the current question, I suggest you finding a different way than tables for organizing your web page. Take a look to <div>s + CSS.
I've this code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>testPage</title>
<style>
table td {
width: 50%;
}
</style>
</head>
<body>
<div id="titlebar">
<center>
Select option:
<select onchange="onSelect.call(this, event)">
<option value="one">One</option>
<option value="two">Two</option>
</select>
<script>
function onSelect(event) {
switch (this.options[this.selectedIndex].text) {
case "One":
var td = document.getElementById("one");
td.style.borderColor = "red";
td.style.borderWidth = "5px";
td.style.borderStyle = "solid";
td.style.width = "99%";
var td = document.getElementById("two");
td.style.borderColor = "black";
td.style.borderWidth = "1px";
td.style.borderStyle = "solid";
td.style.width = "100%";
break;
case "Two":
var td = document.getElementById("two");
td.style.borderColor = "red";
td.style.borderWidth = "5px";
td.style.borderStyle = "solid";
td.style.width = "99%";
var td = document.getElementById("one");
td.style.borderColor = "black";
td.style.borderWidth = "1px";
td.style.borderStyle = "solid";
td.style.width = "100%";
break;
}
}
</script>
</center>
</div>
<div id="images">
<table width="100%" height="100%" border=1 cellpadding=1>
<!-- first row -->
<tr id="row1">
<td id="xxx">
<div id="xxx_div" style="width:100%;height:370px"></div>
</td>
<td id="yyy">
<div id="one" style="width:100%;height:370px"></div>
</td>
</tr>
<!-- second row -->
<tr id="row2">
<td id="zzz">
<div id="zzz_div" style="width:100%;height:370px"></div>
</td>
<td id="kkk">
<div id="two" style="width:100%;height:370px"></div>
</td>
</tr>
</table>
</div>
<div id="bottom">
Bottom ...
</div>
</body>
</html>
that works fine, but if I rescale my browser page you can see that scrollbars appears (I know, I'm using absolute values for div height and the problem probably is about this, but it's only to show the problem ... ).
I'd like to obtain the same behaviour at this site
http://tools.geofabrik.de/mc/
where you can see that if you rescale the browser scale, no scrollbars appears and the maps (so the tables and its contents ... ), rescale ...
Suggestions / examples?
This is what you're looking for:
html, body {
min-height: 100%;
min-width: 100%;
margin: 0;
padding: 0;
}
table {
width: 100vw;
height: 100vh;
}
td {
width: 50%;
height: 50%;
background: red;
}
<table>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</table>
Of course, you might adapt your table size if you need to add inputs or text outside.
Just consider always occupying a total 100% of the visible area.