How do I add a logic to control CSS "After" Pseudo-elements? - css

Currently I have this html in pug and vue code which is working fine. Basically the arrow width is dynamic.
.abc--step-bar: .abc--step-bar-color(:style="`width: ${progressBar.width}`")
.row
.col(v-for="(item, i) in progressItems")
.abc--step-item(:class="{ 'is__done': progressBar.index > i, 'is__current': progressBar.index === i }")
span.abc--step-dot
This is my css using SCSS
.abc--step-bar {
position: absolute;
top: 0;
left: 16.7%;
right: 16.7%;
height: 3px;
background: #e8e8e8;
}
.abc--step-bar-color {
background: #28A745;
position: absolute;
top: 0; bottom: 0; left: 0;
&:after {
color: #28A745;
content: url("../../assets/images/arrow.png");;
display: inline-block !important;
width: 0;
height: 0;
position: absolute;
right: 6px;
top: -6px;
}
}
.abc--step-dot {
display: inline-block;
width: 15px;
border-radius: 50%;
height: 15px;
background: #e8e8e8;
border: 5px solid #e8e8e8;
position: relative;
top: -7px;
.is__done &,
.is__current & {
border: 5px solid #28A745;
//background: #28A745;
}
}
I use the image for the arrow head.
I do not know how I can hide the arrow head with certain logic using Vuejs. i.e. when the progressBar.index equals 1. My arrow head is at after Pseudo-element.
I tried to put the similar example in my codepen.
https://codepen.io/steve-ngai-chee-weng/pen/xxXmRer

Use a Vue-conditional CSS class hide-arrow that hides it. JS cannot access pseudo elements directly.
.abc--step-bar-color.hide-arrow::after { content: ""; }
Please note that :after is very old CSS 2.1 syntax. In CSS 3 pseudo elements must be prefixed with ::.

Related

Creating dynamic speech bubble with media query

I have a container div I'm using to create a speech bubble pointing to the right like this:
.container {
width: 90%;
height: auto;
padding: 10px;
position: relative;
border-radius: .4em;
}
.container:after {
content: '';
position: absolute;
right: 0;
top: 50%;
width: 0;
height: 0;
border: 0.813em solid transparent;
border-left-color: #ffffff;
border-right: 0;
border-top: 0;
margin-top: -0.406em;
margin-right: -0.812em;
}
When the screen is smaller than 700px, I need the following CSS to apply instead, which creates a pointer facing down instead of right:
.container:after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 0;
border: 0.813em solid transparent;
border-top-color: #ffffff;
border-bottom: 0;
border-right: 0;
margin-left: -0.406em;
margin-bottom: -0.812em;
}
This is how I'm trying to accomplish this, but the speech bubble doesn't seem to react.
#media(max-width:700px) {
.container:after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 0;
border: 0.813em solid transparent;
border-top-color: #ffffff;
border-bottom: 0;
border-right: 0;
margin-left: -0.406em;
margin-bottom: -0.812em;
}
}
If I apply that code directly to .container:after outside of the media query it displays perfectly, but I can't seem to use media query to switch between the two types of speech bubbles. I'm guessing this is a syntax error, do I need to target the div ID instead of the class? The ID is chat_bubble, and here's a code pen.
https://codepen.io/TheNomadicAspie/pen/JjWVbKJ
Your media query is working just fine, the "problem" with your code is that your default styling (Outside of media query) is also applying to the part that's within media query, so under 700px viewport, your :after element has both top: 50%, as well as bottom: 0 properties, same goes for left and right properties, which is why you don't get to see your speech bubble triangle, you can fix this by setting top and right properties to unset for example. otherwise, another solution is to create another media query that will apply 700 pixels and upwards and have your default pseudo element styling
`#media(min-width:700px) {
...
}`
so that your element properties don't "overlap" each other.

How can I make a full width videojs v5 progress bar?

