Show div when post has class - javascript

Update
I'd modded the CSS given by David Thomas a bit. Its now a banner.
.div.popular::before {
/* setting the default styles for
the generated content: */
display: block;
width: 10em;
height: 2em;
line-height: 2em;
text-align: center;
background: #F60;
color: #fff;
font-size: 1.4rem;
position: absolute;
top: 30px;
right: 0px;
z-index: 1;
}
I would like to make a folded corner sort of like in this post: Folded banner using css
--- Original post ---
Let me first explain what I'm trying to do. I'm trying to give some post some extra attention by making a little circle with some call-to-action text in it.
But I only want this to trigger when a div has a specific class.
So if the div the class populair or sale I would like to have a little circle show up on that post. This script what I am using right now.
$(document).ready(function($){
if($("#front-page-items").hasClass('populair')){
$(".populair-div").show();
}
if($("#front-page-items").hasClass('sale')){
$(".sale-div").show();
}
});
And this HTML:
<div class="populair-div" style="display:none;">
<strong>Populair</strong>
</div>
<div class="sale-div" style="display:none;">
<strong>Sale</strong>
</div>
But this only show's the populair-div and not the other one. I'm guessing my script is wrong. Should I use else for all the other call-to-action classes?
$(document).ready(function($){
if($("#front-page-items").hasClass('populair')){
$(".populair-div").show();
}
else($("#front-page-items").hasClass('sale')){
$(".sale-div").show();
}
else($("#front-page-items").hasClass('Free')){
$(".free-div").show();
} // and so on
});
Is there someone that could help me out? Also is it possible to echo the div so I don't have to write a whole div for every call-to-action div?

