Apply styling only on the text inside a DIV - javascript

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
}

Related

Hide text completely if it overflows with css

I would like to hide text completely if it overflows.
overflow: hidden won't work for me here, because it will cut off the text.
I would like to use something that "detects" if the text is cut off, and if so it should be removed or not displayed. In this case only one word (or if you want so the word that would get cut).
A pure CSS solution if this is possible would be great. If there is no other way, JS would also be kind of ok.
For my example see the following images. The arrow is inserted by a pseudo class ::before
How it looks when it's fully displayed
How it looks like now when it overflows
What I want it to look like when it overflows
.somediv {
width: 100%;
}
.somediv_2 {
width: 20px;
}
.someanchor {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
background-clip: padding-box;
border-radius: 0;
background: transparent;
font-weight: 500;
color: #000;
box-shadow: inset 0 0 0 1px #000;
line-height: 1.75rem;
padding: .125rem .625rem .125rem .625rem;
display: inline-block;
}
.someanchor::before {
font-family: "Font Awesome 5 Free";
content: "\f0d7";
width: 100%;
height: 100%;
}
<div class="somediv">
<a class="someanchor">
Info
</a>
</div>
<div class="somediv_2">
<a class="someanchor">
Info
</a>
</div>
I made the second button smaller to simulate it. In my case it gets smaller by resizing the viewport, because it's pushed by other elements in a table.

Placeholder for contenteditable div with minimal JS

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.

Vertical align text dynamically

Title of of the album is dynamically generated from admin panel.
So the problem is when titles are not the same length.
They are used for navigating (prev and next) below actual album...
Code:
<div class="album-box">
<div class="prev-album pull-left">
Dynamically generated title
</div>
<div class="next-album pull-right">
<a href="">Dynamically generated title in
Dynamically generated title 3
Dynamically generated title rows</a>
</div>
</div>
Live:
jsfiddle
Not sure how can I position it to be in the middle vertically no matter how long the title is.
Any idea?
Thanks.
EDIT:
I would like to move elements on the left and right border.
Image:
You got plenty of good answers.
Here's one more using display:table
Non-flexbox Demo
.prev-album, .next-album {
font-size: 12pt;
padding: 20px 0;
color: red;
display: table;
}
.album-box a{
display: table-cell;
vertical-align: middle;
}
Use flex: https://jsfiddle.net/58eh0r2g/1/
Add the following code to the parent containers.
display: flex;
align-items: center;
justify-content: center;
In your case these would be .prev-album and .next-album
https://philipwalton.github.io/solved-by-flexbox/demos/vertical-centering/
This solution will lose support for some IE versions, but flex is so powerful it's worth using it.
If you are wanting to grasp a new and awesome css...thing, then I would use flexbox. Flexbox has a property called align-items that will vertically align flex items (children).
Read here: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Browser support is growing, but mobile and IE10 will need -ms- or -webkit- prefix.
Give the next-album and prev-album display: table;
Then add display: table-cell; vertical-align: middle; to the anchor tags inside of those divs.
I also updated your jsfiddle to show my answer.
https://jsfiddle.net/58eh0r2g/7/
You can set css display attribute of the album-box class to table, and child to table-cell, then you can use vertical-align: middle;
Or you could try display flex, but it's not supported by some browsers.
Here's a solution different from the ones posted so far:
jsFiddle Demo
Using a combination of transform and top/left with absolute positioning on the a tags (absolute relative to parent):
.prev-album, .next-album {
font-size: 12pt;
padding: 20px 0;
color: red;
// added this
position: relative;
}
// and these
.prev-album a, .next-album a {
padding: 10px 40px;
position: absolute;
width: 100%;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
Since you want to align the text dynamically in the center of vertical axis, try using the follows:
HTML:
Content here
CSS:
#parent {display: table;}
#child {
display: table-cell;
vertical-align: middle;
}
I have modified your code s per above in this plunk : http://plnkr.co/edit/PdK9YWGUvbuGAW7S00x9?p=preview
This has been asked in various forms all over Stack Overflow but here you go, Simply add this to your CSS:
.prev-album a, .next-album a {
display: table-cell;
text-align: center;
vertical-align: middle;
}
Then change display: inline-block to display: table on both .prev-album and .next-album.
Simple update of your existing code on JSFiddle
Several improvements to your existing code on JSFiddle
You could even opt to use flex box method however older browsers will not support it, especially internet explorer. You can view the browser support for Flex Box on caniuse.com.
You could simplify your CSS by sharing properties as it will reduce code and be easier to manage:
.album-box, .prev-album, .next-album {
border-color: green;
border-style: solid;
border-width: 0;
}
.album-box {
display: block;
width: 100%;
float: left;
border-bottom-width: 2px;
}
.prev-album, .next-album {
font-size: 12pt;
height: 82px;
display: table;
padding: 10px 40px;
width: 50%;
text-align: center;
}
.prev-album {
border-right-width: 1px;
}
.next-album {
border-left-width: 1px;
}
.prev-album a, .next-album a {
display: table-cell;
vertical-align: middle;
}

