how to use pseudoclass :before/:after? - html

hello I'm having problems through using css pseudo classes :before and :adter to echo out different error messages that comes from php on a div layer.
beside the input field i would like to display a div layer. therefor i use z-index method because that div is front of body.
now my problem is that the div layer should appear with different lengths regarding from the string length. in another question someone gave me the hint instead of using an extra div for an arrow and then using the div layer to combine both into one. therefor i found hints at the web to use pseudo classes and creating a speechbubble. as i looked for it i found nearly everywhere the same.
the div layer would be the relative object and the arrow is the child object. In my case it needs to be other way round. the arrow has to be the relative object because of its fixed position next to the input fields. the div layer is variable in its length but should be appended left hand side to the arrow.
so the problem i have is that the div layer will not be displayed when setting the css like:
.wrapper #header #navline form .erm { //the div layer for the arrow that will be placed next to the input field
position:absolute;
z-index:2;
width: 0px;
margin-left: -25px;
margin-top: -10px;
height: 0px;
border-top: 20px inset transparent;
border-left: 22px dashed #f23;
border-bottom: 20px inset transparent;
}
.wrapper #header #navline form .erm:before { // to border arrow
content:"";
position:absolute;
z-index:2;
margin-left: -22px;
margin-top: -17px;
width: 0px;
height: 0px;
border-top: 17px inset transparent;
border-left: 19px dashed #f2f2f2;
border-bottom: 17px inset transparent;
}
.wrapper #header #navline form .erm.left { //the wrapper with the text that should be append left to the arrow
content:"";
color: #F23;
position: absolute;
z-index: 2;
height: 26px;
padding:12px;
white-space: nowrap;
line-height: 26px;
font-family:Arial, Helvetica, sans-serif;
}
and here is the html:
<?php if (empty($errors['a']) === false){?>
<input class="error" type="text" id="a" name="a" value="<?php echo isset($a) ? $a : '';?>" />
<div class='erm'>
<?php echo $errors['a'][0];?>
</div>
<?php }?>
i made some screenshots to show what i would like to archieve.
here is what it should look like:
okay, this what i looks like before. as on the picture there is the red arrow, the gray layer above and the div layer for the text, what not will be visible at all.
so when setting up the div layer as a relative object it will happens this when the strlen is longer than in that version i positioned it before:
or when strlen is shorter:
so if there is someone who could help me out i really would appreciate.
thanks alot.

I think that you have almost all that you need ok.
I would say that the only detail that you are missing is how to position your bubble.
Try setting only the right property
.wrapper #header #navline form .erm.left {
right: 15px;
This should anchor the right border where you want it, and if the width changes it will be the left side that moves.
Note: I haven't checked the pixel value above, it's just an example
editing
I have done my best with your fiddle:
update
I have added inputs to make it more similar to what I think that you want.
Then I have positioned your divs, (where the text is) absolutely to match the input position, but using the right property. This way you don't need to worry about the text length. You only need to take into account to leave some space for the arrow.
Last, I put the arrow where it should be.
You can not position an pseudo element (like ::after) relative to the "father" element

Related

space between text and border bottom

How do I create distance between the text and the border below the text as shown in the image attached using sass/css?
I want the distance to be 5px and the font-size of the text to be 15px.
I tried doing
.selected {
color: #284660;
}
.selected:after {
content: '';
position: absolute;
width: 100%;
height: 0;
left: 0;
bottom: 5px;
border-bottom: 2px solid #284660;
}
but that created a border that was too wide.
I feel couple of things which can be improved in the above snippet.
You may not need psuedo element for desired effect
You should not use absolute positioning for that , in case you want to use psuedo element
In any case you can try this out.
&.selected {
color: #284660;
border-bottom: 2px solid #284660;
padding-bottom:10px ; // this should give you some spacing.
}
Try a negative
{
bottom: -5px;
}
Besides the complete lack of knowledge of your DOM profile or what element the & refers to, if you just slap a border and padding on an inline element, you'll have the effect you want.
No need to play with pseudoelements.
<span style="padding-bottom:5px; border-bottom:2px solid black;">Some Text</span>
Obviously, you should put that styling info in the css file, I merely inlined it for the example.
Oh and next time, please include sample HTML with your sample CSS. Only reason I even bothered was because the solution was as simple as "What is padding for 15, Trebek?"

