How to offset dataObject from referenceObject using popper.js? - popper.js

How do I offset the boat from the anchor by a few pixels?
You can find a code pen where I have unsuccessfully tried to set an offset here
https://codepen.io/anon/pen/wXraLK?editors=1111
HTML
<script src="https://unpkg.com/popper.js/dist/umd/popper.min.js"></script>
<div class="anchor">Anchor</div>
<div class="boat">Boat</div>
CSS
.boat {
display: inline-block;
background-color: yellow;
}
.anchor {
display: inline-block;
background-color: gray;
}
JavaScript
var anchor = document.getElementsByClassName("anchor")[0];
var boat = document.getElementsByClassName("boat")[0];
var offsetTopModifier = function (data) {
data.offsets.popper.top += 50;
return data;
}
var popper = new Popper(
anchor,
boat,
{
placement: 'bottom-end',
modifiers: [offsetTopModifier]
}
);
This was the source that inspired my attempt:
https://github.com/FezVrasta/popper.js/issues/107

One work around was to set margins on the boat.

Related

How to create an add-able dropdown using html similar to what we use in the jira while adding the component?

I am trying to create an add-able dropdown using HTML similar to what we use in the Jira while adding the component/s. Any help would be appreciated. Thanks.
Example:
This needs some styling and you will need to change the way some of the elements are selected but this is the basic JavaScript concept:
const dropdownOptions = [
"qwert",
"scdfvgbh",
"cdrdh",
"sdsrg",
"sgfbrynhybgdfv",
"847ht4r"
];
//selects the div
const container = document.getElementsByTagName("div")[0];
//creates elements
dropdownOptions.forEach(name => {
const element = document.createElement("p");
element.innerHTML = name;
container.appendChild(element);
});
//selects the input
const input = document.getElementsByTagName("input")[0];
input.addEventListener("keyup", function() {
//selects every element in the div
const elements = container.children;
//loop through dropdown options
for (let i = 0, l = elements.length; i < l; i++) {
//checks if the value of the input is contained in the dropdown option
if (elements[i].innerHTML.includes(input.value)) {
elements[i].style.display = "block";
} else {
elements[i].style.display = "none";
}
}
});
input {
width: 150px;
}
div {
width: 156px;
border: 1px solid #000000;
}
div>p {
position: relative;
}
<!DOCTYPE html>
<html>
<body>
<input type="text" />
<div>
</div>
</body>
</html>

How can I slide out a line on the left and right side of text on mouse hover