For something like this, where the displayed text is explicitly linked to the class-name of the element it's easiest to use CSS and the generated content available, effectively hiding the elements you don't wish to show by default and then explicitly allowing elements you want to show, along with the generated content of those elements (using the ::before and ::after pseudo-elements:
div {
/* preventing <div> elements
from showing by default: */
display: none;
}
div.populair-div,
div.sale-div {
/* ensuring that elements matching
the selectors above (<div>
elements with either the 'sale-div'
or 'populair-div' class-names
are shown: */
display: block;
}
div.populair-div::before,
div.sale-div::before {
/* setting the default styles for
the generated content: */
display: block;
width: 4em;
height: 4em;
line-height: 4em;
text-align: center;
border: 3px solid transparent;
border-radius: 50%;
}
div.populair-div::before {
/* setting the text with the
"content" property: */
content: "Popular";
/* providing a specific colour
for the generated contents'
border: */
border-color: #0c0;
}
div.sale-div::before {
content: "Sale";
border-color: #f90;
}
/* entirely irrelevant, just so you can
see a (slightly prettified) difference
should you remove the default display
property for the <div> elements: */
code {
background-color: #ddd;
}
em {
font-style: italic;
}
<div class="neither-popular-nor-sale">
<p>
This element should not be shown, it has neither a class of <code>"populair-div"</code> <em>or</em> <code>"sale-div"</code>.
</p>
</div>
<div class="populair-div">
</div>
<div>Also not to be shown.</div>
<div class="sale-div">
</div>

You can use toggle function for this. It will be shorter and clearer.
Display or hide the matched elements.
Note: The buttons is for tests.
$(document).ready(function($){
init();
});
function init() {
$(".populair-div").toggle($("#front-page-items").hasClass('populair'));
$(".sale-div").toggle($("#front-page-items").hasClass('sale'));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="front-page-items" class="populair sale"></div>
<div class="populair-div">populair-div</div>
<div class="sale-div">sale-div</div>
<hr />
<button onclick="document.getElementById('front-page-items').classList.toggle('populair');init()">toggle populair</button>
<button onclick="document.getElementById('front-page-items').classList.toggle('sale');init()">toggle sale</button>

Related

Can this be achieved without js?

I have this image gallery which I want to do without the javascript. Can this be done without using the javascript ?? Just need the big picture to change when mouseover or something similar.
function myFunction(imgs) {
var expandImg = document.getElementById('expandedImg')
var imgText = document.getElementById('imgtext')
expandImg.src = imgs.src
imgText.innerHTML = imgs.alt
expandImg.parentElement.style.display = 'block'
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial;
}
/* The grid: Four equal columns that floats next to each other */
.column {
float: left;
width: 25%;
padding: 10px;
}
/* Style the images inside the grid */
.column img {
opacity: 0.8;
cursor: pointer;
}
.column img:hover {
opacity: 1;
}
/* Clear floats after the columns */
.row:after {
content: '';
display: table;
clear: both;
}
/* The expanding image container */
.container {
position: relative;
display: none;
}
/* Expanding image text */
#imgtext {
position: absolute;
bottom: 15px;
left: 15px;
color: white;
font-size: 20px;
}
/* Closable button inside the expanded image */
.closebtn {
position: absolute;
top: 10px;
right: 15px;
color: white;
font-size: 35px;
cursor: pointer;
}
<div style="text-align: center">
<h2>Tabbed Image Gallery</h2>
<p>Click on the images below:</p>
</div>
<!-- The four columns -->
<div class="row">
<div class="column">
<img src="img_nature.jpg" alt="Nature" style="width: 100%" onclick="myFunction(this);" />
</div>
<div class="column">
<img src="img_snow.jpg" alt="Snow" style="width: 100%" onclick="myFunction(this);" />
</div>
<div class="column">
<img src="img_mountains.jpg" alt="Mountains" style="width: 100%" onclick="myFunction(this);" />
</div>
<div class="column">
<img src="img_lights.jpg" alt="Lights" style="width: 100%" onclick="myFunction(this);" />
</div>
</div>
<div class="container">
<span onclick="this.parentElement.style.display='none'" class="closebtn">×</span
>
<img id="expandedImg" style="width: 100%" />
<div id="imgtext"></div>
</div>
Any help is appreciated. Sorry for adding this text as StackOverflow won't let me post this without adding more text.
Thanks in advance.
Preface
Though not impossible, I nonetheless highly recommend using JavaScript instead of CSS for this task. You should not see the following content of this answer as an alternative to JavaScript's intended purpose, but see this as a playful "solution".
Another big point to use JavaScript instead of CSS is: Using CSS for this task is not accessible at all. You should always strive to make good, easy-to-use and accessible websites.
You should especially refrain from using this in a business environment for the aforementioned reason.
CSS-only solution
Necessary HTML changes
Since CSS is cascading, the image-previews need to come before either the big image itself or its ancestor. You can imagine this like this: The HTML is a tree, and effects are only carried through down to the leaves, but cannot affect neighbouring branches as that would require backtracking at some point.
In code, this could look like this:
<!-- Either this (case 1): -->
<img class="img-preview">
<img class="big-img">
<!-- Or this (case 2): -->
<img class="img-preview">
<div>
<img class="big-img"> <!-- May be nested deeper -->
</div>
The CSS
The CSS should be relatively simple. The only issue is, that for each image-preview, a new CSS-rule needs to be added. This makes adding a new image-preview a bit more work in the future, but more importantly: It crams your CSS full with unnecessary rules! This will probably result in unused CSS-rules in case you'll rewrite some, and will hinder maintenance and readability heavily.
Friendly reminder: This should better be done by using JavaScript!
CSS' :hover-pseudo-class is effectively the same as JS' mouseover. Using this and the general sibling-combinator ~ (and potentially the descendant combinator ), we can override the big image's background-image-property depending on the image-preview that is hovered:
/* Either this (case 1): */
.img-preview:hover~.big-img {/* ... */}
/* Or this (case 2): */
.img-preview:hover~* .big-img {/* ... */}
As I have already mentioned, every image-preview requires its own CSS-rule. This is because CSS cannot use HTML-attributes for its properties (except for pseudo-elements and their content-property, I think).
This means, the CSS could look like this for the current HTML:
/* The CSS */
.img-preview[data-src="https://picsum.photos/id/10/64/64"]:hover~.big-img {
background-image: url("https://picsum.photos/id/10/64/64");
}
.img-preview[data-src="https://picsum.photos/id/1002/64/64"]:hover~.big-img {
background-image: url("https://picsum.photos/id/1002/64/64");
}
/* etc. */
/* Ignore; for styling only */
img {border: 1px solid black}
.img-preview {
width: 2rem;
height: 2rem;
}
.big-img {
width: 4rem;
height: 4rem;
}
<img class="img-preview"
src="https://picsum.photos/id/10/32/32"
data-src="https://picsum.photos/id/10/64/64">
<img class="img-preview"
src="https://picsum.photos/id/1002/32/32"
data-src="https://picsum.photos/id/1002/64/64">
<!-- etc. -->
<img class="big-img">
(Sidenote: I used attribute-selectors here, but the same thing could be done using IDs or similar, as long as every image-preview can be selected individually.)
Endnote
Adding text-descriptions while hovering may be solved in a similar fashion, but is left as a task.
Unfortunately, the big image won't stay when using this approach. If you want it to stay, you should take a look at Abd Elbeltaji's answer. They use <input>- and <label>-tags to accomplish that, together with CSS' :checked-pseudo-class.
Despite looking so, changing the HTML as shown does not restrict you in how you can style your elements, especially when using FlexBox or CSS Grid. Not only do they make styling easier, they are also meant to easily make a website responsive.
Accessibility
Again: This is not an accessible solution! This whole task should certainly be handled by JavaScript.
Should this be a public website, then I advise adding alt-descriptions for every image, even the previews. Unfortunately updating the big image's alt-attribute via CSS is impossible, making it inaccessible, which in turn harms your SEO. This being said, I commend your effort in displaying the image's alt-attribute in your original code, though not perfect. You might want to take a look at <figure>.
While we're at it: I'd also advise learning some semantic HTML-tags for the purpose of accessibility.
Pseudo-elements (::after, ::before, etc.) are also inaccessible. You should not use them to contain any relevant information/text. Though they may be used for styling-purposes in every imaginable way.
Yes, you can achieve the same behavior without the use of javascript, you may use the concept of input elements (checkbox for single toggle value, radio for multiple select values) as adjacent siblings to your elements that they should be affected of the input, and by utilizing the :checked pseudo selector for inputs in css, in a compination with the adjacent sibling selector ~ you can affect the desired elements when the input is checked. You can also use labels which will allow you to hide your inputs and trigger their values with whatever is inside your label.
// No JS!
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial;
}
/* The grid: Four equal columns that floats next to each other */
.column {
float: left;
width: 25%;
padding: 10px;
}
/* Style the images inside the grid */
.column img {
opacity: 0.8;
cursor: pointer;
}
.column img:hover {
opacity: 1;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* The expanding image container */
.container {
position: relative;
}
/* Expanding image text */
#imgtext::after {
position: absolute;
bottom: 15px;
left: 15px;
color: white;
font-size: 20px;
}
/* Closable button inside the expanded image */
.closebtn {
position: absolute;
top: 10px;
right: 15px;
color: white;
font-size: 35px;
cursor: pointer;
}
.container .img {
height: 500px;
width: 100%;
background-image: url(https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
background-size: cover;
}
/* Tab select */
input[name=tabSelect],
#hideImage {
display: none;
}
#tabSelect1:checked~div.container .img {
background-image: url(https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}
#tabSelect2:checked~div.container .img {
background-image: url(https://images.pexels.com/photos/869258/pexels-photo-869258.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}
#tabSelect3:checked~div.container .img {
background-image: url(https://images.pexels.com/photos/1183021/pexels-photo-1183021.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}
#tabSelect4:checked~div.container .img {
background-image: url(https://images.pexels.com/photos/1124960/pexels-photo-1124960.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}
#tabSelect1:checked~div.container #imgtext::after {
content: "Nature";
}
#tabSelect2:checked~div.container #imgtext::after {
content: "Snow";
}
#tabSelect3:checked~div.container #imgtext::after {
content: "Mountains";
}
#tabSelect4:checked~div.container #imgtext::after {
content: "Lights";
}
/* image hide btn */
#hideImage:checked~div.container {
display: none;
}
<div style="text-align:center">
<h2>Tabbed Image Gallery</h2>
<p>Click on the images below:</p>
</div>
<input type="radio" name="tabSelect" id="tabSelect1">
<input type="radio" name="tabSelect" id="tabSelect2">
<input type="radio" name="tabSelect" id="tabSelect3">
<input type="radio" name="tabSelect" id="tabSelect4">
<!-- The four columns -->
<div class="row">
<div class="column">
<label for="tabSelect1">
<img src="https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Nature" style="width:100%">
</label>
</div>
<div class="column">
<label for="tabSelect2">
<img src="https://images.pexels.com/photos/869258/pexels-photo-869258.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Snow" style="width:100%">
</label>
</div>
<div class="column">
<label for="tabSelect3">
<img src="https://images.pexels.com/photos/1183021/pexels-photo-1183021.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Mountains" style="width:100%">
</label>
</div>
<div class="column">
<label for="tabSelect4">
<img src="https://images.pexels.com/photos/1124960/pexels-photo-1124960.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Lights" style="width:100%">
</label>
</div>
</div>
<input type="checkbox" id="hideImage">
<div class="container">
<label for="hideImage" class="closebtn">×</label>
<div class="img"></div>
<div id="imgtext"></div>
</div>
Here is a working example in: JSFiddle
Note! this approach is not optimal and would be tricky to expand in case you need to add more values.
PS: I had to change the images since the ones provided in your code do not exist.