Creating a triangle out of div with css logic explanation? [duplicate]

This question already has answers here:
How do CSS triangles work?
(23 answers)
Closed 7 years ago.
I recently worked on creating an element with some text inside it, but it has to be flag based shaped. I googled and found below nice css to achieve it. They basically created small triangles out of div(pointing to left/right/top/bottom) using css and attaching it with adjacent div.
However,I did not find any answers with the logic mentioned thus making me little confused about the triangle creation out of div using CSS.
I wanted to know how that css works, specifically for arrow-left class used below.
HTML:
<div class='element'>
<p>OFFER</p>
<div class="arrow-left"></div>
</div>
CSS:
.element{
background-color:#E47911;
display:inline-block;
position:relative;
padding:2px 15px 2px 10px;
color:white;
line-height:18px;
}
p{
font-size:10px;
margin:0;
}
.arrow-left {
width: 0;
height: 0;
border-top: 11px solid transparent;
border-bottom: 11px solid transparent;
border-right: 11px solid white;
display:inline-block;
position:absolute;
top:0px;
right:0px;
}
Here's the codepen link: http://codepen.io/anon/pen/JGvBpN
Any pointers is much appreciated! Thanks.
It doesn't create a triangle so much as it appears to given how border intersections are rendered at an angle.
.arrow-left {
width: 0; /* unnecessary, but does override any unexpected width */
height: 0; /* unnecessary, but does override any unexpected height */
/* These set up the intersecting borders, set each one to a different color to see the borders forming the "triangle" e.g. red, green, blue */
border-top: 11px solid transparent;
border-bottom: 11px solid transparent;
border-right: 11px solid white;
display:inline-block; /* unnecessary, you're taking the elemtn out of the document flow when you absolute potiion it and the div id a block level element anyway, but to correctly have a border you'll need this so it's a decent safeguard */
/* this takes the element out of the document flow and positions it absolutely within the nearest positioning parent, in this case, the relatively positioned parent */
position:absolute;
/* this moves it to the top right edges of the positioning parent*/
top:0px;
right:0px;
}
Here'es an illustration of the box in chrome's dev tools, pulled out of position to make the effect of what's going on made more obvious:
And here it is with positioning restored:
Note that the part you think is transparent is actually opaque so this isn't masking any part of the orange checkout block; it would be obvious that you drew a white part there if the background of the underlying page were not also white.
For what it's worth, it may be worth looking into using an image or SVG and CSS masking to actually "cut" part of the button out, but you'll need to check the user agent support for your needs or try some work arounds.

Fixed placement of element, but considering pseudo before element