I would like to change the videojs v5 controls layout in order to make a full width progress bar, on top of the vjs-control-bar area, similar to the pre-v5 player skin.
Here is the v5 skin:
And here is the pre-v5 skin. Notice the full width progress bar:
How should I proceed? Is it necessary to modify the component structure tree within the ProgressControl component or can it be done using CSS only, with the existing ProgressControl component?
I noticed that I can put it on top by changing the vjs-progress-control display CSS property from flex to block, initial or inline but I can't set the width to 100% (other ProgressControl components width are still considered). I assume it is because the vjs-progress-control is still in the flex flow of the container.
EDIT
I made some progress. I can achieve the desired effect by using the following CSS:
.vjs-progress-control {
position: absolute;
bottom: 26px; /* The height of the ControlBar minus 4px. */
left: 0;
right: 0;
width: 100%;
height: 10px; /* the height must be reduced from 30 to 10px in order to allow the buttons below (e.g. play) to be pushed */
}
.vjs-progress-holder {/* needed to have a real 100% width display. */
margin-left: 0px;
margin-right: 0px;
}
Unless one of you find a way to make it better, I will post this edit as accepted answer when it will be allowed.
DEMO
.vjs-fluid {
overflow: hidden;
}
.vjs-control-bar {
display: block;
}
.vjs-control {
position: absolute;
}
.vjs-progress-control {
bottom: 28px; left: 0;
height: 10px;
width: 100%;
}
.vjs-progress-holder {
position: absolute;
left: 0; margin: 0;
height: 8px; width: 100%;
}
.vjs-play-progress,
.vjs-load-progress {
height: 8px;
}
.vjs-play-progress:before {
font-size: 12px; top: -2px;
text-shadow: 0 0 2px black
}
.vjs-current-time {
display: block;
left: 35px;
}
.vjs-time-divider {
position: absolute;
display: block;
left: 70px;
}
.vjs-remaining-time {
display: none;
}
.vjs-duration {
display: block;
left: 70px;
}
.vjs-volume-menu-button {
position: absolute;
bottom: 0; right: 55px;
}
.vjs-playback-rate {
position: absolute;
bottom: 0; right: 28px;
}
.vjs-fullscreen-control {
position: absolute;
bottom: 0; right: 0;
}
There's still need to style the subtitles, captions and chapter buttons
.video-js .vjs-progress-control {
position:absolute;
width: 100%;
top:-.3em;
height:3px;
/* deal with resulting gap between progress control and control bar that
is the result of the attempt to keep things "clickable" on the controls */
background-color: #2B333F;
background-color: rgba(43, 51, 63, 0.7);
}
.video-js .vjs-progress-holder {
position:absolute;
margin:0px;
top:0%;
width:100%;
}
This seemed to get rid of the problems I had across other browsers with the :hover styling inherited from video.js. More masterful css developers might be able to make the expansion a bottom-to-top expansion, negating the need for the fancy footwork around the position of the progress control and the color.
Here is a minimal custom skin (in scss) that shows a full-width progress bar above the rest of the controls. This works with video.js 5.19.2
.video-js.vjs-custom-skin {
.vjs-custom-control-spacer {
display: flex;
flex: 1 1 auto;
}
.vjs-time-divider {
display: inherit;
}
.vjs-current-time {
margin-left: 1em;
}
.vjs-current-time, .vjs-duration {
display: inherit;
padding: 0;
}
.vjs-remaining-time {
display: none;
}
.vjs-play-progress:before {
display: none;
}
.vjs-progress-control {
position: absolute;
left: 0;
right: 0;
width: 100%;
height: .5em;
top: -.5em;
&:hover {
height: 1.5em;
top: -1.5em;
}
}
.vjs-progress-holder {
margin: 0;
height: 100%;
}
}

How to combine the ::after and :not pseudo selectors

