Show "show more" dynamically - html

I have created a forum-like page where all messages are as follows (simplified):
<div class="message-wrapper" *ngFor="let node of allNodes">
<div [class]="isExpanded(node.id) ? 'message-content expanded' : 'message-content'">
<div class="content" [innerHtml]="node.comment"></div>
<span (click)="toggleExpand(node.id)" class="showMore">{{ isExpanded(node.id) ? 'Show less' : 'Show more' }}</span>
</div>
</div>
And the css
.message-content {
overflow-y: hidden;
.content {
line-height: 1.5vh;
max-height: 6vh;
overflow-y: hidden;
}
}
.message-content.expanded {
max-height: 10000000vh;
overflow: visible !important;
.content {
overflow: visible;
max-height: 100000000vh;
}
}
And when clicking the 'Show more' and 'Show less' span, the div.content expands as expected.
The problem I'm currently encountering is that I want to show the 'Show more' only when the text is actually overflowing.
I know I can find this out by subtracting the scrollHeight and innerHeight but for this to work, I need to have the correct (unique) nativeElement of the corresponding div.comment in my controller.
So my question:
How can I show the 'Show more' span, when the div.content is overflowing while all Messages on the page have the same classes etc.?
The thing that makes this question unique from existing questions is that I don't have a single element but I have multiple of the same elements (multiple messages) thus needing the unique node element.

Created a workaround where I'd add a dynamic id to all divs and spans. Then I loop through all nodes and check if the text is overflowing. If it is I set hidden=false to the label.
for(let comment of this.allComments) {
//element which contains the comment content
let content = document.getElementById('div'+comment.id);
// if the element height is bigger than the displayed height (with an error margin of 10)
if(content.scrollHeight - content.clientHeight > 10) {
// the corresponding 'show more' label
let label = document.getElementById('label'+comment.id);
label.hidden = false;
}
}

Related

Tooltip gets cut off when a table container has overflow-x auto

