Align shapes with css :before, :after - html

I am trying to make shapes in the :before/ :after . this works fine in chrome but in Firefox. there is a small misalignment. and while printing that causes a small white space between the element and the :after selector.
This is how it looks in print preview with Firefox
HTML
<div class="container">
<div class="topbar">
<div class="text">Text</div>
</div>
</div>
My CSS
/* Styles go here */
.container .topbar {
height: 15px;
background-color: #91C34F !important;
width: 100%;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.container .topbar .text {
position: relative;
color: #fff !important;
float: right;
top: 3px;
background-color: #91C34F !important;
font-size: 16px;
padding: 8px 80px;
}
.container .topbar .text:after {
height: 0;
content: "";
display: block;
position: absolute;
top: -0.5px;
left: -37px;
border-right: 38px solid #91C34F !important;
border-bottom: 34px solid transparent;
}
This is a plunk for above code https://plnkr.co/edit/oll1ooap2mKC1EQo0n84?p=preview.
How to make that align properly in all browsers?

use equal value for left, border-right and border-bottom, also there is nothing like .5px.
use line-height to make text vertical align.
updated plunk
/* Styles go here */
.container .topbar {
height: 15px;
background-color: #91C34F !important;
width: 100%;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.container .topbar .text {
position: relative;
color: #fff !important;
float: right;
top: 3px;
background-color: #91C34F !important;
font-size: 16px;
padding: 0px 80px;
height:34px;
line-height:28px;
}
.container .topbar .text:after {
height: 0;
content: "";
display: block;
position: absolute;
top: 0px;
left: -34px;
border-right: 34px solid #91C34F !important;
border-bottom: 34px solid transparent;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body>
<div class="container">
<div class="topbar">
<div class="text">Text</div>
</div>
</div>
</body>
</html>

Take http://dowebsitesneedtolookexactlythesameineverybrowser.com/ to heart. Looking good is a sensible goal, looking the same isn't.
Understand the standards (we never know if the difference is because of a bug or because you've provided instructions that only make sense for a particular window size)
Use them (don't forget to validate the HTML and CSS and to lint the JS)
Ensure you engage standards mode
Learn about bugs in browsers
Though your code is right, it works perfectly on chrome.
Do check here,
https://jsfiddle.net/djmayank/q20e6u9m/
HTML:
<div class="container">
<div class="topbar">
<div class="text">Text</div>
</div>
</div>
CSS:
.container .topbar {
height: 15px;
background-color: #91C34F !important;
width: 100%;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.container .topbar .text {
position: relative;
color: #fff !important;
float: right;
top: 3px;
background-color: #91C34F !important;
font-size: 16px;
padding: 8px 80px;
}
.container .topbar .text:after {
height: 0;
content: "";
display: block;
position: absolute;
top: -0.5px;
left: -37px;
border-right: 38px solid #91C34F !important;
border-bottom: 34px solid transparent;
}
Hope it helped.

Related

CSS: Horizontally centering text between two arrows

I am working on a HTML/CSS project. I have the following code:
category-arrows.html:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>CSS Arrows</title>
<link rel="stylesheet" type="text/css" href="category-arrows.css">
</head>
<body>
<div class="arrows-container">
<div class="up-arrow"></div>
<div class="category-rank">
<p>2</p>
</div>
<div class="down-arrow"></div>
</div>
</body>
</html>
category-arrows.css:
.up-arrow {
width: 60px;
height: 60px;
border-top: 15px solid #000000;
border-right: 15px solid #000000;
transform: rotate(-45deg);
margin: 50px;
border-radius: 15%;
}
.up-arrow:hover, .down-arrow:hover {
border-top: 15px solid #28bfa6;
border-right: 15px solid #28bfa6;
cursor: pointer;
}
.down-arrow {
width: 60px;
height: 60px;
border-top: 15px solid #000000;
border-right: 15px solid #000000;
transform: rotate(135deg);
margin: 50px;
border-radius: 15%;
position: relative;
top: -105px;
}
.category-rank {
position: relative;
top: 50%;
transform: translateY(-50%);
right: -69px;
margin-top: -36px;
font-size: 60px;
font-family: Helvetica;
}
The result of the above code is the following:
When the number between the arrows is -1, I get the following:
When the number between the arrows is negative (e.g. -1), the text is not fully horizontally centred between the arrows. I am using the CSS right property to centre the text between the arrows. This works fine when the number between the arrows does not have a negative sign in front of it.
I would like the text between the arrows to always be horizontally centred. However, I am not sure what the best way to do this is. Any insights are appreciated.
One solution would be to check if number < 0, and then use str.substring(1) to remove the first character of that number (the minus sign), and then display a minus sign next to it in fixed position in a span for example or whatever.
That way the number would always be centered, and if negative that minus sign would show itself and not move the number itself.
Your layout is all broken if you'd just add borders and some padding you'll see everything is miss aligned.
body * {
border: 1px solid;
padding: 10px;
}
.up-arrow {
width: 60px;
height: 60px;
border-top: 15px solid #000000;
border-right: 15px solid #000000;
transform: rotate(-45deg);
margin: 50px;
border-radius: 15%;
}
.up-arrow:hover,
.down-arrow:hover {
border-top: 15px solid #28bfa6;
border-right: 15px solid #28bfa6;
cursor: pointer;
}
.down-arrow {
width: 60px;
height: 60px;
border-top: 15px solid #000000;
border-right: 15px solid #000000;
transform: rotate(135deg);
margin: 50px;
border-radius: 15%;
position: relative;
top: -105px;
}
.category-rank {
position: relative;
top: 50%;
transform: translateY(-50%);
right: -69px;
margin-top: -36px;
font-size: 60px;
font-family: Helvetica;
}
<div class="arrows-container">
<div class="up-arrow"></div>
<div class="category-rank">
<p>-1</p>
</div>
<div class="down-arrow"></div>
</div>
You should instead relay on the changing element, the p is the one that changes so we align the arrows according to it.
display:inline-flex to the container will make it shrink to fit the widest element which the p tag, and we apply align-items: center; to center horizontally the arrows.
/* remove unnecessary padding and margin */
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.arrows-container {
padding: 20px; /* just to be safe */
display: inline-flex;
flex-direction: column;
align-items: center;
}
.up-arrow {
width: 60px;
height: 60px;
border-top: 15px solid #000000;
border-right: 15px solid #000000;
transform: rotate(-45deg);
border-radius: 15%;
}
.up-arrow:hover,
.down-arrow:hover {
border-top: 15px solid #28bfa6;
border-right: 15px solid #28bfa6;
cursor: pointer;
}
.down-arrow {
width: 60px;
height: 60px;
border-top: 15px solid #000000;
border-right: 15px solid #000000;
transform: rotate(135deg);
border-radius: 15%;
}
.category-rank {
font-size: 60px;
font-family: Helvetica;
}
/* For the red line to show center, Not needed */
.arrows-container {
position: relative;
}
.arrows-container:before {
content: '';
position: absolute;
height: 100%;
width: 2px;
background: red;
top: 0;
}
<div class="arrows-container">
<div class="up-arrow"></div>
<div class="category-rank">
<p>-1</p>
</div>
<div class="down-arrow"></div>
</div>
<div class="arrows-container">
<div class="up-arrow"></div>
<div class="category-rank">
<p>1</p>
</div>
<div class="down-arrow"></div>
</div>
<div class="arrows-container">
<div class="up-arrow"></div>
<div class="category-rank">
<p>58</p>
</div>
<div class="down-arrow"></div>
</div>
I tried cleaning the code a little bit.

Firefox UI line "glitch"

I have a "small" issue on my website with Firefox. On Google Chrome and Safari it is working just fine.
What it should be (Chrome and Safari):
Issue on Firefox:
.headline {
line-height: 1.5em;
position: relative;
}
.headline:after {
content: ' ';
position: absolute;
display: block;
width: 230px;
margin: 5px 2%;
border: 2px solid #64c800;
border-radius: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
left: 50%;
transform: translateX(-50%);
}
<h2><span class="headline">Contact</span></h2>
The expected result is that the green line should be below the header (in this case below "Contact".
Reproducible code:
Important forgotten note; I use Bootstrap 4 too.
<style>
#wrapper {
position: relative;
margin: 25px auto 5px auto;
max-width: 820px;
min-height: 600px;
padding: 1px 0px 30px 0px;
background-color: #ffffff;
color: #603813;
text-align: center;
}
.headline {
line-height: 1.5em;
position: relative;
}
.headline:after {
content: ' ';
position: absolute;
display: block;
width: 230px;
margin: 5px 2%;
border: 2px solid #64c800;
border-radius: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
left: 50%;
transform: translateX(-50%);
}
</style>
<div class="container-fluid">
<div class="row-fluid">
<div id="wrapper">
<div class="row">
<div class="col-md-12">
<h2><span class="headline">Contact</span></h2>
</div>
</div>
</div>
</div>
I think the problem is that you don't define a vertical position (top or bottom) for your line, so the browser kinda just does anything.
Try adding
.headline:after {
top: 100%;
}
JSFiddle: https://jsfiddle.net/0p7948Lx/2/
I can't reproduce your issue in Firefox 60.8 on Debian. However, here is a somewhat simplified approach that works without position, transform and border. I find it a little more elegant.
Maybe it fixes the issue as well?
h2 {
width: 230px;
text-align: center;
}
.headline {
line-height: 1.5em;
}
.headline:after {
content: '';
display: block;
width: 100%;
height: 8px;
margin-top: 1em;
background: #64c800;
border-radius: 4px;
}
<h2><span class="headline">Contact</span></h2>

Adding a triangle in css under another element

I have been trying hard without success to add a little triangle under my square to act as a pointer like this:
My code by itself works, but whenever I try to add css to make this triangle nothing will appear. I think it has to do with before-after functions, but I'm not really getting it. Anyone can help me with that?
<div id="slider_outer1">
<div class="slider_segment"><img src="myurl.com" alt="Nature" style="width:100%;"></div>
<div id="slider_marker1"></div>
</div>
<style>
.container {width:400px;}
#slider_outer1 {width: 98%;border: 5px solid #8f89ff; position: relative;display: inline-block; border-radius: 5px;}
.slider_segment {width: 100%; float: left; display: inline;}
#slider_marker1 {
position: absolute;
border: 2px solid #574fff;
height: 30px;
width: 5%;
top: 120px;
left: 57.25%;
text-align: center;
Margin-left: -10%;
padding: 5px 0px;
background: #ffffff;
border-radius: 5px;
}
div#slider_marker1:after {
content: "5";
font-size: 20px;
padding: 5px;
line-height: 30px;
font-family: sans-serif;
}
</style>
edit: code of the triangle
<div class="triangle-down"></div>
<style>
.triangle-down {
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 20px solid #555;
}
</style>
Generally in CSS triangles are made using borders, not before and after pseudo elements. To create a downward pointing triangle, you would create a top border of n number of pixels, and left and right borders of half that width and also transparent.
Example:
<div id="slider_outer1">
<div class="slider_segment"><img src="myurl.png" alt="Nature" style="width:100%;"></div>
<div id="slider_marker1"><div id='triangle-down'></div></div>
</div>
<style>
.container {width:400px;}
#slider_outer1 {width: 98%;border: 5px solid #8f89ff; position: relative;display: inline-block; border-radius: 5px;}
.slider_segment {width: 100%; float: left; display: inline;}
#slider_marker1 {
position: absolute;
border: 2px solid #574fff;
height: 30px;
width: 5%;
top: 120px;
left: 57.25%;
text-align: center;
Margin-left: -10%;
padding: 5px 0px;
background: #ffffff;
border-radius: 5px;
}
#triangle-down {
position: absolute;
top: 40px;
right: 50%;
transform: translateX(50%);
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 20px solid blue;
}
div#slider_marker1:after {
content: "5";
font-size: 20px;
padding: 5px;
line-height: 30px;
font-family: sans-serif;
}
</style>
See my codepen here: https://codepen.io/anon/pen/bvXOab
You could add another div for the triangle like
<div id='triangle'></div>
Css For the triangle...
#triangle{
width: 0;
height: 0;
border-left: 40px solid transparent;
border-right: 40px solid transparent;
border-top: 80px solid blue;
}
However I feel that your problem is not that it just isnt appearing its that the positioning is messed up so its 'hidden' behind the sliders
I think I understand what you're trying to make. This should add a triangle above the marker. This solution should allow you to also remove anything related to triangle-down as it only requires the slider_marker1 div
#slider_marker1::before {
content: "";
width: 0;
height: 0;
position: absolute;
top: -6px;
left: 0;
right: 0;
margin: auto;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-bottom: 4px solid green;
z-index: 100;
}