I have the following SASS code:
section.post {
a {
transition: all $aside-animation-time;
&::after {
position: absolute;
bottom: -.5px;
left: 0;
width: 100%;
height: 0;
content: '';
border-bottom: 1px solid $primary-color;
}
&:hover {
border-color: $hover-color;
}
}
}
What I'm doing here is adding a blue bottom border for all links. However, I noticed that when I use anchor tags with images inside, the image also has the border (since it's a link as well). Now, my goal is to append the anchor styles to text links only.
What I tried so far is using :not(img), chaining it with ::after, overriding the previous rules etc., but nothing worked as expected. Any help would be appreciated.
Currently CSS doesn't have an option to style the parent based on any child elements. If you were styling the image itself with the link it would be fine.
You might be able to use something like jQuery to add a class to any links which contain child images:
$('a:has(img)').addClass('has_img');
You can then use this with your CSS :not as in
section.post {
a:not(.has_img) {
transition: all $aside-animation-time;
&::after {
position: absolute;
bottom: -.5px;
left: 0;
width: 100%;
height: 0;
content: '';
border-bottom: 1px solid $primary-color;
}
&:hover {
border-color: $hover-color;
}
}
}
Maybe this will help you.
a {
display: block;
height: 2.5em;
position: relative;
&:after {
border-bottom: thin solid blue;
bottom: 0;
content: '';
left: 0;
position: absolute;
width: 100%;
}
&:hover:after {
border-bottom-color: red;
}
img {
display: block;
height: inherit;
position: relative;
z-index: 1;
}
}
Quick Codepen sample:
http://codepen.io/vkjgr/pen/WvMGRK

How to strike through obliquely with css showing the text on top of the strike through

I've just run into a very nice answer here about "How to strike through obliquely with css". The solution is nice, but I wonder if it is possible to pimp the CSS snippet there to show the text on top of the strike through.
If not, an alternate solution?
To move something behind the other you need to give it a z-index that is lower than the other element, in this case I gave the strike a z-index of -1
http://jsfiddle.net/p2F7G/1/
.strikethrough {
position: relative;
}
.strikethrough:before {
position: absolute;
content: "";
left: 0;
top: 50%;
right: 0;
border-top: 1px solid;
border-color: #F00;
z-index: -1;
-webkit-transform:rotate(-5deg);
-moz-transform:rotate(-5deg);
-ms-transform:rotate(-5deg);
-o-transform:rotate(-5deg);
transform:rotate(-5deg);
}
You can give the strikethru a lower z-index than the text. I highlighted the text red so it can be seen:
.strikethrough {
position: relative;
color: #f00;
}
.strikethrough:before {
position: absolute;
z-index: -1;
content: "";
left: 0;
top: 50%;
right: 0;
border-top: 1px solid;
border-color: #000;
-webkit-transform:rotate(-5deg);
-moz-transform:rotate(-5deg);
-ms-transform:rotate(-5deg);
-o-transform:rotate(-5deg);
transform:rotate(-5deg);
}
http://jsbin.com/oqibus/109/

Css - how to add an image outside a text box (on the left side but touching the box)

On my website http://goo.gl/ok43H I'd like to add the small "+" icon next to each white text box (I made a mockup of what i'm trying to achieve here: http://goo.gl/ftRpZ ) but I have no idea how to do that.
What would be your suggestions?
Many thanks,
Here is the html code:
<div class="presentation-plusbox">
<p>Expertise dans l'industrie</p>
<p>blblablabla</p>
<p>blabla</p>
</div>
and here is the css code:
.presentation-plusbox
{
width: 500px;
background-color:#FFFFFF;
padding:10px;
margin-left:25%;
color:#000000;
margin-bottom:8px;
opacity:0.95;
filter:alpha(opacity=95); /* For IE8 and earlier */
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
You can use the :before - http://jsfiddle.net/fgRRw/
div:before {
content: "+";
height: 30px;
width: 30px;
text-align: center;
line-height: 30px;
background: orange;
color: #fff;
display: block;
left: -30px;
position: absolute;
}
Just a note - :before is not supported in IE7 and below LINK
Define your + box as a div inside of .presentation-plusbox
Also add position: relative to .presentation-plusbox
Then apply the following css to the plus box
.plusBox {
position: absolute;
top: 20px;
left: -50px;
}
Of course, you'll need to adjust top and left to get it just right.
I haven't tried it, but that should work.
p { position: relative; }
p:after {
height: 20px;
width: 20px;
background-image: url('image.url.goes.here.jpg');
position: absolute;
top: 5px;
left: -20px;
}

Resources