I have an annoying issue with the html layout of a form. I cannot really change the general setup, since it is part of a huge framework. But I have to "move" a button to a more suitable location. I am close, but not happy with the solution so far. Maybe you can give me some idea in this. Here is a dramatically simplified version to demonstrate my approach:
I have two container divs, top and bottom.
The top container shows a button on the left side. That button is fixed, but can have a different width due to the translation of its label.
The bottom container holds lots of stuff. Amongst that a second button at its top which works fine, but looks wrong. I want to optically move it into the top container, since there is a logical connection to the button in there. Sure, really placing it in there would be the correct solution, but I currently cannot do that. Instead I use a fixed position which works fine, except for the horizontal placement. I have to decide how far pushed from the left to place the button, so that it certainly does not overlap the first button in the container. I obviously have to consider all translations, the result works, but depending on the first buttons label I have an annoying horizontal gap between the two buttons.
I tried to use a pseudo element (::before) on the second button to help with the layout. Since when rendering the view I obviously have the translated label of the first button I can copy that into some property of the second button and use that property in my css to fill a before pseudo element of the second button which has exactly the same length as the first button. That is what is shown in the code example posted below.
What I completely fail to do is to place that pseudo element such that is it left in the top container (so exactly below the first button). The idea is to indirectly place the second button that way. Looks like this is not possible, obviously. But since I am a bloody beginner in markup and styling I thought it might be worth asking here...
Below is some drastically stripped down code to demonstrate my approach.
I create a jsfiddle for you to play around with. Here is the code:
HTML:
<div id="top-container">
<button>multilingual button text</button>
</div>
<div id="bottom-container">
<h2>
Some title opening the bottom container
<span class="into-top-container">
<button id="place-me" reference-text="multilingual button text">button to be placed</button>
</span>
</h2>
<p>Some content</p>
<p>Some content</p>
<p>Some content</p>
</div>
CSS:
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
div {
margin: 0;
padding: 5px;
}
button {
margin: 0;
padding: 5px;
white-space: nowrap;
}
div#top-container {
width: 100%;
border: 1px solid green;
}
div#bottom-container {
width: 100%;
border: 1px solid blue;
}
#place-me {
position: fixed;
top: 0;
left: 400px;
margin: 5px;
background: yellow;
}
#place-me::before {
z-index: 0;
/*visibility: hidden;*/
position: absolute;
content: attr(reference-text);
margin: 0 5px;
padding: 0;
background: gold;
right: 100%;
}
Notes:
that in the above code the second button is placed with left: 400px;. That is more or less what I want to change. But obviously left: 0 is not correct...
the visibility css rule for the pseudo element is currently commented out for demonstration purpose
keep in mind that the second button is *not* contained inside the top container, but actually logically below the title of the bottom container. The goal is to move it optically up into the top container which already is where close to what I want. Except for the horizontal alignment...
Upon request here is a screenshot:
It is taken from the fiddle I posted above. I added the red ellipse which shows what element pair I want to move and the left pointing arrow indicating where I want to move that too. I want to move it exactly that far, that the two tests "multilingual button text" are exactly placed on top of each other, but without specifying an explicit left placement obviously. That is why the pseudo element exists: as a dummy placeholder. I would then hide that pseudo element and have the second button placed exactly right of the first button, regardless of how long the translated text in there is.
So the final result should like like that:
OK, I invested some more time, since this issue popped up again after a regression in our code and I found, as often after allowing some time to pass, a logical and relatively clean solution:
I use the same stripped down code to for demonstration purposes.
The jsfiddle is based on the one provided in the question itself.
HTML: no real change, except for the reference-text having moved from button to container, for the why see below:
CSS:
* {
font-size: 12px;
font-weight: normal;
font-family: Arial;
}
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-size: 12px;
font-weight: normal;
}
span,
div {
margin: 0;
padding: 5px;
}
button {
margin: 0;
padding: 5px;
white-space: nowrap;
}
div#top-container {
width: 100%;
border: 1px solid green;
}
div#bottom-container {
width: 100%;
border: 1px solid blue;
}
span.into-top-container {
position: fixed;
top: 0;
left: 0;
pointer-events: none;
border: 1px solid transparent;
}
span.into-top-container::before {
visibility: hidden;
content: attr(reference-text);
position: relative;
margin-right: 5px;
padding: 5px;
border: 2px solid;
background: gold;
}
#place-me {
background: yellow;
pointer-events: all;
}
The basic change in strategy: it is the container holding the button to be placed that has to be positioned in a fixed manner, not that button itself (so the <span class="into-top-container">)! That allows to use the pseudo before element, now also anchored to that container, not the button, to take the space as required without actually getting part of the button itself.
Since that container is now place over the original multilingual button that one is not clickable any more. That issue is fixed by a css pointer-events set to none for the container and set to all for the placed button again. That makes the container itself simply ignore all events (clicks) and have them passed to the original button beneath.
I had to make sure that the font used inside the pseudo element is style exactly like the original multilingual button. That actually makes sense, since the font styling defines the actual width used by that button, so the actual width used by the pseudo element should be defined in exactly the same manner. In the example above I forced that by simply setting all elements font style rules to some fixed values (the initial * {...} in the CSS code). That can obviously also be done right inside the css rules for the pseudo element itself. I chose the more simple and brute variant here to keep the code clean.

CSS vertical-align: middle not working on nav bar with text to the left and login link to the right