Adding margin-top causes page to extend

Im trying to make the height of the "mainbar" div stretch the entire page without there being a need for the vertical scrollbar while also making sure I can see the top of the div. when I remove the "margin-top" value from the "mainbar" css it removes the scrollbar but cuts off the top 50px. How would I move the div 50px lower (so I can see all of the content inside of it) without extending the page and adding the scrollbar back?
Here is the html:
<!DOCTYPE html>
<html>
<head>
<link href="style.css" type="text/css" rel="stylesheet">
</head>
<body>
<div class="navbar">
<ul>
<li class="nav">Home</li>
<li class="nav">About</li>
<li class="nav">Upload</li>
</ul>
</div>
<div class="mainbar">
<h1>hello</h1>
<h2>whats up</h2>
</div>
</body>
</html>
Here is the css
* {
box-sizing: border-box;
}
body {
background-color: #450068;
background-color: rgb(69, 0, 104);
margin: 0px;
padding: 0px;
}
h1, h2 {
text-align: center;
color: white;
}
li {
display: inline;
text-align: right;
list-style: none;
padding: 20px;
}
.navbar {
background-color: #8729a5;
border-bottom: .5px solid gray;
width: 100%;
height: 50px;
position: fixed;
top: 0;
padding: 0px;
border-bottom-left-radius: 15px;
border-bottom-right-radius: 15px;
}
.mainbar {
background-color: #8729a5;
background-color: black;
height: 100vh;
width: 1100px;
margin-left: auto;
margin-right: auto;
margin-top: 50px;
border: .5px solid gray;
border-radius: 15px;
overflow: scroll;
overflow-x: hidden;
}
* {
box-sizing: border-box;
}
body {
background-color: #450068;
background-color: rgb(69, 0, 104);
margin: 0px;
padding: 0px;
}
h1, h2 {
text-align: center;
color: white;
}
li {
display: inline;
text-align: right;
list-style: none;
padding: 20px;
}
.navbar {
background-color: #8729a5;
border-bottom: .5px solid gray;
width: 100%;
height: 45px;
position: fixed;
top: 0;
padding: 0px;
border-bottom-left-radius: 15px;
border-bottom-right-radius: 15px;
}
body > .mainbar {
background-color: #8729a5;
background-color: black;
height: 90vh;
width: 1100px;
margin-left: auto;
margin-right: auto;
margin-top: 50px;
border: .5px solid gray;
border-radius: 15px;
overflow: scroll;
overflow-x: hidden;
overflow-y: auto
}
new slimScroll(Element);
<!DOCTYPEhtml>
<head>
<link href="style.css" type="text/css" rel="stylesheet">
<script src="slimscroll.js"></script>
</head>
<body>
<div class="navbar">
<ul>
<li class="nav">Home</li>
<li class="nav">About</li>
<li class="nav">Upload</li>
</ul>
</div>
<div class="mainbar">
<h1>hello</h1>
<h2>whats up</h2>
<h2>whats up</h2>
</div>
</body>
Looked at : https://github.com/kamlekar/slim-scroll
and Hide scroll bar, but still being able to scroll
Not sure if that is what you wanted but the plugin removed the scrollbar on the right of the page >>
So the problem, it seems, is that you have a fixed height for navbar, and want mainbar to take the remainder of the screen.
With mainbar having a height of 100vh it will be as tall as the viewport; so anything you do to move it down 50px will cause the scrollbar to appear. This is the headache of mixing pixel sizes and relative (%, vh/vw) sizes.
If your target browser(s) support modern CSS, a flexbox is the solution to this problem.
If not, the "old way" is to use JavaScript to adjust the size of your mainbar div after the initial CSS-based layout is calculated; a pure CSS solution didn't exist before flexbox.
Try modifing your CSS maybe it will solve the problem.
margin-top to padding-top for the .mainbar.
* {
box-sizing: border-box;
}
body {
background-color: #450068;
background-color: rgb(69, 0, 104);
margin: 0px;
padding: 0px;
}
h1, h2 {
text-align: center;
color: white;
}
li {
display: inline;
text-align: right;
list-style: none;
padding: 20px;
}
.navbar {
background-color: #8729a5;
border-bottom: .5px solid gray;
width: 100%;
height: 50px;
position: fixed;
top: 0;
padding: 0px;
border-bottom-left-radius: 15px;
border-bottom-right-radius: 15px;
}
.mainbar {
background-color: #8729a5;
background-color: black;
height: 100vh;
width: 1100px;
margin-left: auto;
margin-right: auto;
padding-top: 50px; /* here */
border: .5px solid gray;
border-radius: 15px;
overflow: scroll;
overflow-x: hidden;
}

