I'm trying right to left direction in my HTML as it will be useful for languages like arabic,hebrew
The problem which i face is border-right is not changing it's retained in the same place when shifted to RTL. According to my understanding i thought border-right will be changed as border-left when i switch to RTL mode.
What does RTL property really does?. It just shifts only the content.
If so i can do the workaround by changing the border-right to left in case of RTL. But before doing that i just to want understand what the RTL really does. Please throw some light on it
var rtl = document.getElementById('RTL');
var content = document.getElementById('content');
var currentState;
rtl.onclick = implementRTL;
function implementRTL() {
currentState = content.getAttribute('dir');
if (currentState == 'ltr') {
content.setAttribute('dir', 'rtl');
} else {
content.setAttribute('dir', 'ltr');
}
}
div {
border: 10px solid #000;
border-right: 10px solid red
}
<div id="content" dir="ltr">
Hi Here is the content
</div>
<button id="RTL">
RTL SWITCH
</button>
Check the code below which i tried
border-inline-end
This property sets the right border when the text is LTR and the left border in case of RTL. Similarly, there is border-inline-start for the border on the other side, and border-block-start and border-block-end for the top and bottom borders. They apply correctly to vertical text as well.
var rtl = document.getElementById('RTL');
var content = document.getElementById('content');
var currentState;
rtl.onclick = implementRTL;
function implementRTL() {
currentState = content.getAttribute('dir');
if (currentState == 'ltr') {
content.setAttribute('dir', 'rtl');
} else {
content.setAttribute('dir', 'ltr');
}
}
div {
border: 10px solid #000;
/* border-right: 10px solid red; */ /* old */
border-inline-end: 10px solid red; /* new */
}
<div id="content" dir="ltr">
Hi Here is the content
</div>
<button id="RTL">
RTL SWITCH
</button>
dir="ltr" sets the direction of content flow within a block-level element. This applies to text, inline, and inline-block elements. It also sets the default alignment of text and the direction that table cells flow within a table row.
You can use direction: rtl; in CSS and do something like that :
.rtl {
direction: rtl;
}
.element {
border-right: 1px solid red;
}
.rtl .element {
border-right: none;
border-left: 1px solid red;
}
or
.element {
border-right: 1px solid red;
}
#content:dir(rtl) .element {
border-right: none;
border-left: 1px solid red;
}
When the "dir" attribute of content reflects a value of either ltr or rtl, what gets effected is the direction in which text displays. Altering the border-color of an element generally requires a manual solution. Here is one way to accomplish this feat:
HTML:
<div id="content" dir="ltr">
Hi! Here is the content
</div>
<button id="RL">
RL SWITCH
</button>
CSS:
div,.divltr {
border: 10px solid #000;
border-right: 10px solid red;
}
.divrtl {
border: 10px solid #000;
border-left: 10px solid red;
}
JAVASCRIPT:
var d = document;
d.g = d.getElementById;
var rl = d.g('RL');
var c = d.g('content');
rl.addEventListener('click',function(){
toggleWhichWay();
});
function setTextBorder(whichway) {
c.setAttribute('dir', whichway);
c.className = "div" + whichway;
}
function getCurrState() {
return c.getAttribute('dir');
}
function toggleWhichWay() {
(getCurrState() == 'ltr')? setTextBorder('rtl') :setTextBorder('ltr');
}
see demo.
var toggleButton = document.querySelector('#rtl');
var targetEle = document.querySelector('#content');
function toggleTextDir(ele) {
var dir = ele.attributes.dir.value;
ele.attributes.dir.value = dir === 'rtl' ? 'ltr' : 'rtl';
}
toggleButton.addEventListener('click', function() {
toggleTextDir(targetEle);
});
Related
I am new to css. How can I add a status button which changes color depending on chat availability on top of another button?
You can use the position property.
See an example code here.
Some resources:
https://www.w3schools.com/css/css_positioning.asp
https://developer.mozilla.org/en-US/docs/Web/CSS/position
From the picture i can tell you don't have to use 2 html elements on top of each other, but you can use css properties like border and background-color to achieve exactly as the button in your picture.
I posted how in the code below with even a little bit of javascript to toogle the button status (not needed for styling, so if you don't know any javascript yet, you can skip that part).
let isOpen = false;
const btn = document.querySelector("#btn");
const dot = document.querySelector(".dot");
const txt = document.querySelector("#text");
btn.addEventListener("click", () => {
if (isOpen) {
dot.style.backgroundColor = "red";
txt.innerHTML = "The chat is now closed";
} else {
dot.style.backgroundColor = "green";
txt.innerHTML = "The chat is now open";
}
isOpen = !isOpen;
});
.dot {
height: 25px;
width: 25px;
background-color: red;
border-radius: 50%;
display: inline-block;
border: 5px solid gray;
}
#wrapper {
border: 1px solid black;
text-align: center;
padding: 10px;
}
#btn {
margin-top: 10px;
}
<div id="wrapper">
<span class="dot"></span>
<p id="text">The chat is now closed</p>
</div>
<button id="btn">Toogle</button>
Having a table with draggable rows where each row is draggable=true, how can the user still be able to select text from a column?
<table>
<thead>..</thead>
<tbody>
..
<tr draggable="true">
<td>..</td>
<td>Cool text but you can't select me</td>
<td>..</td>
</tr>
..
</tbody>
</table>
Another simple example (https://codepen.io/anon/pen/qjoBXV)
div {
padding: 20px;
margin: 20px;
background: #eee;
}
.all-copy p {
-webkit-user-select: all; /* Chrome all / Safari all */
-moz-user-select: all; /* Firefox all */
-ms-user-select: all; /* IE 10+ */
user-select: all; /* Likely future */
}
<div class="all-copy" draggable="true">
<p>Select me as text</p>
</div>
There are two things we need to do.
One thing is limitting the drag event only trigger on specified area, for example, the drag handle.
The other thing is that we only set the text on the div with content class can be selected. The reason why we do so is that the element that has been set to draggable, on which browser will add a default rule user-select: none.
const itemEl = document.querySelector('.item');
const handleEl = document.querySelector('.handle');
let mouseDownEl;
itemEl.onmousedown = function(evt) {
mouseDownEl = evt.target;
}
itemEl.ondragstart = function(evt) {
// only the handle div can be picked up to trigger the drag event
if (mouseDownEl.matches('.handle')) {
// ...code
} else {
evt.preventDefault();
}
}
.item {
width: 70px;
border: 1px solid black;
text-align: center;
}
.content {
border-top: 1px solid gray;
user-select: text;
}
<div class="item" draggable="true">
<div class='handle'>handle</div>
<div class='content'>content</div>
</div>
One way to make that work, is to actually check which element fired the event, e.target, against the element that has the listener attach to itself, #draggable (in this case using this).
if (e.target === this) {...}
This will allow default behavior on element positioned inside the draggable element, such as selecting a text and so on.
Note, since Firefox has issue with draggable="true", I used a different drag method.
Stack snippet
(function (elem2drag) {
var x_pos = 0, y_pos = 0, x_elem = 0, y_elem = 0;
document.querySelector('#draggable').addEventListener('mousemove', function(e) {
x_pos = e.pageX;
y_pos = e.pageY;
if (elem2drag !== null) {
elem2drag.style.left = (x_pos - x_elem) + 'px';
elem2drag.style.top = (y_pos - y_elem) + 'px';
}
})
document.querySelector('#draggable').addEventListener('mousedown', function(e) {
if (e.target === this) {
elem2drag = this;
x_elem = x_pos - elem2drag.offsetLeft;
y_elem = y_pos - elem2drag.offsetTop;
return false;
}
})
document.querySelector('#draggable').addEventListener('mouseup', function(e) {
elem2drag = null;
})
})(null);
#draggable {
display: inline-block;
background: lightgray;
padding:15px;
cursor:move;
position:relative;
}
span {
background: white;
line-height: 25px;
cursor:auto;
}
<div id="draggable">
<span>Select me as text will work<br>when the mouse is over the text</span>
</div>
I have an text input with the following HTML:
<span>
✍
</span>
<input type="text">
and the corresponding CSS:
input{
text-align: center;
border: none;
outline: none;
background-color: transparent;
}
The input element should blend seamlessly into its background with only the HTML icon indicating that it is indeed an input. The HTML icon will remain in a static position with the current mark-up as new text is added into the input.
Is there anyway to have my HTML icon start right to the left of the first letter and have it gradually move toward the left as the left boundary of the text string pushes in the same direction?
Fiddle Example
If you're ok with contenteditable you could try this:
span{
display: inline-block;
position: relative;
left: 50%;
transform: translateX(-50%);
}
span::before {
content: '\270D';
}
<span contenteditable='true'></span>
A possible but imperfect (needs lots of work) idea using jquery.
fiddle
$('input').bind('keypress', function(e) {
var tester = $(this).val().length;
var code = e.keyCode || e.which;
var currentWidth = $('input').css('width').slice(0, -2);
var currentWidthParsed = parseInt(currentWidth, 10);
if(code == 8) {
var newWidth = (currentWidthParsed - 8) + 'px'
$('input').css('width', newWidth);
} else {
var newWidth = (currentWidthParsed + 8) + 'px'
$('input').css('width', newWidth);
}
});
body {
text-align: center;
}
input{
text-align: left;
border: none;
outline: none;
background-color: transparent;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<span>
✍
</span>
<input type="text">
As far as I know you can't have dynamic width of inputs with something like width: auto. In that case you could have a wrapper with fixed with and a text-align right.
So I would say the only possibility is to have that icon inside the value of the input (if it may exist as UTF-8 icon) and then strip it out when processing the value. But of course this would seem dirty.
I need to have a ng-click-event nested into another ng-click-event.
This doesn't seem to be a problem in the Chrome client I am able to use here at work, but the standard browser is IE9.
The problem is that clicking on the inner control does not trigger the function corresponding to the inner control, but rather the function of the parent control.
The code looks a little like this:
angular.module('App', [])
.controller('Controller', function() {
var self = this;
self.outer_function = function($event) {
alert('Outer function called');
}
self.inner_function = function($event) {
$event.stopPropagation();
alert('Inner function called');
}
});
.outer {
border: 1px solid black;
padding: 10px;
display: inline-block;
}
.inner {
margin: 0 10px;
padding: 5px;
border: 1px solid red;
display: inline-block;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="App">
<div ng-controller="Controller as ctrl">
<button class="outer" data-ng-click="ctrl.outer_function($event)">
This is the div
<div class="inner" data-ng-click="ctrl.inner_function($event)">
Inner div
</div>
</button>
</div>
</div>
Is there anything I am forgetting? Or a workaround to make this work in IE9?
Thanks in advance!
So what I'm trying to accomplish seems like easy CSS etc. Im changing a messaging system and what the conversations to start at the bottom sorta like Facebook or text message where it has one person on the left and the other on the right.
How do I get the divs to go up as new content is added via ajax? I saw this similar question but didn't quite understand what he mean focus on the LI. An example would be great.
Something like this perhaps?
<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}
function newEl(tag){return document.createElement(tag);}
function newTxt(txt){return document.createTextNode(txt);}
function prependChild(parent, element)
{
if (parent.childNodes)
parent.insertBefore(element, parent.childNodes[0]);
else
parent.appendChild(element)
}
window.addEventListener('load', mInit, false);
function mInit()
{
byId('btnAddNew').addEventListener('click', onAddBtnClicked, false);
}
function onAddBtnClicked()
{
var txtInputElem = byId('newMsgTxtInput');
var msgTxt = txtInputElem.value;
var li = newEl('li');
li.appendChild( newTxt( msgTxt ) );
var ulTgt = byId('msgTarget');
var existingLiItems = ulTgt.querySelectorAll('li');
var numItemsExisting = existingLiItems.length;
if (numItemsExisting%2 != 0)
li.className = 'even';
else
li.className = 'odd';
prependChild(ulTgt, li);
}
</script>
<style>
.controls
{
display: inline-block;
padding: 8px;
margin: 8px;
border: solid 1px #555;
border-radius: 4px;
color: #777;
background-color: #ddd;
}
#msgTarget
{
width: 275px;
border: solid 1px #555;
margin: 8px;
border-radius: 4px;
}
/*
Doesn't work 'properly' - since we add items at the top, rather than the bottom
The first item added will be 'even', then the second item gets added and now it's the first child 'even'
so, the item added first is now an 'odd' child. A better way may be to count the number of existing li
items the ul contains, before assigning the new li elements a class of even or odd that will enable css
styling.
#msgTarget li:nth-child(odd)
{
background-color: #CCC;
}
#msgTarget li:nth-child(even)
{
background-color: #5C5;
}
*/
.odd
{
background-color: #CCC;
}
.even
{
background-color: #5C5;
}
</style>
</head>
<body>
<div class='dlg'>
<div class='controls'>
<input id='newMsgTxtInput'/><button id='btnAddNew'>Add message</button>
</div>
<ul id='msgTarget'></ul>
</div>
</body>
</html>