CSS: Horizontally centering text between two arrows - html

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.

Related

Align Crossmark with text in CSS

I'm trying to create a crossmark and a checkmark to align with the text behind. However, while the checkmark seems aligned well, the crossmark is to the top-right. Is there any way I can fix this reliably? I'm not sure if fiddling with margins and paddings would be smart, as that might break once the size of the screen changes.
.list {
font-family: sans-serif;
margin: 1rem 0 1rem !important;
}
.checkmark {
transform: rotate(45deg);
height: 24px;
width: 12px;
border-bottom: 7px solid lightgreen;
border-right: 7px solid lightgreen;
}
.crossmark {
height: 24px;
width: 12px;
position:relative;
}
.crossmark::after{
position: absolute;
content: '';
width: 24px;
height: 0px;
border: solid orange;
border-width: 0 0px 7px 0;
transform: rotate(45deg);
top:0;
}
.crossmark::before{
position: absolute;
content: '';
width: 24px;
height: 0px;
border: solid orange;
border-width: 0 0px 7px 0;
transform: rotate(-45deg);
top:0;
}
.highlighted-err {
background-color: red;
color: white;
border-radius: 0.5rem;
padding: 0.5rem;
}
.highlighted-success {
background-color: darkgreen;
color: white;
border-radius: 0.5rem;
padding: 0.5rem;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<div class="row list" id="type-msg">
</div><div class="row list highlighted-success" id="size-msg">
<div class="col-md-1">
<div class="checkmark"></div>
</div><div class="col-md-11">
<div>Bild-Dateien müssen 600 x 450 Pixel oder größer sein.</div>
</div>
</div><div class="row list highlighted-err" id="aspect-msg">
<div class="col-md-1">
<div class="crossmark"></div>
</div><div class="col-md-11">
<div>Bild-Dateien müssen eine Breite zu Höhe von 3:4 haben.</div>
</div>
</div>
in your crossmark before and after remove
top:0;
replace in the 2 by
top:12px;
You are making rotation 45deg and -45deg. Position element in center (crossmark 24px, so 12px center), and rotate. Transform origin rotate in center center for the element.
Your absolute positioning with top: 0; forced the before and after elements to the top of the parent.
By switching it to top: 50%; and adding translate(0, -50%) to each transform, you effectively center both elements within the parent element.
This will work even if you start changing the values of the fixed widths and heights.
.list {
font-family: sans-serif;
margin: 1rem 0 1rem !important;
}
.checkmark {
transform: rotate(45deg);
height: 24px;
width: 12px;
border-bottom: 7px solid lightgreen;
border-right: 7px solid lightgreen;
}
.crossmark {
height: 24px;
width: 12px;
position:relative;
}
.crossmark::after{
position: absolute;
content: '';
width: 24px;
height: 0px;
border: solid orange;
border-width: 0 0px 7px 0;
transform: translate(0, -50%) rotate(45deg);
top: 50%;
}
.crossmark::before{
position: absolute;
content: '';
width: 24px;
height: 0px;
border: solid orange;
border-width: 0 0px 7px 0;
transform: translate(0, -50%) rotate(-45deg);
top: 50%;
}
.highlighted-err {
background-color: red;
color: white;
border-radius: 0.5rem;
padding: 0.5rem;
}
.highlighted-success {
background-color: darkgreen;
color: white;
border-radius: 0.5rem;
padding: 0.5rem;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<div class="row list" id="type-msg">
</div><div class="row list highlighted-success" id="size-msg">
<div class="col-md-1">
<div class="checkmark"></div>
</div><div class="col-md-11">
<div>Bild-Dateien müssen 600 x 450 Pixel oder größer sein.</div>
</div>
</div><div class="row list highlighted-err" id="aspect-msg">
<div class="col-md-1">
<div class="crossmark"></div>
</div><div class="col-md-11">
<div>Bild-Dateien müssen eine Breite zu Höhe von 3:4 haben.</div>
</div>
</div>

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;
}

Align shapes with css :before, :after

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.

How to create css headers for bootstrap div's

I'm trying to make the div for bootstrap to look like below not sure how you do it with css. The arrow and the section labeleled movies
Please view the pic at https://plus.google.com/+SamuelMuiruri/posts/fMMhNQwPbCm
First of all you have to position the title "Movies" about the description. The arrow is a only a little css magic
HTML:
<div class="container">
<div class="row">
<div class="col-sm-4">
<div class="specialbox">
<img src="https://placeimg.com/320/240/tech"/>
<div class="specialbox__description">
<span class="specialbox__title">Movies</span>
<h2>Age of Ultron</h2>
<p>Tony Stark tries ti jumpstart a dormant peace-kepping program...</p>
</div>
</div>
</div>
</div>
</div>
CSS:
.specialbox {
border: 3px solid #ccc;
}
.specialbox img {
width: 100%;
}
.specialbox__description {
position: relative; /* You need this, to position the title element absolute to the description */
padding: 20px 10px;
}
.specialbox__title {
position: absolute;
background-color: yellow;
text-transform: uppercase;
padding: 10px;
border-radius: 10px 10px 0 0;
top: -40px; /* Adjust to the height of the title container */
}
/* Magic described here */
.specialbox__title:after {
position: absolute;
display: block;
content: '';
width: 30px;
height: 30px;
border: 15px solid transparent;
left: 50%;
bottom: -30px;
margin-left: -15px;
border-top: 15px solid yellow;
}
http://jsfiddle.net/ytbtbt1d/
I think you want to create a TRIANGLE edge below the div containg the text -'MOVIES' (see screenshot below)
I have created a code for you here: JSFIDDLE
HTML:
<div>Movies</div>
CSS
div{
position: relative;
display:inline-block;
width: 140px;
padding: 10px;
background:#FFC000;
text-transform: uppercase;
font-size: 24px;
text-align: center;
}
div:after{
position: absolute;
width: 0;
height: 0;
border-bottom: 40px solid rgba(0, 0, 0, 0);
border-right: 40px solid #FFC000;
bottom: -15px;
left: 0;
right:0;
margin:auto;
content: '';
-ms-transform: rotate(135deg); /* IE 9 */
-webkit-transform: rotate(135deg); /* Chrome, Safari, Opera */
transform: rotate(135deg);
}

Interesting CSS shape navigation (chevrons)

I'm building a fairly interestingly shaped navigation for a site at the moment. The shape each menu item needs to be is illustrated below:
The final nav will look like an extended version of this:
I thought it would be an interesting experiment to do these shapes in CSS. The CSS and HTML for one of the arrow shapes is here:
.arrowEndOn {
font-size: 10px; line-height: 0%; width: 0px;
border-top: 11px solid #FFFFFF;
border-bottom: 11px solid #FFFFFF;
border-left: 5px solid transparent;
border-right: 5px solid #FFFFFF;
float: left;
cursor: pointer;
}
.arrowBulkOn {
height: 20px;
background: #FFFFFF;
padding: 2px 5px 0px 0px;
float: left;
color: #000000;
line-height: 14pt;
cursor: pointer;
}
.arrowStartOn {
font-size: 0px; line-height: 0%; width: 0px;
border-top: 11px solid transparent;
border-bottom: 11px solid transparent;
border-left: 5px solid #FFFFFF;
border-right: 0px solid transparent;
float: left;
cursor: pointer;
}
<div id="nav" class="navArrow" style="position: relative;">
<div class="arrowEndOn" id="nav"> </div>
<div class="arrowBulkOn" id="nav">NAV</div>
<div class="arrowStartOn" id="nav"> </div>
</div>
Each nav item has a negative offset applied to it (which I've left out of the demo) as it's rendered to get them all flush with each other.
I'm handling the rollovers and on states with Javascript.
My problem is getting the nav to stretch all the way across the width of the page. At the moment I have to set the nav container to a much larger width to accommodate it all.
I've tried setting overflow to hidden but the last item is dropping down a level rather than carrying on and just having the end cut off.
I've set an example up here - http://jsfiddle.net/spacebeers/S7hzu/1/
The red border has overflow: hidden; and the blue doesn't.]
My question is: How can I get the boxes to all float in a line that fills the width of the containing div without them dropping down a level.
Thanks
Add a negative margin to each arrow:
.navArrow {
float: left;
margin-left: -8px;
}
Demo: http://jsfiddle.net/S7hzu/2/
Flexbox
You can use this example
https://codepen.io/WBear/pen/pPYrwo
it works on new browsers, to support old ones some changes needed.
HTML:
<div class="content">
<div class="as1">
NAV
</div>
<div class="as2">
NAV
</div>
<div class="as3">
NAV
</div>
</div>
CSS:
.content {
margin-top: 10px;
width: 100%;
display: inline-flex;
}
.as1, .as2, .as3 {
height: 70px;
min-width: 8%;
max-width: 100%;
background-color: black;
position: relative;
display: inline-flex;
text-align: center;
flex-wrap: wrap;
flex-grow: 1;
}
.as1 a, .as2 a, .as3 a {
text-decoration: none;
display: inline-flex;
color: white;
margin: auto;
font-size: 14pt;
}
.as1:after {
content: "";
position: absolute;
right: 4px;
border-top: 35px solid transparent;
border-left: 25px solid black;
border-bottom: 35px solid transparent;
z-index: 2;
}
.as2 {
background-color: grey;
margin-left: -29px;
}
.as2:after {
content: "";
position: absolute;
right: 4px;
border-top: 35px solid transparent;
border-left: 25px solid grey;
border-bottom: 35px solid transparent;
z-index: 3;
}
.as3 {
background-color: #A9A9A9;
margin-left: -29px;
}