css border with triangle shape

Is there any way to create the border on the left with css ?
Here is a way to do it using CSS; you are just layering a Parallelogram and a Rectangle:
.espanolIcon
{
width: 300px;
height: 100px;
padding-left: 30px;
}
.rectangle {
position: absolute;
top: 0px;
left: 200px;
width: 200px;
height: 100px;
background-color: green;
border-radius: 0px 0px 30px 40px;
}
.arrow-left {
position: absolute;
top: 0px;
width: 300px;
height: 100px;
background-color: green;
-webkit-transform: skew(22deg);
transform: skew(22deg);
border-radius: 0px 0px 30px 40px;
}
h1 {
color: white;
}
<div class="espanolIcon">
<div class="rectangle"><h1>Espanol</h1></div>
<div class="arrow-left"></div>
</div>
Use a zero-dimension :before with thick, partial borders
By adjusting the top/bottom and left/right values of border-width on the :before pseudo-element, you can effectively change the skew of the triangle. The left position can then be changed to properly align the pseudo-element.
a {
display: inline-block;
position: relative;
margin-left: 14px; /* Should counter `left` value of `a:before` */
padding: .5em 1em;
color: #fff;
font: bold 1em/1 sans-serif;
text-decoration: none;
text-transform: uppercase;
border-radius: 0 0 10px 10px;
background: #75bf41;
}
a:before {
content: '\200B'; /* zero-width non-breaking space */
display: block;
position: absolute;
top: 0;
left: -14px; /* Adjust to align */
width: 0;
height: 0;
border-width: 14px 8px; /* Adjust top/bottom and left/right to skew */
border-style: solid;
border-color: #75bf41 #75bf41 transparent transparent; /* Triangle orientation. */
}
Español
Full css could work, but you should use .png as background-image or perhaps you could use .svg as you can animate and/or change every point or pixel. You might be able to use just CSSbut it would take a lot of leveling and positioning and alot of layers of absolute and relative positioning. As Css would only change the full width of the element, and it can only be used to change the width of elements. What you can do is use .svg, you could map every pixel which could be animated.
I accomplished it using borders and pseudo elements.
<ul>
<li class="lang-item lang-item-6 lang-item-es">
::before
<a>Español</a>
</li>
</ul>
ul {
position:relative;
}
.lang-item {
text-align: right;
position: relative;
}
.lang-item a {
background: #76c53f;
padding: 15px;
color: #fff;
text-transform: uppercase;
border-bottom-right-radius: 10px;
border-bottom-left-radius: 14px;
}
.lang-item::before {
position: absolute;
right: 101px;
top: -15px;
content: "";
display: inline-block;
border-top: 40px solid #76C541;
border-left: 40px solid transparent;
}
jsfiddle