Change class and css , with jQuery , of a flaticon

This is the situation
<div id="idDiv">
<span class="flaticon-edit23"></span>
</div>
to change the css of the span i have to do this
#idDiv > span::before{
position: relative;
font-size: 26px;
line-height: 60px;
margin-left: 13px;
color: white;
}
if i click on #idDiv, I have to change the icon of the span, and also change some parameters of the css span (in this case, the font-size)
this works , and change correctly the icon
$("#idDiv").find("span:first").removeClass().addClass("flaticon-floppy13");
but I should change the css of the ::before selector , and i try this (and other similar combinations)
$("#idDiv").find("span:first").removeClass().addClass("flaticon-floppy13").find("span:before").css({"font-size":"36px"});
but it does not work properly
how can I do this ? thanks
UPDATE
this don't work
$("#idDiv").find("span:first").removeClass().addClass("flaticon-floppy13");
$("#idDiv").find("span:before").css("font-size","36px");
this don't work
$("#idDiv").find("span:first").removeClass().addClass("flaticon-floppy13");
$("#idDiv").find("span:before").css({"font-size":"36px"});
this don't work
.new_class{font-size: 36px; }
$("#idDiv").find("span:first").removeClass().addClass("flaticon-floppy13");
$("#idDiv").find("span:first").addClass("new_class");
this don't work
.new_class > span::before{font-size: 36px; }
$("#idDiv").find("span:first").removeClass().addClass("flaticon-floppy13");
$("#idDiv").find("span:first").addClass("new_class");
I don't think pseudo elements can be selected and modified as you are trying to do here.
What you can instead do is to have two different pseudo elements defined and either of them would get applied based on the span's CSS class.
e.g.
#idDiv > span.flaticon-edit23::before{
position: relative;
font-size: 26px;
line-height: 60px;
margin-left: 13px;
color: white;
}
#idDiv > span.flaticon-floppy13::before{
position: relative;
font-size: 36px;
line-height: 60px;
margin-left: 13px;
color: white;
}
and then, only changing the CSS class of the span
$("#idDiv").find("span:first").removeClass().addClass("flaticon-floppy13");
should be sufficient..
$("#idDiv").find("span:first").removeClass().addClass("flaticon-floppy13");
$("#idDiv").find("span:before").css("font-size":"36px");
Also
if (!$('.your class').val()) {
$('#idDiv').val("flaticon-floppy13");
} else {
$('#idDiv').val("");
}
or just remove {} but its better to separate the functions. I don't think they work together.
Have you done the same like this?
.new_class{font-size: 36px !important; }
$("#idDiv").find("span:first").addClass("new_class");

Selecting a div without a .Class or #Id

For some reason, it is much easier for me if it is possible to select all the divs that match a particular set of similar style attributes.
Example of div that I want to select
<div style="background-image: url(http://localhost/website/images/template/markers/cluster.png); height: 34px; line-height: 34px; width: 34px; text-align: center; cursor: pointer; color: rgb(255, 255, 255); position: absolute; font-size: 12px; font-family: Arial, sans-serif; font-weight: bold; top: 78.15521871251985px; left: 725.3256078213453px; background-position: 0px 0px; ">15</div>
Other than this div, other divs that needs to be selected can be similar to this one, but with say different height and top left positions. However, the good thing is that the background-image url() remains the same.
How can this selection be made with jQuery? Thank you !!
EDIT
Surrounding Code
Easier to provide a screencap
I don't think it's a good idea, but you can select elements by specific inline style with this:
$('div[style*="height: 34px"]')
Example

Categories