If parent div has no children showing then show a certain different child div

I am seeing simlar questions about hiding parent divs if there is no child but can't find how to show a different div in the parent if no other child is in it.
I have a parent div that is updated with free meeting rooms:
.Parent{
width: 100%;
margin-top: 4px;
overflow: auto;
}
if there is a free room it is display on the board (in the parent). This is done in JS like so:
$('#Parent').addClass("showRooms");
If a room is not free by default it is hidden:
if(roomStatus == "Taken"){
$('#Parent').addClass("hideRooms");
}
The css classes are as so:
.showRooms{
visibility: visible;
background-color: green;
}
.hideRooms{
visibility:hidden;
}
When all the rooms are hidden there is a blank board, I would like to show a different child div in the parent so I can show something more interesting e.g. the company logo.
(I am aware I could have the compnay logo on the parent even if there are rooms showing but I only want it to show if there are no rooms free)
What can I use to achieve this?
Yes!
I've came up with a pure CSS solution, because combining selectors is awesome:
Consider the following setup:
.container {
margin: 10px;
border: 1px solid #000;
}
.room {
width: 100px;
height: 75px;
background-color: #F00;
}
.hidden {
display: none;
}
.placeholder {
display: block;
}
.room:not(.hidden) ~ .placeholder {
display: none;
}
<div class="container">
<div class="room hidden"></div>
<div class="room hidden"></div>
<div class="room hidden"></div>
<div class="room hidden"></div>
<div class="placeholder">No rooms available!</div>
</div>
<div class="container">
<div class="room hidden"></div>
<div class="room"></div>
<div class="room"></div>
<div class="room hidden"></div>
<div class="placeholder">No rooms available!</div>
</div>
Now the magic lies in the following lines:
.room:not(.hidden) ~ .placeholder {
display: none;
}
Explanation:
Take a placeholder, who is a sibling of a .room that does not contain the .hidden class. The placeholder is visible by default, but if it can find a sibling that has a .room without .hidden, it will fall back into display none.
Take note, this requires the placeholder div to always be the last child of it's parent. Since the ~ selector only checks for next siblings, not previous.
I would go something like :
if(allRoomStatusAreTaken()){
$('#Parent').addClass("showLogo");
} else {
$('#Parent').removeClass("showLogo");
}
And
.showLogo{
visibility: visible;
background-image: url(...);
}
In allRoomStatusAreTaken() you have to check if all rooms are taken. I would use a function like every from Lodash :
function allRoomStatusAreTaken() {
return every(allRooms, room => room.status === "Taken");
}
You could hide the logo by default, and change the display using js if the rooms are hidden. Example:
$(function() {
var roomStatus = "Taken";
if (roomStatus == "Taken") {
$('#Parent').addClass("hideRooms");
$('.logo').addClass('show');
}
})
.Parent {
width: 100%;
margin-top: 4px;
overflow: auto;
}
.showRooms {
visibility: visible;
background-color: green;
}
.hideRooms {
visibility: hidden;
}
.logo {
display: none;
width: 200px;
height: 200px;
background: red;
}
.logo.show {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="Parent">
<div class="logo">
</div>
</div>
Just Keep the Logo div with class 'companyLogo' inside parent and use the following CSS and will work.
.hideRooms .companyLogo{
visibility:visible;
}
.showRooms .companyLogo{
visibility:hidden;
}
For more specific answer please provide HTML structure.
When the parent is free you have to use append to add anything you want to the parent
if(roomStatus == "Taken"){
$('#Parent').addClass("hideRooms");
$("#Parent").append("<span>somthing to show</span>");
}
You can have a logo wrapped in some div (or anything else, or you can add a class to the logo image, really anything), which will have a 'hidden' class by default which will hide it and then you can also show this whet you have no rooms, something like:
if(roomStatus == "Taken") {
$('#Parent').addClass("hideRooms");
$('.logo').addclass("visible");
$('.logo').removeClass("hidden");
} else {
$('#Parent').addClass("showRooms");
$('.logo').removeClass("visible");
$('.logo').addClass("hidden");
}
```

"between" CSS/jQuery selector

The problem
Given a jQuery selection of one element (.context), how can I select into it:
the elements that are not child/grandchild of a specific class (e.g. .paragraph) [the class can have deeper nested levels of itself, like .paragraph .paragraph]
the child/grandchild elements with a certain set of tags (e.g. strong | i)
Notes
.context can be descendant of another .context or another .paragraph.
the elements I want to selects can be identified by [data-hint^="I want"] selector (obviously the data attribute is not present in the real scenario).
I don't want just the direct children of .context but also the descendants (obviously filtering away the elements contained in .context .paragraph.
The battle field
$selection = $('.context').first();
$formatting_elements = $selection.find('strong, i')
.not('.paragraph *');
.paragraph {
margin: 15px;
position: relative;
border: 1px solid black;
}
.paragraph .paragraph {
border: 1px solid #444;
}
.paragraph .paragraph .paragraph {
border: 1px solid #888;
}
.context {
margin: 15px;
position: relative;
background-color: limegreen;
}
[data-hint^="I want"] {
background-color: violet;
}
.paragraph:before {
content: '-paragraph-';
position: absolute;
bottom: 100%;
left: 200px;
}
.context:before {
content: '-context-';
position: absolute;
bottom: 100%;
left: 200px;
color: green;
}
.context .paragraph:before {
font-style: italic;
color: #444;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div class="paragraph">
<i>bar</i>
<div class="paragraph">
<strong>foo</strong>
<i>bar</i>
<div class="context" data-hint="Find elements relative to this element">
<i data-hint="I want to get this">foo</i>
<div class="paragraph">
<i>bar</i>
<div class="paragraph">
<strong>foo</strong>
<div class="paragraph">
<strong>foo</strong>
<i>bar</i>
</div>
<i>bar</i>
</div>
</div>
<strong data-hint="I want to get this">foo</strong>
<i data-hint="I want to get this">bar</i>
</div>
</div>
</div>
I tried the above script but it doesn't seem to work.
The goal
is being able to select and change yellow elements to be violet.
Edit
Sorry, misunderstood your question therefore re-writing the entire answer.
What you are trying to achieve here can be done using a custom filter function.
The theory is simple, you select all the elements that meet a specific criteria (including the one's that are children/grandchildren of some specific selector), then you filter your set out given the parent/grandparent criteria
var myElements = $('strong, i').filter(
function() {
return $(this).parents('.context').length < 1;
});
See working fiddle here
UPDATE
In light of your comment, I have made the following changes to the fiddle. I hope this is what you are looking for.
var myElements = $('strong, i', '.context').filter(
function() {
return $(this).parent('.context .paragraph').length < 1;
});
See updated fiddle here

Create and Display a Div using JQuery without distorting other elements

I am trying to create a div and show a timeout message in there. But it actually distorts other parts of Page. For eg see below. Session Timed out is the div with the message.
Now I don't want this to happen. PFB the JQuery code I am using to create this Div
function ShowSessionTimeOutDiv() {
var styler = document.createElement("div");
styler.setAttribute("style","font-size:15px;width:auto;height:auto;top:50%;left:40%;color:red;");
styler.innerHTML = "<b><i>Session TimedOut, Please refresh the Page</i></b>";
document.body.appendChild(styler);
var currentDiv = $('#GoToRequestControl1_UpdatePanel1').get(0);
currentDiv.parentNode.insertBefore(styler,currentDiv) ;
}
Am I missing something here? The Part in which this div is being displayed is coming from Master Page.
Have you tried the position:fixed styling on it in css, i did that on one of my websites and it didn't distort anything.
A page has a natural flow of its elements based on the default display rules specified by the W3C. When you add a div in between other elements it naturally affects the layout of the page; the positions of the other elements.
In order to drop in a new element without it affecting other elements you have to either reserve space for it, or take it out of the normal page flow.
There are a couple of ways to take an element out of the flow — you can float it, float:left or float:right, which is great, for example, to stack blocks on the left (instead of top-down) and let them wrap to new rows as available width changes. Using a flex layout gives you a lot of control also. But in this case of one thing popping up, changing the positioning of the new element is the most straightforward and can let you put the block exactly where you want it.
I have a demonstration and full explanation in a fiddle showing several examples along the way to getting what you want.
Basically, styling is needed to reposition the timeout message element that you're inserting. Styling is better done with CSS styles, compared to adding a bunch of inline styles. If I put my timeout popup message in a "messagebox" I can make a class for it.
/* Your styles, plus a couple extra to make the example stand out better */
div.messagebox {
font-size: 16px;
width: auto;
height: auto;
top: 40%;
left: 30%;
background-color: white;
border: 2px solid black;
}
Likewise, style the message itself with a class, instead of using inline styles and the deprecated presentational tags <b> and <i>.
/* I want the message in a messagebox to be bold-italic-red text. */
div.messagebox .message {
color: red;
font-style: italic;
font-weight: bold;
}
The big difference is that we will change the positioning of the element from the default static to instead use absolute positioning:
/* I don't really recommend a class called "positioned".
A class should describe the kind of thing the element *is*
not how it *looks*
*/
div.messagebox.positioned {
position: absolute;
width: 40%;
padding: 1.5em;
}
/* The container of the positioned element also has to be positioned.
We position it "relative" but don't move it from its natural position.
*/
section#hasposition {
position: relative;
}
The term "absolute" is tricky to learn ... the element being positioned is given an absolute position within its container, in a sense it's positioned relative to its container... but what position:relative means is relative to its own natural position, so it's easy to get confused at first over whether you want absolute or relative positioning.
Putting it all together, we have some basic HTML that represents major portions of a page — a real page will have far more, but those should be contained within some top-level containers. This shows only those top-level containers.
Then we have some javascript that will add the new element at the appropriate time. Here I just call the function to add it after a delay created with setTimeout(). I'm using full-on jQuery since you're using some in your example, and it makes the javascript more portable and more concise.
function ShowSessionTimeoutStyled() {
var styler = $('<div>').addClass('messagebox').addClass('positioned');
styler.html('<span class="message">The Session Timed Out</span>');
$('#hasposition .above').after(styler);
}
// wait 6 seconds then add the new div
setTimeout(ShowSessionTimeoutStyled, 6000);
div.messagebox {
font-size: 16px;
width: auto;
height: auto;
top: 20%;
left: 20%;
background-color: white;
border: 2px solid black;
}
div.messagebox .message {
color: red;
font-style: italic;
font-weight: bold;
}
div.messagebox.positioned {
position: absolute;
width: 40%;
padding: 1.5em;
}
section#hasposition {
position: relative;
}
/* also style some of the basic parts so you can see them better in the demonstration */
section.explanation {
margin: 1em 0.5em;
padding: 0.5em;
border: 1px solid gray;
}
.demonstration {
margin-left: 1em;
padding: 1em;
background-color: #e0e0e0;
}
.demonstration .above {
background-color: #fff0f0;
}
.demonstration .middle {
background-color: #f0fff0;
}
.demonstration .below {
background-color: #f0f0ff;
}
.demonstration footer {
background-color: white;
}
p {
margin-top: 0;
padding-top: 0;
}
section {
font-family: sans-serif;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="explanation">
<p>Here, a div is added dynamically, after the "basic part above", but the added div is <em>positioned</em>. You can see the other content isn't affected.</p>
<section class="demonstration" id="hasposition">
<div class="above">Basic part above</div>
<div class="middle">Middle part</div>
<div class="below">Part Below</div>
<footer>This is the page footer</footer>
</section>
</section>
I highly recommend the site Position Is Everything for articles and tutorials on positioning. Some of its other content is outdated — who needs to make PNGs to do drop-shadows any more? — but the way positioning works hasn't changed.

ContentEditable Placeholder Issue

I followed a SO question on how to create a placeholder for div[contenteditable].
My code looks like: http://jsfiddle.net/sdxjgkzm/
$('div[data-placeholder]').on 'keydown input', ->
if (this.textContent)
this.dataset.divPlaceholderContent = 'true'
else
delete(this.dataset.divPlaceholderContent)
Unfortunately, the problem is that as you can see the standard input's placeholder stays until you begin typing, while the contenteditable's goes away as soon as you click inside.
How do I fix this?
change your html a bit then use the below css:use placeholder instead of data-placeholder i.e. without data attribute.
input,div {
border: 1px black solid;
margin-top: 20px;
}
[contenteditable=true]:empty:before {
content: attr(placeholder);
}
<input placeholder="test"/>
<div contenteditable='true' placeholder="test"></div>
Check this out, CSS only :)
Placeholder support for contentEditable elements, without JavaScript
Updated Fiddle: enter link description here
All you need is to add the following CSS:
[contenteditable=true]:empty:before {
content: attr(placeholder);
display: block; /* For Firefox */
}
/* General Styling for Demo only */
div[contenteditable=true] {
border: 1px dashed #AAA;
width: 290px;
padding: 5px;
}
pre {
background: #EEE;
padding: 5px;
width: 290px;
}
<h3>Placeholder support for contentEditable elements,<br>without JavaScript!</h3>
<h5>Demo:</h5>
<div contenteditable="true" placeholder="Enter text here..."></div>
<p>All you need is to add the following CSS:</p>
<pre>
[contenteditable=true]:empty:before {
content: attr(placeholder);
display: block; /* For Firefox */
}
</pre>
<h5>Notes</h5>
<ul>
<li>Can add a different style than actual text like opacity, italic, etc</li>
<li>If your html needs to be 100% compliant, you can replace "placeholder" for "data-placeholder" on both files</li>
<li>Chrome will add <br />'s inside contentEditable elements in some cases, breaking the :empty check. Can be fixed with a bit of JavaScript.</li>
</ul>
<i>By Ariel Flesler</i>

Categories