Essentially, I'm looking to animate a line on the left and right side of text that will increase its width to the end of the display when I hover over the text.
Perhaps this will help...
without hovering:
SOME TEXT
on hover:
----------------------------SOME TEXT--------------------------------------------------------------------------------------
I'd like these lines to animate outward to the end on the parent. I've tried using the pseudo elements but had no luck. Some help would be greatly appreciated.
Here's how I'd do it. Feel free to play with animation duration and timing function:
.separator {
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
.separator:before, .separator:after {
content: '';
flex-grow:0;
height: 1px;
background-color: currentColor;
transition: flex-grow .6s cubic-bezier(.4,0,.2,1);
margin: 0 .5rem;
}
.separator:hover:before, .separator:hover:after {
flex-grow: 1;
}
<div class="separator">SOME TEXT</div>
<div style="width: 50%; margin-top: 60px;border: 1px solid red; color: blue; padding: 3rem 0;">
<div class="separator">TEST</div>
Here's a JavaScript solution. Adds - to either side until it reaches the end of the line, and it removes the dashes when the mouse moves away.
To prevent the overflow, you just have to track the clientHeight and stop adding dashes as soon as the height increases.
var div = document.getElementsByClassName('test')[0];
var origText = div.innerText;
var origHeight = div.clientHeight;
var tooLong = false;
var addTxtInt;
div.addEventListener('mouseover', function() {
addTxtInt = setInterval(function() {
if (tooLong)
return;
if (div.clientHeight > origHeight) {
div.innerText = div.innerText.substring(1, div.innerText.length - 1);
tooLong = true;
return;
}
div.innerText = "-" + div.innerText + "-";
if (div.clientHeight > origHeight) {
div.innerText = div.innerText.substring(1, div.innerText.length - 1);
tooLong = true;
return;
}
}, 80);
});
div.addEventListener('mouseleave', function() {
clearInterval(addTxtInt);
div.innerText = origText;
tooLong = false;
});
.test {
display: block;
overflow: hidden;
text-align: center;
}
<div class='test'>SOME TEXT</div>

Hover not working with text below image in anchor tag html

I have this code for making a nav bar. I am trying to add image buttons with text below them. The problem is that the images can be of different sizes and thus they are not centered properly in the output.
Also, the title for all images must come at same level but its not the case.
ul.nav-icon {
list-style: none;
display: block;
margin: auto;
width: 800px;
}
ul.nav-icon li {
float: left;
}
ul.nav-icon a {
display: inline-block;
text-decoration: none;
}
ul.nav-icon a:hover {
background: #4095A6;
}
ul.nav-icon img {
margin: 0px 0px 0px 0px;
padding-top: 16px;
padding-left: 30px;
}
.img-box {
width: 160px;
height: 138px;
}
h6 {
color: white;
text-align: center;
}
<ul class="nav-icon">
<li>
<a href="#" class="img-box">
<img src="http://imgur.com/Et4vXHk.png">
<h6>Families</h6>
</a>
</li>
<li>
<a href="#" class="img-box">
<img src="http://i.imgur.com/lubEbTP.png">
<h6>Families</h6>
</a>
</li>
<li>
<a href="#" class="img-box">
<img src="http://i.imgur.com/lubEbTP.png">
<h6>Families</h6>
</a>
</li>
</ul>
Here's a way to deal with your problem: https://github.com/smohadjer/sameHeight
Here's the .js file you'll need to include in your html. It's better if it's an external file. For any confusion, this file can also be found in the link above with both minified/unminified versions.
;(function ($, window, document, undefined) {
'use strict';
var pluginName = 'sameHeight',
defaults = {
oneHeightForAll: false,
useCSSHeight: false
};
//private method
var getHeightOfTallest = function(elms) {
var height = 0;
$.each(elms, function() {
var _h = $(this).outerHeight();
if (_h > height) {
height = _h;
}
});
return height;
};
// The actual plugin constructor
function Plugin(element, options) {
this.$element = $(element);
this.options = $.extend({}, defaults, options);
this.init();
}
// methods
var methods = {
init: function() {
var self = this;
self.index = 0;
self.$elms = self.$element.children();
self.cssProperty = self.options.useCSSHeight ? 'height' : 'min-height';
$(window).on('resize.' + pluginName, function() {
//remove previously set height or min-height
self.$elms.css(self.cssProperty, '');
initSameHeight();
});
//use setTimeout to make sure any code in stack is executed before
//calculating height
setTimeout(function() {
initSameHeight();
}, 0);
function initSameHeight() {
//if there are adjacent elements
if (self.getRow(0).length > 1) {
self.setMinHeight(0);
if (self.options.callback) {
self.options.callback();
}
}
}
},
setMinHeight: function(index){
var self = this;
var row = self.options.oneHeightForAll ? self.$elms : self.getRow(index);
var height = getHeightOfTallest(row);
$.each(row, function() {
$(this).css(self.cssProperty, height);
});
if (!self.options.oneHeightForAll && self.index < self.$elms.length - 1) {
self.setMinHeight(self.index);
}
},
getRow: function(index) {
var self = this;
var row = [];
var $first = self.$elms.eq(index);
var top = $first.position().top;
row.push($first);
self.$elms.slice(index + 1).each(function() {
var $elm = $(this);
if ($elm.position().top === top) {
row.push($elm);
self.index = $elm.index();
} else {
self.index = $elm.index();
return false;
}
});
return row;
},
destroy: function() {
var self = this;
//remove event handlers
$(window).off('resize.' + pluginName);
//remove dom changes
self.$elms.css(self.cssProperty, '');
self.$element.removeData('plugin_' + pluginName);
}
};
// build
$.extend(Plugin.prototype, methods);
// A really lightweight plugin wrapper around the constructor,
// preventing against multiple instantiations
$.fn[pluginName] = function(options) {
this.each(function() {
if(!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName, new Plugin(this, options));
}
});
return this;
};
})(jQuery, window, document);
After you include the above .js file, add this script to your current page:
$('.img-box').sameHeight();
This should make all of your boxes with image/text be the same size height wise.
Next in order to make sure the text is always at a certain point within your img-box, add some css inline, or make a class with the css as
h6 {
bottom:10px;
}
The amount of pixels can be anything you'd like it to be. To explain, the text will now always be 10 pixels from the bottom of the img-box.
Either this, or just make the images the background image for the container and set them all to predetermined sizes.

