I have a span inside another span. I would like to allow the user to be able to select the text from the parent span, but not the child one.
Note: user-select (family) does not work. It prevent the selection to start or end in this area, but the text is still in the end clipboard result if I surround it with the select in the text from the parent span.
For example:
<head>
<style>
.hole-hint {
display: inline-block;
position: absolute;
bottom: 45%;
font-size: 12px;
color:rgb(255, 0, 0);
background-color:rgba(255, 225, 225, 0.5);
z-index:1;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
.hole {
padding-top: 7px;
position: relative;
background-color:#EEEEEE;
}
</style>
</head>
<body>
<span> this is the parent text<span class="hole"><span class="hole-hint">no copy</span></span>and this is text on the other side </span>
</body>
</html>
I had a similar need, I used place holders for text that wasn't entered yet. However if the user wanted to copy that block of text they would never want the place holders in the copied text. I came up with the following solution.
Here is an example, it uses some jquery but that could be replaced
CSS (not really needed just for fun)
div.copying { background-color: yellow; }
div.copying .nocopy { display: none; }
HTML (Note: if you wanted to apply to the entire page, move oncopy to )
<body>
<div>text not related to the copy, dont select this</div>
<div oncopy="handleHideCopy(this);" class="container">
<span>the text between ><span class="nocopy"> I don't want this text copied </span><span>< will be excluded from copy, or at least in IE</span>
</div>
<div>and don't select this either</div>
</body>
JS
function handleHideCopy(el)
{
$(el).addClass('copying');
var innerHtml = el.innerHTML;
$(el).find('.nocopy').remove();
setTimeout(function(){
$(el).removeClass('copying');
$(el).children().remove();
el.innerHTML = innerHtml;
},300);
}
The reason why this works is because oncopy is called on the parent element before the copy takes place, and the content that must be hidden has to actually be removed, as display:none does absolutely nothing for copy.
Instead of using innerHTML for large amounts of html a more targeted DOM remove/insert should be used to remove the content and put it back where it belongs. I don't have an example handy for that.
Related
Is there any possibility how to target HTML tag <title> in CSS for content: ""?
It would be pretty neat to control both the <h1> and the title of the page by one attribute.
I've tried something like
title::before{
content: "Hello world"
}
If this won't be possible, what other solution might be appropriate?
Thanks!
You sure can, in fact, as all elements in a HTML document are plain <tags> they can be made visible and get id, class, style (inline or style block) or any other selector attribute, whether global or custom. Even contenteditable and make them runtime editable (won't work on <script>, though).
Below a snippet displaying <title> with pseudo selectors.
...And if you really want to dig into showing runtime styles, links and javascript check out this Codepen I created some time ago. Beware, not for beginners. Hit the bottom/right [show styles] button in the pen and see the magic happen...
<html>
<head>
<title>Document Title, quite long some we can forse a line break (well, on smaller windows anyway...)</title>
<style>
/* Because it is hidden by default */
head {
display: block;
}
title {
display: block; /* default hidden too */
width: 100%;
min-height : 2rem;
line-height: 2rem;
hyphens: auto;
cursor: pointer; overflow: hidden;
font-size: larger; text-align: center;
background-color: hsl(45,100%,50%);
}
title::before { content: 'Before: ' ; font-weight: bold }
title::after { content: ' :The End!'; font-weight: bold }
body { background-color: Gainsboro }
</style>
</head>
<body>
<p>Some regular paragraph element</p>
</body>
</html>
I'd like to have links zoom in when the mouse hovers on them, I've tried with transform unsuccessfully, but then I found this answer, which looked promising.
However, making an inline element an inline-block also seems to prevent it from being split across several lines, as shown in the snippet below, which can create very unpleasant results for short width of the enclosing box.
div {
border: 1px solid black;
text-align: justify;
width: 20em;
}
a {
text-decoration: none;
display: inline-block;
}
a:hover {
transform: scale(1.01);
}
<div>
<p>Today, <a href="https://github.com/Aster89/WinZoZ">my
Vim plugin for easy window navigation</a>, which I named
WinZoZ,
has got its first star! Given <a
href="https://stackoverflow.com/questions/69007954/vim-remap-ctrl-w-in-insert-mode-to-behave-as-it-does-in-normal-mode#comment121984179_69007954">this
comment on StackOverflow</a>, the star is from the user #yolenoyer.
</p>
</div>
On the other hand, in this specific example above I see that the first link is so long that it does split across lines, so it looks like inline-block elements can indeed do that. How can allow it when they are shorter than the text width?
The animation missing is due to the original link (a tag) element not having the transition: property defined. Per the positioning documentation here it seems only inline-block is suitable for flowing text and that fails to show wrapped text, even with wrap: break-word; present. The inline-flex, inline-grid don't work either since they are both block display types.
One solution would be to break the text lines at certain points and setting different <br> elements to show at different #media widths for certain page widths/devices. However the inline-block elements cannot wrap like normal text, so the breaks just end up making it a 2-line block in the middle of the text.
div {
border: 1px solid black;
/* text-align: justify; */
width: 20em;
}
a {
text-decoration: none;
/* new */
transition: transform .15s; /* Animations: "transform" on a-tag must be present */
display: inline-block;
}
a:hover {
transform: scale(1.01); /* then we transform the transition here */
-ms-transform: scale(1.01); /* IE 9 */
-webkit-transform: scale(1.01); /* Safari 3-8 */
}
<div>
<p>Today, <a href="https://github.com/Aster89/WinZoZ">my
Vim plugin for easy window navigation</a>, which I named
WinZoZ,
has got its first star! Given <a
href="https://stackoverflow.com/questions/69007954/vim-remap-ctrl-w-in-insert-mode-to-behave-as-it-does-in-normal-mode#comment121984179_69007954">this
comment on StackOverflow</a>, the star is from the user #yolenoyer.
</p>
</div>
Some JS scripting
A breaking up of the line into blocks in a ul list with the li items being inline-block themselves could be a solution. A function to run at DOM load on each desired div's contents could do this. A loop for all a elements in those divs that transform each of the links into an array of words and puts the array items in a ul -> li. Perhaps there is a jQuery plugin for this already.
Light JS example
(not complete code, but using querySelectorAll, which could be used to gather the links from a <div> with a class you put as the function input):
<script type="text/javascript">
// function to look for a-tags in a DIV with a specific class
function linkToList(inputDivClass) {
// get the links inside the div with the input div class
const allLinks = document.querySelectorAll("div." + inputDivClass + " > a");
for (var i = allLinks.length; i < 0; i++) {
// here we go through the links returned from the div...
}
// then go through the data and see what to put where...
}
// when dom is loaded we run the function that looks for the divs with the a-tags...
document.addEventListener("DOMContentLoaded", linkToList(inputDivClass) );
</script>
I'm building some sort of framework where the content of the page can be edited with ContentTools. A requirement of ContentTools is that the regions must be parents.
If you try this:
<h1 data-editable data-name="heading">Content</h1>
It wont work as a region has to contain editable block level elements. A way around this is to wrap the tag like so:
<div data-editable data-name="heading">
<h1>Content</h1>
</div>
But I just want to make the text editable, so I automatically wrapped the inner elements in a div. This works but it affects the styles.
Is there a way to make a div 'transparent', so it will inherit all styles?
I tried the following code.
To be clear: In this example I don't write the h1 css, so i have no influence over which styles are used.
$("[data-editable]").wrapInner("<div class='innerWrap'></div>");
/* example h1 css, could be anything */
body > h1{
font-size: 40px;
color: red;
font-family: sans-serif;
border: 3px solid green;
background-color: blue;
padding: 5px;
}
.innerWrap{
all: inherit;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 data-editable data-name="heading">Content</h1>
As you can see some things work. But things like a border will double.
It has to be no difference with or without the innerWrap.
Is it possible to do this with css? It has to work on every css property.
I think you need to wrap the h1 with a div not div with h1.
for eg. .wrapInner() will produce something like
<h1 data-editable="" data-name="heading">
<div class="innerWrap">Content</div>
</h1>
But what you want is
<div data-editable data-name="heading">
<h1>Content</h1>
</div>
So please try with .wrap() instead of .wrapInner()
$("[data-editable]").wrap("<div class='innerWrap'></div>");
h1{
font-size: 40px;
color: red;
font-family: sans-serif;
border: 3px solid green;
background-color: blue;
padding: 5px;
}
.innerWrap{
all: inherit;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 data-editable data-name="heading">Content</h1>
.innerWrap{
all: inherit; /* remove it*/
}
As a default behaviour, if you not specify css props for ".innerWrap" it will look same as parent only
The ability to make an individual element editable standalone as opposed to as part of a collection (e.g in a region) is currently being worked on: https://github.com/GetmeUK/ContentTools/issues/79
There is however a short-term imperfect approach you could try, first change you're HTML as follows:
<h1 data-editable data-name="heading">
<span data-inline data-ce-tag="h1">Content</span>
</h1>
This will make the h1 tag the region and tell ContentTools/Edit to treat the inner span element as a h1 (text) element (thanks to the data-ce-tag).
But the next problem is that if the user hit's return you'll end up with a new paragraph tag inside of your h1 - which we don't want. This is where the data-inline attribute comes in, we need to listen for mount events and if the element mounted has the data-inline attribute we'll modify its behaviour so it can't do certain things which might produce undesirable events:
ContentEdit.Root.get().bind('mount', function(elem) {
// We're only interested in elements that are marked as inline
if (elem.attr('data-inline') === undefined) {
return;
}
// Change the default behaviour of the element
elem.can('drag', false);
elem.can('drop', false);
elem.can('remove', false);
elem.can('spawn', false);
});
You can find out more about modifying behaviours here, along with their current limitations here.
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;
}
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."
}