I have found a lot of issues related to this one, but not one that matches the exact same problem and I was also not able to resolve my problem with other "related" issues. Below you can see two screenshots, one with overflow-x: auto and one without.
With overflow-x: auto
[[With overflows-x][]1]
Without overflow-x: auto
[[Without overflows-x][]1]
So overflow-x auto is cutting off my tooltip when it overflows vertically. I do not know why it behaves this way, even if I put overflow-y visible on it, it does not work.
Reason I am using overflow-x: auto
I am using overflow-x: auto to make my table responsive on resize. This will give me a scrollbar when the content does not fit. I see that many people use this to make their tables responsive.
Important code parts that I am currently using
HTML
<div key={uniqueKey} className={'table-container'}>
<table>
<thead>
<tr>
<th scope='col'>Id</th>
<th scope='col'>Name</th>
</tr>
</thead>
<tbody>
{someList.map((item, index) => {
return (
<tr key={index}>
<td data-label='Id'>{id}</td>
<td data-label='Name'>{name}</td>
<td data-label='Actions'>
<div className={'actions-container'}>
// EXISTING TOOLTIP COMPONENT HERE, I WILL SHOW THE CSS.
</div>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
CSS
.table-container {
overflow-x: auto;
border-collapse: separate;
table-layout: fixed;
table {
width: 100%;
tr {
height: 40px;
}
td {
height: auto;
}
th {
min-width: 175px;
padding: 8px;
}
}}
CSS Tooltip
.tooltip{
width: 300px;
background-color: black;
color: #fff;
text-align: center;
padding: 5px;
border-radius: 6px;
position: absolute;
z-index: 100;
word-break: normal;
opacity: 0;
visibility: hidden;
transition: opacity 0.5s;
transition-delay: 0.4s;}
Other notes
I can not modify the tooltip too much since it is a existing component within our company, we would have to change it on lots of places. Also it works as expected on other places.
If there is any information missing, just let me know and I will respond as soon as possible.
Any insights are welcome at this point!
We had faced similar issue. The way we solved this is add a support to render the tooltip view in a react portal instead.
You'll need a component change but you don't need to change a lot of existing code.
Add a portal component:
const Portal = (props) => {
const { children, target = document.body } = props;
return ReactDOM.createPortal(children, target);
};
Add a usePortal prop that'll render the view in portal instead. Otherwise the view will be rendered as it is currently.
You'll have a viewDom that renders your tooltip view, use the Portal component:
const { usePortal } = props;
const viewDom = <span> Your view dom </span>;
if (usePortal) {
return (
<Portal>
{ viewDom }
</Portal>
)
}
// otherwise return the default dom without portal
return viewDom;
I’m not sure if this would solve the issue or not, but I noticed that the visibility is set to hidden and that will hide everything that doesn’t fit within that specific div. You might want to try setting that to visible to see if it fixes this cut off issue. I have no idea if that is the fix to this, but I wanted to try and help ha ha.
If your tooltips have a max-height, you can add padding/margin top to the table to clear that height.
So if
.tooltip {
...
max-height: 3em;
}
table {
margin-top: 3em;
}
Haven't tested it but your tr only has 40px height and will cut off the overflow on auto, because your three lines of text will take more than 40px space at all.
You should try to set the tr to position:relative and the tooltip to position:absolute for positioning and forget about the overflow;

How do I get the text next to a checkbox to wrap around?

I have these checkboxes on my website. Formatted as below
<el-row>
<div class="sentbox" align="left" :style="{display: sentence1 === '' ? 'none' : 'block'}">
<el-checkbox v-model="sent1"> {{sentence1}} </el-checkbox>
</div>
</el-row>
CSS for sentbox is just:
.sentbox {
width: 500px;
margin: 10px;
}
But what ends up happening is the sentence might be too long and goes past width of the screen forcing the user to scroll to right to see the entire sentence. As you may see in the picture below, the sentence is cut off and I would have to scroll to the right. What am I doing wrong?
The el-checkbox from Element UI sets a white-space:nowrap style, but you could apply white-space:initial to allow the text to wrap:
.el-checkbox {
white-space: initial;
}
demo

Stop content moving when div is set to visible?

I have a hidden div which get's displayed when a radio button is clicked, However the paragraph beneath it gets pushed down when I make the div visible, is there any way that I can have the paragraph pushed down even when the div is hidden, so that it doesn't move? Here is my code
HTML
<div id="container">Hello</div>
<p>Click the button below to view content</p>
<input type="radio" onclick="displayDiv()">
CSS
#container {
display: none;
color: #fff;
font-size: 30px;
}
Javascript
function displayDiv() {
document.getElementById("container").style.display = "block";
}
Change the property display by visibility; its purpose is to place the div as if it was on the page, but rendering it invisible if you give it a value of "hiden".
See this
CSS:
#container {
visibility: hidden;
}
JavaScript
function displayDiv() {
document.getElementById("container").style.visibility = "visible";
}

Hover parent div; show text in child div. Do not show text when hover child div

Very new to HTML and CSS. I've finally figured out how to hover a div and cause that to show text in another div. But what then happens is when I hover the div where the text appears that too shows the text; which I don't not want.
<div class="leaf5">
<img class="leaf-5-about" src="images/Leaf%205%20about.png" onmouseover="this.src='images/Leaf%205%20about%20hover.png'" onmouseout="this.src='images/Leaf%205%20about.png'">
<div class="cashdup-info">
<h3 class="cashdup-text"><i><span style="font-size: 38px; color: #359869" >CashdUp</span> is a home budgeting tool that allows you to make every cent count. </i></h3>
</div>
</div>
Is there a way to hover the div called "leaf5" and have that show text in another div without the text showing up if I hover the actual div the text is contained in. My CSS is as follows:
.cashdup-text {
font-weight: 100;
font-size: 22px;
display: none;
}
.leaf5:hover .cashdup-text {
display: block;
}
Thanks.
.leaf5:hover .cashdup-text:hover {
visibility: hidden;
}
I wouldn't use display: none here, because an element that has display: none logically can't be in a hover state.
use this way :
Demo
Demo for singlle image only
CSS
div {
display: none;
}
img:hover + div {
display: block;
}
HTML
<img src="image/imh.pmg">
<div>Stuff shown on hover</div>
The issue you are facing is when you apply hover to your leaf5 div it displays the cashdup-text which then increases the area of leaf5 including the text part. That is why when you have text displayed you can't make it disappear. Because you are already hovering it.
You can try absolute position like this way:
CSS:
.cashdup-text {
font-weight: 100;
font-size: 22px;
}
.cashdup-text{
position: absolute;
display: none;
}
.leaf5:hover .cashdup-text {
display: block;
}
Fiddle: https://jsfiddle.net/dqz9j2tj/
The problem is, .cashdup-text is a child of .leaf5 so when you're hovering over .cashdup-text, the browser sees it that you're also hovering over .leaf5 (in a way).
Are you open to using JS? If so, please see below.
var showme = document.getElementById("showme");
showme.style.display = "none";
function display() {
showme.style.display = "block";
}
function hide() {
showme.style.display = "none";
}
<div class="leaf5" onMouseOver="display();" onMouseOut="hide();">
<img class="leaf-5-about" src="images/Leaf%205%20about.png" onmouseover="this.src='images/Leaf%205%20about%20hover.png'" onmouseout="this.src='images/Leaf%205%20about.png'">
</div>
<div class="cashdup-info">
<h3 class="cashdup-text" id="showme"><i><span style="font-size: 38px; color: #359869" >CashdUp</span> is a home budgeting tool that allows you to make every cent count. </i></h3>
</div>
As you can see, I've added an id of "showme" to the h3 element you want to show / hide and have added MouseOver / MouseOut events to the .leaf5 div. I've also separated .leaf5 from the div below, just so it doesn't cause any issues like you described when hovering over .cashdup-text.
Try adding this to your stylesheet:
.leaf5:hover .cashdup-text {
opacity:0;
}
.cashdup-text {
opacity:1;
}

Making invisible text selectable

I am making a source code display which supports line folding. While it's easy enough with CSS to ensure that the replacement text ("N lines hidden") is not selectable, I would like the hidden source code to still be selected, so the user can just select a chunk of code and not worry about whether part of it is missing due to a fold. Is there a (not-too-hacky) way to do this?
Elements with opacity: 0 can be selected, although they're invisible.
.hidden-selectable {
display: inline-block;
width: 1px;
opacity: 0;
}
<div>Visible<span class='hidden-selectable'>selectable</span></div>
In the above snippet, the 'selectable' string will be present in the selection and the copy-pasted text when the elements around it are selected.
The element needs to have a non-zero width and height, otherwise it doesn't appear in the selection. Also, it has to be inside the element flow (i.e. it can't have position: absolute), otherwise, again, it's not going to appear in the selection. Therefore I give it some very small but non-zero width, so that it doesn't affect flow visibly, but is still "visible enough" to be selectable.
Here's the fiddle.
Here's what else I've tried that doesn't work:
display: none
visibility: hidden
If you have the following structure:
<html>
<body>
<div>before</div>
<div class="folded">this is the hidden source code</div>
<div class="info">N lines hidden</div>
<div>after</div>
</body>
</html>
You should be good with this CSS:
.folded {
overflow: hidden;
height: 0px;
}
.info {
-moz-user-select: none;
//add other browsers' variation
}
EDIT: another option (untested in Chrome)
HTML:
<html>
<body>
<div>before</div>
<div class="folded">this is the hidden source code</div>
<div class="info" data-lines='5'> </div>
<div>after</div>
</body>
</html>
CSS:
.folded {
overflow: hidden;
height: 0px;
}
.info:before {
content: attr(data-lines) " lines hidden."
}