I created a div tag with the contenteditable attribute.
I want to put the placeholder in here, and I found the following code.
[contenteditable=true]:empty:before {
content: attr(placeholder);
display: block;
/* For Firefox */
}
<div class="test" contenteditable="true" placeholder="test"></div>
In a chromium-based engine, it looks like it's working. But I heard there is an error here that requires JavaScript. I couldn't find the error. Can you tell me what the problem is?
I'm also not sure that content:attr(); is the web standard in css. Is it a standardized CSS property?
The problem is that a <br> is automatically inserted inside a contenteditable div when it is empty. I think that they added <br> to prevent it from collapsing. Here's where they discussed this: Bugzilla.
Here's an example of the collapse prevention I mentioned. You can see that, initially, div has 0 height. However, you can still focus on it. Try typing, then erasing everything. Browser automatically inserts <br> to prevent it from returning to 0 height by adding a <br> which is one line-height high.
div {
border: 1px solid black;
}
<div contenteditable="true" data-placeholder="Test"></div>
So we can simply use <span>, which does not insert a random <br>, instead of <div> to do what you want like so. Try typing, then erasing the characters. The placeholder will be there exactly as you want it to be.
* {
box-sizing: border-box;
}
span {
display: block;
width: 100%;
border: 1px solid black;
border-radius: 5px;
font-family: sans-serif;
padding: 10px;
cursor: text;
}
span:empty::before {
content: attr(data-placeholder);
display: block;
height: 100%;
color: #00000066;
}
<span contenteditable="true" data-placeholder="Test"></span>
If you really have to use div, then you can erase the <br> manually using JS:
const editable = document.querySelector('#editable')
editable.addEventListener('keyup', e => {
if (editable.innerText === '\n') editable.innerHTML = ''
})
* {
box-sizing: border-box;
}
#editable {
display: block;
width: 100%;
border: 1px solid black;
border-radius: 5px;
font-family: sans-serif;
padding: 10px;
cursor: text;
}
div:empty::before {
content: attr(data-placeholder);
display: block;
height: 100%;
color: #00000066;
}
<div id="editable" contenteditable="true" data-placeholder="Test"></div>
Using attr() function in CSS with content is not experimental. With other CSS properties like color, though, it is still experimental. Read further on this MDN page.
In .html
<div placeholder="Write your message.." contenteditable class="form-control edit-box holder"></div>
In .css
.holder:before {
content: attr(placeholder);
color: lightgray;
display: block;
position:absolute;
font-family: "Campton", sans-serif;
}
This solution worked for me.
It works on Firefox too. I think I found the "error" that may require the supposed Javascript. Try typing in the div, then delete all of it by CTRL+A backspace; the placeholder won't come back because there's a <br> the browser has automatically inserted (<p></p> in other browsers).
The content property and attr(...) has been standard since IE8, so it's fine.
Related
I want to right-align text to each line in a textarea that a user is typing like this:
It should also support scrolling like this (see how the top is cut off when it's out of view?):
How might I go about doing that?
EDIT:
Also, any div on the right should animate on hover and when clicked, the contents should be copied to clipboard. Like so:
Just make two different text areas and put one at left and second to right. Then make them look visually like one: for left make border-right: 0; for right - border-left: 0;
For your task you could use texterea and div like that:
* {
margin: 0;
padding: 0;
}
.textarea-block {
box-sizing: border-box;
display: inline-block;
border: 1px solid #eee;
padding: 10px;
width: 400px; /* Here you could use % or wh to make it looks better in your app */
}
/* Don't forget to make a clearfix after floats */
.textarea-block:after {
content: '';
clear: both;
}
.left {
font-family: Arial;
font-size: 16px;
border: 0;
width: 50%;
}
.right {
font-family: Arial;
font-size: 16px;
display: inline-block;
text-align: right;
width: 50%;
float: right;
}
<div class="textarea-block">
<textarea name="" cols="30" rows="10" class="left">First line
Second line</textarea>
<div class="right">
First line <br>Second line
</div>
</div>
Just be sure to make the same font-size and font-family to textarea and div to make text looks same.
I'm having a div in HTML which is dynamically creating from the server side. I want to apply css in HTML(front-end) only on that div if and only if its having some-content. If it doesn't have any content then I have no need to apply the new styling.
The sample of HTML code is:
<div class="attr-marker">
Some-text-content <!-- Apply New Styling on it -->
</div>
<div class="attr-marker">
<!-- No need of new styling -->
</div>
<div class="attr-marker">
<!-- No need of new styling -->
<i class="fas fa-car" style="color:#d42424;font-size:px"></i>
</div>
And the CSS which I tried but failed is:
.attr-marker text {
display: block;
width: 12px;
height: 12px;
border-radius: 50%;
line-height: 12px;
font-size: 9px;
text-align: center;
background: #000;
color: #fff;
}
I can achieve it by using javascript but I want purely CSS solution so it'll help me to minimize the code.
You can set default style for empty div by using :empty pseudo selector. And then for regular div, just set the style as given above.
Or you can use :not(:empty) Pseudo Selector to set the style for the div that is not empty.
Here's an example:
.attr-marker:not(:empty) {
display: block;
width: 12px;
height: 12px;
border-radius: 50%;
line-height: 12px;
font-size: 9px;
text-align: center;
background: #000;
color: #fff;
}
Let me know in case you have any questions.
Regards,
AJ
You can use the :empty pseudo-class. However your server will need to output the .attr-marker div with no whitespace.
Like...
<div class="attr-marker"></div>
not
<div class="attr-marker">
</div>
And then the css would be,
.attr-marker:empty {
display: block;
width: 12px;
height: 12px;
border-radius: 50%;
line-height: 12px;
font-size: 9px;
text-align: center;
background: #000;
color: #fff;
}
Additional reading, https://developer.mozilla.org/en-US/docs/Web/CSS/:empty
Writing .attr-marker text { } means you want to access child elements with tag text of class attr-maker. No such tag exists in HTML.
There are specific CSS text and CSS font properties which work only on text. They are to be used in the text's parent element (in your case div with class name attr-marker):
.attr-marker {
/* text properties */
/* some other properties */
}
Properties like display: block;, width: 12px;, height: 12px; and so on, won't work on text.
That being said, you don't need to worry whether your CSS properties will be applied to the text or to the whole div. If you're using the right properties, you can be sure they are only applied to the text.
As for the content(text) presence, you don't need to worry about it. If there is no text, CSS won't change anything.
Either add another class to that div from the server side if it will send content or wrap content with another element and give it some styling.
Edit:
If you know exact position of your element then you can select it with nth-child pseudo-class:
.attr-marker:nth-child(1):not(:empty) {
border: 1px solid #333;
background-color: yellow;
}
If these markers are block rendered elements, the browser should not display them, unless they have content, therefore you can trust the browser to not render the elements with no content, use the max-width and max-height properties below:
.attr-marker {
display: block;
max-width: 12px;
max-height: 12px;
border-radius: 50%;
line-height: 12px;
font-size: 9px;
text-align: center;
background: #000;
color: #fff;
/*If required*/
overflow:hidden
}
Fairly new to programming in general, so this might not be pretty. My problem is when I click the button in the html (Fiddle)
$(document).ready(function() {
$("button").click(function() {
$(".groupcontainer").clone().appendTo(".groupcontainer");
});
});
it will duplicate the first time perfectly. Then, as I keep clicking it, the div will duplicate exponentially and the format gets messy. Also, when it does add to the webpage, the parent div won't expand vertically to allow for the duplicates.
Need one duplicate each time the button is pressed (append to itself, if possible???)
When it's duplicated multiple times, need the parent div to expand with it.
I'm assuming #1 is because I'm using .groupcontainer to clone and appending it to itself - is that an issue? Can someone explain how I would clone .groupcontainer and have it append directly below itself? I've looked around but not seeing the same issue I'm having.
As for #2, does appending this way not allow the parent div to expand?
Am I so far off you want to laugh??
I suggest using a combination of .closest() and .parent() like so (also note my use of the flags for .clone()):
$(document).ready(function() {
$("button").click(function() {
var target = $(this).closest(".groupcontainer");
target.clone(true, true).appendTo(target.parent());
// alternatively you can also use .insertAfter() to
// place the clone after the cloned element rather
// than at the end of all cloned elements
// https://api.jquery.com/insertAfter/
/* target.clone(true, true).insertAfter(target); */
});
});
.groupcontainer {
background-color: white;
height: 225px;
float: left;
margin-top: 10px;
}
.group {
font-family: Arial;
margin-right: 20px;
font-size: 12px;
float: left;
background-color: black;
padding: 2px;
color: white;
clear: both;
display: inline-block;
}
.quantity {
font-family: Arial;
font-size: 12px;
float: left;
background-color: black;
padding: 2px;
display: inline-block;
color: white;
}
.system {
float: left;
background-color: black;
padding: 2px;
display: inline-block;
color: white;
font-family: Arial;
font-size: 12px;
}
.total {
float: left;
background-color: black;
padding: 2px;
display: inline-block;
color: white;
font-family: Arial;
font-size: 12px;
}
.specs {
float: left;
width: 648px;
min-height: 50px;
border-left: 1px solid black;
border-right: 1px solid black;
border-bottom: 1px solid black;
clear: both;
}
.specs table {
width: 650px !important;
}
.specs table tr {
background-color: white !important;
}
.specs table tr td {
font-family: Arial !important;
font-size: 9px !important;
padding: 0px !important;
margin: 0px !important;
color: black !important;
border-bottom: 1px solid black;
}
.specs table tr td span {
color: black !important;
font-family: Arial !important;
font-size: 9px !important;
padding: 0px !important;
margin: 0px !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="groupcontainer">
<div class="group">
<label for="exampleInputText">Group: </label>
<input type="text" name="group_1" id="group_1" onchange="updateDue()" />
</div>
<div class="quantity">
<label for="exampleInputText">Quantity: </label>
<input type="text" name="quantity1" id="quantity1" onchange="updateDue()" />
</div>
<div class="total">
<label for="exampleInputText">System Price:</label>
<input type="text" name="systemprice" id="systemprice" onchange="updateDue()" />
</div>
<div class="system">
<label for="exampleInputText">Group Total:
<script type="text/javascript">
// Library ready to use:
accounting.formatMoney(5318008);
</script>
</label>
<input type="text" name="grouptotal" id="grouptotal" onchange="updateDue()" />
</div>
<!--begin the specs here-->
<div class="specs">
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
<button>Clone all p elements, and append them to the body element</button>
</div>
</div>
Wanted to update this in case someone else sees it. In the end, the best answer:
$('#clone').click(function() {
var target = $('.groupcontainer:last');
target.clone(true, true).insertAfter(target);
});
$(.groupcontainer:last) instead of $(this).closest(".groupcontainer") worked nicely because there was no restriction on where the button is. I neglected to mention in the question that I planned on moving the button.
You are selecting the whole class .groupcontainer and $(".groupcontainer") will actully return you an array with all elements from this class. Why don't you try selecting an element by it's Id. This way you will select only one element and cloning it shouldn't be a probelm.
The problem is that $('.groupcontainer') grabs all elements with a class of groupcontainer. You can grab the most recent one by using .last() then use .parent() to get the parent of the .groupcontainers and append to that.
var $groupContainer = $('.groupcontainer');
$groupContainer.last().clone().appendTo($groupContainer.parent());
You need to define the first instance of .groupcontainer as the page loads. This will find that single group container and make it a variable.
Then when you click, it will append a new (single instance) group container to your container.
$(document).ready(function(){
var clonedGroupContainer = $('.groupcontainer').clone();
$('.groupcontainer').click(function(){
$(this).append(clonedGroupContainer);
});
});
UPDATE
Because we're using a single instance of a clone, the DOM thinks there's only one instance and basically it's just moving the clone around (even though it's going to the same place).
So what we have to do is create the clone of the first element right off the bat, then append that to wherever (I just appended to the body for ease) and then we hide it. It doesn't matter where it is because the element will be hidden (just don't clone it to itself). Then every time we click, it creates a NEW clone of that object and we can manipulate that new clone every time.
$(document).ready(function(){
var clonedGroupContainer = $('.groupcontainer').clone();
$('body').append(clonedGroupContainer);
clonedGroupContainer.addClass('clone').hide();
$(document).on('click', '.groupcontainer', function(){
var clonedGroupContainer2 = $('.clone').clone();
$(this).append(clonedGroupContainer2);
clonedGroupContainer2.removeClass('clone').show();
});
});
the time you select the container inside the click handler is essential.
On the first click, there's only one container and you clone it and append it to itself.
With the second click you have two containers. You select both, and append both to themselves, leading to an exponential behaviour.
Restrict your selector to only one or store your first container in a reference variable.
$(document).ready(function() {
var $container = $('.groupcontainer');
$container.find('button').click(function() {
$container.clone().appendTo($container);
}
});
Good evening!
I have the following code in jQuery that doesnt work. The idea of the code is to fade in or fade out the div depending on the contents.
html code:
<div class="mainContentWrapper">
sample text
</div>
css code:
div.mainContentWrapper{
display: none;
width: 80%;
margin: 0.5% 10%;
padding: 0.5% 3%;
box-sizing: border-box;
border-radius: 4px;
border: 0.15em solid #1C86EE;
background-color: rgba(255,255,255,0.65);
}
jquery function:
$(document).ready(function(){
$('.mainContentWrapper').on('change',function(){
var mainContentWrapper_str=$.trim($(this).text());
if(mainContentWrapper_str.length==0){
$('.mainContentWrapper').fadeOut(500);
}else{
$('.mainContentWrapper').fadeIn(500);
}
});
});
onChange dosen't apply to changes to the css. It is meant for user interface elements such as <input> or <textarea>.
onChange can only be used with <input>, <select> and <textarea>.
I have two divs that are inline. they both have similar styles and importantly both are inline.
JQuery is reporting that their css "display" is block ONLY in chrome. I really need to know that these two are inline.
jsfiddle here
css:
div
{
display: inline;
width: 50%;
float: left;
height: 100px;
text-align: center;
font-weight: bold;
padding: 10px;
box-sizing: border-box;
}
.div1
{
background-color: black;
color: white;
border: 2px solid grey;
}
.div2
{
background-color: white;
color: black;
border: 2px solid black;
}
html:
<div class="div1">1</div>
<div class="div2">2</div>
jQuery:
jQuery("div").click(function()
{
jQuery(this).append("<br/><span>" + jQuery(this).css("display") + "</span>");
});
jQuery("div").click();
Does anyone know what is happening or more importantly what can I do? (other than pull my hair out... its starting to hurt ;) )
As I said in my comment, float: left forces display: block.
Here's the relevant information in the spec:
http://www.w3.org/TR/CSS21/visuren.html#propdef-float
The element generates a block box that
is floated to the left.
And then:
http://www.w3.org/TR/CSS21/visuren.html#dis-pos-flo
Otherwise, if 'float' has a value
other than 'none', the box is floated
and 'display' is set according to the
table below.
To summarize said table: float = display: block.