I wish to use CSS background shading to annotate some text in HTML.
But, the regions may overlap each other.
In this example I wish to shade the background of "Jim, Alex, Dunedin" in yellow, then "Dunedin, 184.3" in blue. In this instance, the "Dunedin" element would therefore be shaded in green.
I'm pretty sure this isn't possible in HTML, since I don't think span elements can overlap.
Any other solutions to this problem offered?
Can it be done? Yes.
Should it be done? Maybe not the way I've shown it. It's just to get you started.
span:first-of-type {
background-color: yellow;
}
span:last-of-type {
background-color: lightblue;
display: inline-block; /* needed so that the next line will work as we cannot transform inline elements */
transform: translateX(-59px); /* move this element 59 pixels to the left so that it overlaps */
mix-blend-mode: multiply; /* blend the backgrounds together */
}
<span>Jim, Alex, Dunedin</span>
<span>Dunedin, 184.3</span>
Maybe it would make more sense to process this HTML so that the markup is changed to look something like the following:
.yellow {
background-color: yellow;
}
.blue {
background-color: lightblue;
}
.yellow.blue {
background-color: lightgreen;
}
<span class="yellow">Jim, Alex</span><span class="yellow blue">Dunedin</span><span class="blue">, 184.3</span>
<!-- note, newlines above would result in whitespace separating the background colors between the <span>'s -->
You can can accomplish most of what you're setting out to do via relative/absolute positioning, z-indexing, and setting opacity on these elements to anything under 1.
For example:
<h1>Image Transparency</h1>
<span style='opacity:.3;background:yellow; position:absolute;width:100px; height: 1em;'> </span>
<span style='opacity:.3;background:#98fffc; position:absolute;width:100px; height: 1em; left: 50px;'> </span>
<p>The opacity property specifies the transparency of an element. The lower the
value, the more transparent:</p>
Good luck!
Note: in the end I solved the problem by analysing the data & producing a different span for each differently shaded block.
So effectively, my code produced:
<span class='yellow'>Jim, Alex, </span><span class='yellow-blue'>Dunedin, </span><span class='blue'> 184.3</span>
It did this by creating an array of arrays, with a cell for every character in the text. As the text was analysed, for each character it would add "styles for that character" in the array for that cell. Then the code went through and assigned a span for each consecutive set of cells that shared the same styles.
The Python code to do this is here, and here is an example of the highlighted output, though in this example there are no overlapping regions.
Related
I'm trying to move letters individually from a word one-by-one to the right.
It should look like they're being pulled to that direction from the center.
Look at this pen (not mine, btw): https://codepen.io/egrucza/pen/LZdPeP .
It should be like that, except the word (in HTML) is there already and the letters should move to the right when the word is hovered on.
Now look what I've got so far in my pen: https://codepen.io/jenny0515/pen/wvpdKBz .
A piece here (but please click on my code pen link):
.content1 :hover {
text-align: right;
content: "Hair Clips";
}
.content2 :hover {
text-align: right;
content: "Make-up";
}
.content3 :hover {
text-align: right;
content: "Jewelry";
}
So, instead of the letters appearing from above or below, the word should be at the center of the row (as I have it in my code pen), and when at hover, the last letter of the word should move to the right, and the other letters by it should follow with a slight delay in between each first move.
How can I do that in CSS?
You need to break down the elements to animate them individually.
<div class="center">
<span class="one">M</span>
<span class="two">o</span>
<span class="three">v</span>
<span class="four">e</span>
In this CodePen I broke the letters down into spans and animate manually, there are other solutions you could use to clean up your CSS and handle the delays but this is quick and dirty.
https://codepen.io/duncanlutz/pen/XWVaBQY
I guess you need to understand the basics first. Therefore, a simple example showing the basic concepts only.
To explain:
Use single span elements for the letters (most important and already mentioned by others).
letter:hover should be clear.
The &:nth-of-type(4) part moves the 4th letter using translateX.
Two more things you should know:
The transition property in the example you have posted is a
shorthand, see here
To my understanding, moving all letters one by one on hovering a div would require keyframes.
Note: You can only move the fourth letter on hover with this example.
HTML
<div class="box">
<span class="letter">H</span>
<span class="letter">e</span>
<span class="letter">r</span>
<span class="letter">e</span>
</div>
CSS
$duration: 5s;
span {
display: inline-block;
}
.letter:hover {
&:nth-of-type(4) {
transform: translateX(200px);
transition-duration: $duration;
}
}
That seems to be a dumb question, but I'm really surprised, after a few websites worked with. Why does the foo div is red, not green?
https://jsfiddle.net/de8he92v/
<div class="wrapper-2">
<div class="wrapper-1">
<div>foo</div>
</div>
</div>
<style>
.wrapper-1 { background-color: red; }
.wrapper-2 { background-color: green; }
</style>
Edit
Ok, I read ThisClark answer, but still don't understand.
Here is updated fiddle:
https://jsfiddle.net/de8he92v/3/
Now the foo is yellow, but why it is not green?
The foo is inside red wrapper. Then, the red wrapper is inside green wrapper. So why we don't see green? What the madness?
In other words, if the puppy is inside the kennel, then we would see the kennel. But here we see only the puppy.
<div>foo</div> has the default user agent styles applied to it which is typically a transparent background and display: block.
Since it's inside .wrapper-1 and has a transparent background, you will see red.
To make this really stand out, add this to your fiddle and run it again:
div {
margin: 5px;
padding: 5px;
border: solid black 5px;
}
That additional style will apply to all the divs on the page and give you a better visual idea of where they are and what styles they have.
With the additional style applied, it ends up looking like this:
Additionally, div.wrapper-1 is said to be a child of div.wrapper-2 and even though 1 comes before 2 in numerical order, the div.wrapper-1 styles appear on top of their parent element, div.wrapper-2. The same parent-child relationship applies between div.wrapper-1 and <div>foo</div>.
EDIT
Your updated code in 3D view with margin, padding, and border:
Your update without additional style:
I want to:
be able to style some text on my HTML page so that a certain background color only covers the text and not beyond it.
Ideally I would like to control this from one div.
Here is my jsfiddle of the below:
#edit_this_div {
min-width: 0px;
background-color: yellow;
}
#bad_way {
background-color: yellow;
display: inline-block
}
<div id="edit_this_div">Please edit this div to there isn't extra yellow background without manually setting the width.</div>
<br>
<div id="bad_way">This is the inefficient and manual way.</div>
What I tried:
The way I thought of accomplishing this is to set the div as an inline block, which I've also shown in my jsfiddle. However, I rather not do this because I feel it would complicate things; when I did this my block started jumping around and combining with other elements. I don't plan to have any other elements with the div so I am fine with it staying as a block that takes up the whole line on the screen.
With the display of block, I also tried setting the padding and minimum widths but it doesn't have an effect laterally for removing the extra color that spills past the text.
It is generally recommended that you put text into appropriate block tags, i.e. <p>...</p>, <h1>...</h1>, <blockquote>...</blockquote>, etc.
If you did that, it would be easy, for example:
<div id="edit_this_div">
<p>Please edit this div to there isn't extra yellow background without manually setting the width.</p>
</div>
Then the CSS:
#edit_this_div p {
background-color: yellow;
display: inline;
}
Even cleaner would be to use both <p>-tags as well as additional inline tags, for example <span>-tags:
<div id="edit_this_div">
<p><span>Please edit this div to there isn't extra yellow background without manually setting the width.</span></p>
</div>
CSS:
#edit_this_div p span {
background-color: yellow;
display: inline;
}
What you need is <mark></mark> tag, like this:
<p>Do not forget to buy <mark>milk</mark> today.</p>
Here's a fiddle for you:
http://jsfiddle.net/am9rzfmd/
The default css settings for this tag are:
mark {
background-color: yellow;
color: black;
}
So you don't have to explicitly define the css, only just in case you need to change the color.
Update
As misterManSam pointed out:
Be aware that the element has a special semantic meaning and
shouldn't be used if you just want "to make my text a yellow
background"
Change it from a div to a span and it will only stretch its width to the contents within it.
<body>
<span id="edit_this_div">Please edit this div to there isn't extra yellow background without manually setting the width.</span>
<br>
<br>
<span id="bad_way">This is the inefficient and manual way.</span>
</body>
http://jsfiddle.net/bbv5ryhk/
Question
Can I style just a part of a single character?
Meaning
CSS attributes cannot be assigned to parts of characters. But if you want to style only a certain section of a character, there is no standardized way to do that.
Example
Is it possible to style an "X" which is half-way red and then black?
Not working code
<div class="content">
X
</div>
.content {
position: relative;
font-size: 50px;
color: black;
}
.content:after {
content: 'X';
color: red;
width: 50%;
position: absolute;
overflow: hidden;
}
Demo on jsFiddle
Purpose
My intention is styling the Font Awesome icon-star symbol. If I have an overlay with dynamic width, shouldn't it be possible to create an exact visualization of scores?
While playing around with a demo fiddle, i figured it out myself and wanted to share my solution. It's quite simple.
First things first: The DEMO
To partly style a single character, you need extra markup for your content. Basically, you need to duplicate it:
<div class="content">
<span class="overlay">X</span>
X
</div>
Using pseudo-elements like :after or :before would be nicer, but i didn't found a way to do that.
The overlay needs to be positioned absolutely to the content element:
.content {
display: inline-block;
position: relative;
color: black;
}
.overlay {
width: 50%;
position: absolute;
color: red;
overflow: hidden;
}
Do not forget overflow: hidden; in order to cut off the remaing part of the "X".
You can use any width instead of 50% which makes this approach very flexible. You can even use a custom height, other CSS attributes or a combination of multiple attributes.
Extended DEMO
Great work on your solution. I’ve got a version that uses :after (instead of duplicating the content in the HTML) working in Chrome 19.
http://jsfiddle.net/v5xzJ/4/
Basically:
Set position:relative on .content
Position :after absolutely
Set :after to overflow:hidden
Adjust the width, height, text-indent and line-height of :after to hide bits of it.
I’m not sure if it’ll work well cross-browser though — the em values will probably work out a bit differently. (Obviously it definitely won’t work in IE 7 or below.)
In addition, you end up having to duplicate the content in your CSS file instead of the HTML, which might not be optimal depending on the situation.
I have the following that I would like wrapped as units.
<div class='tag-box'>
<a href=#>Axe Committee</a>
<div class='circle'><a href=#>x</a></div>
</div>
The CSS for these classes are:
.tag-box {
display:inline;
}
.circle {
display:inline;
padding-left:4px;
padding-right:4px;
background:rgb(196,15,24); /*dark red*/
-moz-border-radius:10px;
-webkit-border-radius:10px;
}
.circle a {
font-size:10px;
text-decoration:none;
color:#fff;
position:relative; top:-2px;
}
I can have upwards of 20 or 30 of these tag-boxes displayed inline. The problem is that the wrapping will break the words from each other or even break the red circle from the link. This makes it hard to differentiate which circle belongs to which link. (In the future, each circle corresponds to a different action with respect to the link.) See below.
alt text http://www.freeimagehosting.net/uploads/f0c5a72ac9.png
How do I prevent this kind of wrapping from occurring?
You want each of your .tag-box to be inline (not taking all the width available) but still being considered as a block (its content shouldn't be cut in half). Here enters ... inline-block!
Here is a complete HTML code: http://pastebin.com/24tG7tCz
I used a list of links to better represent the lists of couple of links tag+action (bad news: you've a divitis syndrome ;))
I also added titles: your 'x' links aren't accessible at all and can be confusing for everybody, with or without any handicap, because one is never sure if the x will suppress the tag on the left or on the right: there are dozens of links, each with the text 'x'! A title attribute on the a element tells blind users and everybody else via a tooltip what'll really do that x.
With a span inside a.x, you can change the background-color on hover and focus, it wouldn't be possible with a inside a span or div.
0: Use white-space: nowrap;.
1: You could have the circle as background of your .tag-box (or your .circle a). eg:
.tag-box {
display: inline;
background-image: url('circe.png');
background-position: 100%; /* Display to the right */
background-repeat: no-repeat;
padding-right: 10px /* To leave space for the image */
}
2: You could use fixed-size floating .tag-box-es ( :/ )
3: You could have a (ready made) script put a circle on the right of every ".circle a"
You could try:
.tag-box {
display: inline-block;
}
Although you may experience some issues with firefox 2 and older versions of IE