Truncate opposite end of string inside html table

Is there a css / html way of truncating the from the start of a string? Showing the end characters instead?
For example:
string = "A0000000982091011328885"
truncated (show start) = "A000000098..."
truncated (show end) = "...1011328885"
I've tried changing the text direction but apart from that I'm out of ideas. I am completely capable of doing this in Javascript however it'd be nice not to.
I'm also doing this within a table td, so if there is some weird table specific <element> that'd be satisfactory.
Here is a "reverse ellipsis" pen made by Roman Komarov which does exactly what you want using just pure CSS. It just requires a specific HTML markup in order to work.
<div class="box ellipsis reverse-ellipsis">
<div class="ellipsis__content">Here is some long content that doesn't fit.</div>
</div>
It also uses pseudo-elements as the ellipsis and positioned them at the start of the text.
.reverse-ellipsis::after {
content: "…";
float: left;
width: 1em;
padding: 0 1px 0 1em;
margin: -1.35em -1em;
background: #FFF;
}
var rows = document.getElementById('container').childNodes;
for (var i=0, row; row = rows[i]; i++) {
trimLeft(row);
}
function trimLeft(row){
var trimContents = function(row, node){
while (row.scrollWidth > row.offsetWidth) {
var childNode = node.firstChild;
if (!childNode)
return true;
if (childNode.nodeType == document.TEXT_NODE){
trimText(row, node, childNode);
}
else {
var empty = trimContents(row, childNode);
if (empty){
node.removeChild(childNode);
}
}
}
}
var trimText = function(row, node, textNode){
var value = '...' + textNode.nodeValue;
do {
value = '...' + value.substr(4);
textNode.nodeValue = value;
if (value == '...'){
node.removeChild(textNode);
return;
}
}
while (row.scrollWidth > row.offsetWidth);
}
trimContents(row, row);
}
#container {
width: 200px;
border: 1px solid blue;
}
#container div {
width: 100%;
overflow: hidden;
white-space: nowrap;
}
<div id="container" >
<div>A00000009sfsgsdfggdsf1011328885</div>
</div>

Dynamic height auto-resize with css

As I can have a div with two children inside, one of which is not shown (display: none) and the other occupies the entire space of the father, but when I tell javascript to display the hidden the other autoredimensiones to space left without using javascript?
html:
<div class="parent">
<div class="child1" id="id1">
</div>
<div class="child2">
</div>
</div>
css:
.parent {
height: 200px;
background-color: red;
}
.child2 {
height: 100%;
background-color: blue;
}
.child1 {
display:none;
height: 50px;
background-color: green;
}
javascript:
var myDiv = document.getElementById('id1');
myDiv.style.display="block";
This can't be achieved with pure CSS, but if you're okay about adding a little more JavaScript (in order to add a class-name), then it can be achieved:
Amended JavaScript:
var myDiv = document.getElementById('id1');
myDiv.style.display = "block";
myDiv.className += ' nowShown';
Appended CSS:
.child1.nowShown {
float: left;
width: 50%;
}
.child1.nowShown + .child2​ {
display: inline-block;
width: 50%;
}​
JS Fiddle proof-of-concept.
Otherwise it's not possible, simply because CSS lacks the capacity to determine the visual/display state of an element. If it had a :visible pseudo-class then it'd be possible, but without such, as currently, it's sadly not.
Adapted the above proof-of-concept to implement a slightly less-than-concise toggle:
function showDiv1() {
var myDiv = document.getElementById('id1'),
cN = myDiv.className;
myDiv.style.display = "block";
if (cN.match(/nowShown/)){
myDiv.className = cN.replace(/nowShown/,'');
myDiv.style.display = 'none';
}
else {
myDiv.className += ' nowShown';
}
nC = myDiv.className;
myDiv.className = nC.replace(/\s{2,}/,' ');
}
document.getElementsByTagName('button')[0].onclick = function(){
showDiv1();
};​
JS Fiddle demo.