I am center aligning inline-block elements by using a 50% margin and transformation.
When I add transform: translateX(-50%); it causes a thin border to appear on the left side of my divs (its a little hard to see but its on the left of 'all' and left of the 'search products').
If i try changing the translate to diffrent percentages it stays; sometimes the border gets thicker when i change the percentage. Anyone know why this could be happening?
Here is my code incase i missed something that might be important:
HTML:
<div class="tabs">
<a class="tab active">All</a>
<a class="tab">New</a>
<a class="tab">Popular</a>
<i class="fa fa-search"></i>
<div class="search-input active">
<%= text_field_tag :term, params[:term], placeholder: "Search products..." %>
</div>
</div>
CSS:
.tabs {
display: inline-block;
vertical-align: bottom;
margin-left: 50%;
transform: translateX(-50%);
}
.tabs .tab {
margin-right: 32px;
color: #92969c;
height: 40px;
line-height: 40px;
text-decoration: none;
display: inline-block;
vertical-align: bottom;
font-size: 12px;
font-weight: 700;
letter-spacing: 1px;
cursor: pointer;
}
.tabs .tab.active {
color: #25282c;
-webkit-box-shadow: 0 2px 0 #25282c;
box-shadow: 0 2px 0 #25282c;
border-bottom: 2px solid #25282c;
}
.search-input {
display: inline-block;
max-width: 240px;
padding: 0 32px 0 10px;
height: 40px;
position: relative;
}
.search-input input {
outline: none;
height: 40px;
width: 100%;
border: none;
padding: 0;
}
.search-input.active {
-webkit-box-shadow: 0 2px 0 #25282c;
box-shadow: 0 2px 0 #25282c;
}
EDIT: It seems like the issue is happening because of my box-shadow code:
.search-input.active {
-webkit-box-shadow: 0 2px 0 #25282c;
box-shadow: 0 2px 0 #25282c;
}
But i dont want to have to remove my box shadow to fix this...
This is a known bug with translate in transforms, and the solution is the null translation hack:
.tabs {
display: inline-block;
vertical-align: bottom;
margin-left: 50%;
translateX(-50%) translate3d(0,0,0);
}
By adding translate3d(0,0,0) to your element, you can fix your box shadow problem without removing them!
It seems you want it to be a border
By changing
.search-input.active {
-webkit-box-shadow: 0 2px 0 #25282c;
box-shadow: 0 2px 0 #25282c;
}
to
.search-input.active {
border-bottom: 2px solid #25282c;
padding-bottom: 0px;
}
You will get the same result without the faded line on the side.
Instead of using a shadow to make that border wider, without causing the other tabs to move down, you can add a transparent bottom border to all of them and change its color just on the active one.
Also, you can use Flexbox instead of translate to horizontally center the menu.
Any of these options alone would fix your problem. Here's an example using both:
.tabs {
display: flex;
justify-content: center;
font-family: monospace;
font-size: 12px;
font-weight: 700;
letter-spacing: 1px;
}
.tab {
margin: 0 16px;
color: #92969c;
height: 40px;
line-height: 40px;
text-decoration: none;
vertical-align: bottom;
cursor: pointer;
border-bottom: 4px solid transparent;
}
.tab.active {
color: #25282c;
border-bottom-color: #000;
}
.tab:hover {
border-bottom-color: cyan;
}
.search-input {
max-width: 240px;
padding: 0 32px 0 16px;
height: 40px;
position: relative;
border-bottom: 4px solid transparent;
}
.search-input.active {
border-bottom-color: #000;
}
.search-input input {
outline: none;
height: 40px;
width: 100%;
border: none;
padding: 0;
font-family: monospace;
font-size: 12px;
letter-spacing: 1px;
}
<div class="tabs">
<a class="tab active">All</a>
<a class="tab">New</a>
<a class="tab">Popular</a>
<div class="search-input active">
<input type="text" />
</div>
</div>
I had the same issue and the ticked solution didn't helped me so I used margin-left 100% - a couple of percentage for this to work
Before
transform: translateX(100%); top: 0; right: 0;
After
top: 0; margin-left: 97%;
and this worked for me
Related
This question already has answers here:
CSS hover border makes elements adjust slightly
(14 answers)
Closed 7 months ago.
I am currently working on a div element containing a radio button and a label. It looks like this:
When hovering over the div element, I am applying a border to that div so the result looks like this:
The problem here is, that the moment the border is visible, you can see that the elements move 2px down and right because of the border size. The border size is 2px.
How can I prevent this from happening?
Here is the relevant css I am using:
.container {
display: inline-flex;
align-items: center;
}
.label {
display: inline-block;
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
margin-left: 15px;
}
.radioButton {
width: 18px;
height: 18px;
padding: 0;
border: 2px solid white;
margin: 0;
appearance: none;
background-color: #fff;
border-radius: 100%;
box-shadow: 0 0 0 2px #002750;
transition: all ease-in 0.2s;
}
.radioButton:checked {
background-color: #002750;
}
.radioButton:focus,
.radioButton:hover {
box-shadow: 0 0 0.15em 0.2em #0c64e7;
}
.container:focus,
.container:hover {
border-width: 2px;
border-style: solid;
border-color: #419BF9;
border-radius: 15px 5px 5px 15px;
}
<div class="container">
<input type="radio" class="radioButton">
<label class="label">Copy</label>
</div>
I appreciate every help!
The easiest solution is to provide a transparent border to the div that you are adding a border to when hovering.
.container {
display: inline-flex;
align-items: center;
border: 2px solid transparent;
}
You can use transform: translate(-2px, -2px) to maintain it in the same position after hover
.container:focus, .container:hover {
border-width: 2px;
border-style: solid;
border-color: #419BF9;
border-radius: 15px 5px 5px 15px;
transform: translate(-2px, -2px);
}
Another way is by adding margin:-2px 0 0 -2px; to container:focus and containr:hover
.container {
display: inline-flex;
align-items: center;
}
.label {
display: inline-block;
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
margin-left: 15px;
}
.radioButton {
width: 18px;
height: 18px;
padding: 0;
border: 2px solid white;
margin: 0;
appearance: none;
background-color: #fff;
border-radius: 100%;
box-shadow: 0 0 0 2px #002750;
transition: all ease-in 0.2s;
}
.radioButton:checked {
background-color: #002750;
}
.radioButton:focus,
.radioButton:hover {
box-shadow: 0 0 0.15em 0.2em #0c64e7;
}
.container:focus,
.container:hover {
margin:-2px 0 0 -2px;
border-width: 2px;
border-style: solid;
border-color: #419BF9;
border-radius: 15px 5px 5px 15px;
}
<div class="container">
<input type="radio" id="btn" class="radioButton">
<label class="label">Copy</label>
</div>
I have the following flex item (#globalSearchContLi) inside a flex-container. The container is an unordered list.
My problem is that I'm creating a fun looking search bar with a half-sphere submit button. The button is pretty much attached to the search bar with inline-block and margin properties.
This bundle (the search bar and button) won't center in the div any way I try to.
I tried setting #globalSearchCont with a specific width and auto side margins, but the whole flexbox presentation won't display correctly on mobile.
Any suggestions/advice? Thanks in advance.
#globalSearchContLi {
flex-grow: 7;
margin: 0px 15px;
flex-basis: 100px;
}
#globalSearchContLi {
flex-grow: 7;
margin: 0px 15px;
flex-basis: 100px;
}
#munchGlobalSearchbar {
width: 240px;
height: 50px;
/* box-shadow: 0 0 0 1px#000,0 0 0 3px #FFF, 0 0 0 5px #333; */
font-weight: 300;
font-size: 1.6rem;
border-radius: 10px;
display: inline-block;
margin-top: 20px;
text-align: center;
background-color: #edad0c;
border-bottom: 2px solid #333;
border-top: 2px solid #333;
border-left: 2px solid #333;
}
#munchGlobalSearchbar::placeholder {
color: #000;
}
#globalSearchBtn {
background-image: url(../imgs/addOn/panEmoji.png);
width: 50px;
height: 51px;
margin: 0px 0px -17px -12px !important;
border-bottom-right-radius: 50%;
border-top-right-radius: 50%;
display: inline-block;
border: 2px solid #333;
background-color: #38b32b;
transition: .2s all ease;
}
.backImageCon {
background-repeat: no-repeat;
background-size: contain;
background-position: center;
}
<li id="globalSearchContLi">
<div id="globalSearchCont">
<input placeholder="Search..." type="textbox" name="globalSearch" id="munchGlobalSearchbar">
<div id="globalSearchBtn" class="backImageCon"></div>
</div>
</li>
Use justify-content: center on the parent to horizontally center the button elements.
#globalSearchContLi {
list-style-type: none;
margin-left: 0;
}
#globalSearchCont {
display: flex;
justify-content: center;
height: 50px;
}
#munchGlobalSearchbar {
width: 240px;
font-weight: 300;
font-size: 1.6rem;
border-radius: 10px;
text-align: center;
background-color: #edad0c;
border-bottom: 2px solid #333;
border-top: 2px solid #333;
border-left: 2px solid #333;
}
#munchGlobalSearchbar::placeholder {
color: #000;
}
#globalSearchBtn {
background-image: url(../imgs/addOn/panEmoji.png);
width: 50px;
border-bottom-right-radius: 50%;
border-top-right-radius: 50%;
border: 2px solid #333;
background-color: #38b32b;
transition: .2s all ease;
margin-left: -10px;
}
.backImageCon {
background-repeat: no-repeat;
background-size: contain;
background-position: center;
}
ul {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
<ul>
<li id="globalSearchContLi">
<div id="globalSearchCont">
<input placeholder="Search..." type="textbox" name="globalSearch" id="munchGlobalSearchbar">
<div id="globalSearchBtn" class="backImageCon"></div>
</div>
</li>
</ul>
I'm struggling with aligning text to div.
I currently have this:
But I want to achieve this (I have just edited a screenshot to show you what I mean):
My code looks as follows:
HTML
<div class="regionHeader">
<div class="regionArrow"></div>
<h2>Some long header that should be aligned to the left next to the div with arrow</h2>
</div>
CSS
.regionHeader {
border-bottom: 1px solid #ffd800;
cursor: pointer;
}
.regionArrow {
border-right: 4px solid #ffd800;
border-bottom: 4px solid #ffd800;
width: 13px;
height: 13px;
transform: rotate(45deg);
float: left;
margin-top: 11px;
margin-right: 13px;
margin-bottom: 0px;
margin-left: 3px;
}
h2 {
font-family: changa-regular;
font-size: 2em;
}
I have already played with display and floats, but it either doesn't work or I'm doing it incorrectly.
You can either simply use a padding-left on your heading:
.regionHeader {
border-bottom: 1px solid #ffd800;
cursor: pointer;
}
.regionArrow {
border-right: 4px solid #ffd800;
border-bottom: 4px solid #ffd800;
width: 12px;
height: 13px;
transform: rotate(45deg);
float: left;
margin-top: 11px 13px 0 3px;
}
h2 {
font-size: 2em;
padding-left: 1.2em; /* <- added */
}
<div class="regionHeader">
<div class="regionArrow"></div>
<h2>Some long header that should be aligned to the left next to the div with arrow</h2>
</div>
Or use a flexbox approach and remove the float.
.regionHeader {
border-bottom: 1px solid #ffd800;
cursor: pointer;
display: flex; /* <- added */
}
.regionArrow {
border-right: 4px solid #ffd800;
border-bottom: 4px solid #ffd800;
width: 16px;
height: 13px;
transform: rotate(45deg);
margin: 30px 15px;
}
h2 {
font-family: changa-regular;
font-size: 2em;
}
<div class="regionHeader">
<div class="regionArrow"></div>
<h2>Some long header that should be aligned to the left next to the div with arrow</h2>
</div>
Browser support for flexbox is pretty good. Don't forget to add proper vendor prefixes.
I have used this question to create buttons. But when I try to create a bottom left shadow to the button the white area will appear as:
.btn {
height: 40px;
background: red;
width: 128px;
margin: 15px 5px 15px 5px;
cursor: hand;
text-align: center;
vertical-align: middle;
line-height: 40px;
-webkit-box-shadow: 2px 3px 3px #666666;
-moz-box-shadow: 2px 3px 3px #666666;
box-shadow: 2px 3px 3px #666666;
}
.btn:before {
width: 0px;
height: 20px;
border-left: 20px solid red;
border-top: 20px solid white;
float:right;
content:"";
}
.btn:hover{
-webkit-box-shadow: 1px 1px 1px #666666;
-moz-box-shadow: 1px 1px 1px #666666;
box-shadow: 1px 1px 1px #666666;
}
.userNave{
width: 140px;
}
<nav class="userNave">
<div class="btn"
onClick="alert('Hi')"
style="">Click Me Me</div>
<div class="btn"
onClick="alert('Hello')"
style="">No Click Me </div>
</nav>
Is there any workaround for this. Or even better. Is there any way to create a true Trapezoid button so that it will work with the shadow and there will be no problem with the background matching.
This is the best I could come up with, using the pseudo elements as the background.
.btn {
position: relative;
height: 40px;
width: 128px;
margin: 15px 5px 15px 5px;
padding: 0 10px 5px 0;
cursor: hand;
text-align: center;
vertical-align: middle;
line-height: 40px;
overflow: hidden;
}
.btn:before {
position: absolute;
left: -23px; top: 0;
width: calc(100% - 5px);
height: 50%;
background: red;
content: "";
z-index: -1;
transform: skewX(45deg);
transform-origin: left top;
box-shadow: 0px 1px 3px 1px #666666;
}
.btn:after {
position: absolute;
left: 0; top: 50%;
width: calc(100% - 5px);
height: calc(50% - 5px);
background: red;
content: "";
z-index: -1;
box-shadow: 2px 2px 4px #666666;
}
.userNave {
width: 140px;
}
<nav class="userNave">
<div class="btn" onClick="alert('Hi')" style="">Click Me Me</div>
<div class="btn" onClick="alert('Hello')" style="">No Click Me</div>
</nav>
A SVG image would most likely be the better choice though.
.btn {
position: relative;
height: 40px;
width: 128px;
margin: 15px 5px 15px 5px;
padding: 0 0 5px 0;
cursor: hand;
text-align: center;
vertical-align: middle;
line-height: 40px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' id='trapezoid' viewbox='0 0 118 45' preserveAspectRatio='none'%3E %3Cfilter id='dropshadow' height='130%25'%3E %3CfeGaussianBlur in='SourceAlpha' stdDeviation='3'/%3E %3C!-- stdDeviation is how much to blur --%3E %3CfeOffset dx='2' dy='2' result='offsetblur'/%3E %3C!-- how much to offset --%3E %3CfeMerge%3E %3CfeMergeNode/%3E %3C!-- this contains the offset blurred image --%3E %3CfeMergeNode in='SourceGraphic'/%3E %3C!-- this contains the element that the filter is applied to --%3E %3C/feMerge%3E %3C/filter%3E %3Cpath d='M0,0 L100,0 L120,20 L120,40 L0,40z' fill='red' style='filter:url(%23dropshadow)'%3E%3C/path%3E %3C/svg%3E");
}
.userNave {
width: 140px;
}
<nav class="userNave">
<div class="btn" onClick="alert('Hi')" style="">Click Me Me</div>
<div class="btn" onClick="alert('Hello')" style="">No Click Me</div>
</nav>
In your example, you can't add a proper box-shadow without having these white parts on each side. That is because the CSS border colouring the grey shaped trapeziod DIV.
In the example above, they are using an .SVG file (image), since it is an image, the original shape of it is a trapezoid, not a rectangle with white side like yours.
You will need to draw an .svg in the shape and color you want, and then add a shadow to the element itself.
Here are more informations about SVG.
I hope it helps.
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;
}