Consider the following HTML:
<p>This is a potentially large paragraph of text, which <span>may get
wrapped onto several lines when displayed in the browser.
I would like to be able to draw a minimal</span> box round the span</p>
I would like to draw a minimal border round the span.
That is:
If the span is rendered on a single line, the border is equivalent to setting a CSS style of border: 1px solid black;
If the span is rendered on multiple lines, the border is drawn around the outermost edges of the span, not between the lines which it crosses. This is equivalent to setting a CSS background color on the span, and drawing the line around the edges of the highlighted area.
I am fairly confident this cannot be done with raw CSS alone (in the second case). Solutions involving javascript libraries, or those which are Firefox-specific, are acceptable.
This is a mock-up of how the second scenario should look:
Consider adding an outline, not border http://jsfiddle.net/tarabyte/z9THQ/
span {
outline: 2px solid black;
}
Firefox draws outline between lines. There is a workarond: http://jsfiddle.net/z9THQ/2/
.wrapped {
outline: 2px solid black;
}
.wrapped span {
border: 1px solid white;
background-color: white;
position: relative;
z-index: 1000;
}
<p>
This is a potentially large paragraph of text, which
<span class="wrapped"><span>
may get wrapped onto several lines when displayed in the browser. I would like to be able to draw a minimal
</span></span>
box round the span
</p>
Related
I was trying to complete a simple task on Javascript.info and I'm getting my ass beaten by an "a" tag. The task is to simply place (and remove) a tooltip above the element on hover and I have no problem with the roof or the house, but when I try to place the box above the link, it breaks and I can't solve it for my life.
I'm asking for help here because the solution on the site uses position:fixed while I'm trying to use position:absolute and simply mimicking the solution won't help me learning anything. The problem is all on line 77 and 78, when I try to assign tooltip.style.left and tooltip.style.top.
If I try to assign it usign a literal (for example, "-58px"), it works. Otherwise, it just defaults to whatever value the tooltip on "house" would have. I tried to see what is going on with some tactical alerts and it drove me insane. It shows me that if I use a computed value, it defaults and if I use a literal, it will work normally.
I'd like someone to explain what is going on and possibly some insight (pointing out if I got wrong how position:absolute works, how element size properties works or something on this nature)
The code (I only made the part that is inside of the script tag on line 64, the rest is from the authors of the task):
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<style>
body {
height: 2000px;
/* the tooltip should work after page scroll too */
}
.tooltip {
position: fixed;
z-index: 100;
padding: 10px 20px;
border: 1px solid #b3c9ce;
border-radius: 4px;
text-align: center;
font: italic 14px/1.3 sans-serif;
color: #333;
background: #fff;
box-shadow: 3px 3px 3px rgba(0, 0, 0, .3);
}
#house {
margin-top: 50px;
width: 400px;
border: 1px solid brown;
}
#roof {
width: 0;
height: 0;
border-left: 200px solid transparent;
border-right: 200px solid transparent;
border-bottom: 20px solid brown;
margin-top: -20px;
}
p {
text-align: justify;
margin: 10px 3px;
}
</style>
</head>
<body>
<div data-tooltip="Here is the house interior" id="house">
<div data-tooltip="Here is the roof" id="roof"></div>
<p>Once upon a time there was a mother pig who had three little pigs.</p>
<p>The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you."</p>
<p>The three little pigs set off. "We will take care that the wolf does not catch us," they said.</p>
<p>Soon they met a man. Hover over me</p>
</div>
<script>
house.onmouseover= function(event){
let target= event.target.closest('[data-tooltip]');
let tooltip= document.createElement('div');
tooltip.textContent= target.dataset.tooltip;
tooltip.classList.add("tooltip");
target.append(tooltip);
if(!tooltip.parentElement.style.position){
tooltip.parentElement.style.position= 'relative';
}
tooltip.style.position= 'absolute';
tooltip.style.top= "-"+(tooltip.offsetHeight+5)+"px";
tooltip.style.left= -target.clientLeft+(target.offsetWidth-tooltip.offsetWidth)/2+"px";
//alert("-"+(tooltip.offsetHeight+5)+"px");
//alert(tooltip.style.top);
}
house.onmouseout= function(event){
let target= event.target.closest('[data-tooltip]');
tooltips= target.querySelectorAll('.tooltip');
for(tooltip of tooltips){
tooltip.remove();
}
}
</script>
</body>
</html>
Thanks already :)
when I try to place the box above the link, it breaks
This is because the tooltip box is positioned to appear under the mouse. Hovering over the link generates a regenerative feedback loop of
Create and append the tooltip element to the <a> element
The mouse is over the tooltip element
Fire mouseout on the a element in preparation of firing mouseover on the tooltip.
mouseout handling removes the tooltip element
The mouse is now over the a element,
Fire mouseover on the a element and repeat from step 1.
The roof and interior mouseover events don't trigger the loop because the tooltip box is outside the target element with the data-tooltip attribute.
You could try
Moving the tooltip box so it cannot appear under the mouse, or
Think of creative ways of using mousenter and mouseleave events on the anchor element that don't fire when hovering over the tooltip because it is a child of the anchor element, or
Turn off pointer events from tooltip elements:
.tooltip {
pointer-events: none;
}
Additional listeners used to verify the problem:
house.addEventListener("mouseover", e=>console.log("over"));
house.addEventListener("mouseout", e=>console.log("out"));
The additional delay caused by console.log did result in the tooltip box being rendered and becoming visible in Firefox, but the log output definitely confirms the feed back loop in action.
I am making a window where the components need to scale according to the height of the window, as the user resizes it.
To this end, I have some JS to update the css style of the components whenever the window changes size.
For one of the components, I want the text inside it to be centered, but for some font sizes, the text is placed too high up:
Bad vertical alignment example
I scaled up this example to make it more clear. There are 1px of space above the text, and 3px below.
I have tried
setting lineHeight = height, and vertical align center
setting display flex, align-items center, and wrapping the text in a child div/span.
setting lineHeight = 1, and appropriate padding top/bottom (same values)
In all situations above, I also set height and font-size to a value that matches the current window height. I also tried avoiding fractional font sizes, by having the font size rounded to the nearest integer.
It all works in most situations, but there are always some window sizes where the alignment messes up. Particularly for smaller window sizes.
The html consists of a display flex div with button elements, each containing the text to be centered.
Edit 1:
I reproduced it in this fiddle: https://jsfiddle.net/Lz7p2joy/6/
<div class="strip">
<button>SBO</button>
<button>PIN</button>
<button>ISN</button>
</div>
.strip{
display: flex;
float: left;
margin-left: 5px;
border-radius: 5px;
border: 1px solid #3F3F46;
overflow: hidden;
}
button{
font-size: 8px;
line-height: 10px;
height: 10px;
padding: 0px 3.8452px;
text-align: center;
background-color: #007ACC;
color: #F1F1F1;
border: none;
border-right: 1px solid #3F3F46;
border-radius: 0;
}
It is subtle, but there are 3 px of space below the text, and 1px above. This might depend a bit on the computer/monitor/browser it is run on. I have seen some worse examples on users' machines (Might be related to windows display scaling).
I'm trying to use this npm package, react-selectable-fast (See the demo to get a better understanding of what I am talking about). When a user selects something, there is the dotted lined box which shows where on the screen you've drawn the selection-box.
In the example code, they seem to give their selection box an outline like so:
.selectable-selectbox {
z-index: 9000;
position: absolute;
cursor: default;
background: none;
border: 1px dashed grey;
}
I have copied their stylesheet to have the same kind of selection box outline. But it doesn't start at the right point. My selection box is drawn way higher. What might be the reason? Is there anything in the React/JS code I need to consider?
How do you get a nice outline? This is similar to the question:
CSS/Javascript: How to draw minimal border around an inline element?
However, the accepted solution to that question results in jagged textboxes, as seen here:
http://jsfiddle.net/z9THQ/2/
/* p {
text-align: justify;
} */
.wrapped {
outline: 2px solid black;
box-shadow: 0px 0px 0px 2px rgba(0,0,0,1);
}
.wrapped span {
border: 1px solid white;
background-color: white;
position: relative;
z-index: 1000;
}
Even with justified text, the right edge is still jagged; it should look like a single line, like in the image below.
A pure CSS solution would be ideal, but if Javascript is necessary, that would be fine too.
A related symptom which a solution would ideally solve is the fact that the :hover attribute is not activated by the region in between two lines of text. Ideally, the whole section should feel like a text-area, only it is non-rectangular since it is inline with other text.
a outline box as below is needed:
The HTML code is:
<p>We <span>prefer questions that can be answered, not</span> just discussed.</p>
It is difficult to get the coordinate of the left-top point and right-bottom point of the outline box.
using:
outline: 2px red solid;
can only work in chrome, but failed in firefox. And also failed in chrome while the line-height of <p> is 300%.
Like so:
CSS:
p {
width: 220px;
}
span {
outline: 2px red solid;
}
So you have the span around what you want, just put outline on it and done. Pretty simple uh? :D
DEMO HERE
Note: As pointed out in the comments, this doesn't seem to work in Firefox. Looking into a solution now.
If you know how to use CSS3, use it. Else, please insert the following within your html page.
<style type="text/css">
span {
border: 5px solid red;
}
</style>