I have a page with a header, followed by a (menu/tool) bar underneath, which is supposed to carry two elements: a text to the left (big font) and a login link (smaller text). The right hand link is supposed the be centered vertically.
The following resource seemed to be exactly what I need:
http://www.css4you.de/Texteigenschaften/vertical-align.html
and
http://www.css4you.de/example/vertical-align.html
Here's my HTML:
<div style="border: 1px solid purple;">
<h1 style="border: 1px solid red; display: inline;">Textext</h1>
<span id="logindisplay" style="border: 1px solid lime; float: right; vertical-align: middle;">Log In</span>
</div>
The CSS ID selector for logindisplay doesn't exist. h1 is just
h1
{
font-size: 18pt;
}
I basically did everything as in the resource above, but it doesn't work - neither on IE9 nor on FF. Here's what I get:
Does anybody know what I'm doing wrong?
Note: Workarounds/hacks aren't desired. (One would be to set padding-top: on the span...)
Try this
#logindisplay { line-height: 18pt; }
...and get rid of your vertical-align property.
vertical-align doesn't work in the way you thinkit does, it seems. Take a look at http://css-tricks.com/what-is-vertical-align/ for a good explanation of what it does.
Using float:right negates the vertical-align as you found. Mark's suggestion doesn't work with position:relative on the div? In which case, line-height seems like the easiest way.
make your outer div be display: table-cell, or give it a line-height of appropriate size.
vertical-align is one of the stupidest bits of CSS, and rarely works as you'd expect without having to hack up containing elements: http://phrogz.net/css/vertical-align/index.html
A different approach would be putting position relative on the parent div and then absolute position the span like this:
#logindisplay {
position: absolute;
right: 0;
top: 50%;
margin-top: -9px;
}
Example

CSS z-index mystery

I have some problems with CSS and z-index. Let me show you an example
Suppose that on a first moment it only appears the tag pointers. Then, when I click one of this pointers appears a tag globe. I want that the tag pointers appears always under the tag globes, and I want too that every time I open a tag globe it appears over all other tag globes opened.
My div structure is:
<div id="t01" class="tag">
<div class="small">
<div class="globe">
<div class="in-globe">
<!--tag globe content-->
</div>
</div>
<div class="globe-arrow"></div>
</div>
</div>
And the related CSS code is this:
.tag {
z-index: 3;
position: absolute;
left: 0; /*JavaScript modified*/
top: 0; /*JavaScript modified*/
width: 19px;
height: 26px;
padding: 0 11px 10px 15px;
background: url('../../images/zoom/tag.png') no-repeat center;
}
.small {
cursor: pointer;
width: 19px;
height: 26px;
}
.globe-arrow {
position: absolute;
left: 23px;
bottom: 30px;
width: 8px;
height: 6px;
background: url(../../images/zoom/tag_arrow_UR.gif) no-repeat;
z-index: 5;
}
.globe {
position: absolute;
left: 23px;
bottom: 30px;
z-index: 4;
}
.in-globe {
font-size: 11px;
margin: 0 0 3px 3px;
padding: 3px;
background: #FFF;
border: 1px solid #000;
}
The 'tag' is all the conglomerate, and its background is the tag pointer image. However, this image has some shadows and I only want that a certain zone can be clicked. Then, the 'small' div has this function. The 'globe' and 'in-globe' divs are where the content of the globe is written (it could be an only div, there are two for historical reasons), and the 'globe-arrow' div is basically a little image to show this small arrow over the globe.
With this structure it doesn't work. In a same conglomerate, a globe is always over a tag, but an entire conglomerate defined before in the html code appears entirely under a newer one. In the same way, although a globe is inserted by JavaScript always after an older one (logically) the tag conglomerate is inserted when the page is loaded and then the overlapping works like I said.
Can you propose an smart way to reach my objective? Think that I'm interested on positioning the globe respective to the tag, because when I drag a pointer with a globe opened I want that the globe moves with it by CSS, not by JavaScript.
give .globe-arrow a z-index of 3
I solved the problem. There's no magic way to do it. I had to change the way I structure tags. It seems that z-index inherits from the container div, then like the parent has less z-index, a son of another parent with the same z-index appears under the first although this son has a bigger z-index. It's very confusing, yes.
In few words, I define a tag-container (to positionate the tag), into it I define a pointer and a tag globe. The first with less z-index than the second. Now, as all the divs with z-index has the same level all tag globes appear over all tag pointers.
I want that every time I open a new tag globe it appears over the opened globes. Against my desires, I had to use JavaScript for this because with a same z-index the browser show over the last defined div. This is ugly. I build a stack of z-index's that increases with more globes and decreases when I close them. Then I simply edit the css dinamicaly to put this new z-index to the new globe.
Thank you for your attention and help :) I hope this could be useful for somebody.