Parent with overflow-x: hidden hides vertically translated child - css

Let's say I want to hide container's horizontal content, but at the same time time I want to translate child elements. Adding overflow-x: hidden; to the parent causes it to clip vertically translated children too. Why does this happen and how can I work around it?
.content{
margin: 1rem;
}
.rail {
display: flex;
padding: 0.5rem;
background: #EEE;
overflow-x: hidden;
}
.card {
padding: 1rem;
border: 1px solid gray;
background: #FFF;
}
.card:hover {
transform: translate3d(0px, -1.5rem, 0px);
}
<div class="content">
<div class="rail">
<div class="card">CONTENT</div>
</div>
</div

I faced a similiar issue recently as well, a workaround I found was just to wrap a new container around the transformed element:
.content {
margin: 1rem;
}
.rail {
display: flex;
padding: 0.5rem;
background: #EEE;
}
.card {
padding: 1rem;
border: 1px solid gray;
background: #FFF;
}
.card:hover {
transform: translate3d(0px, -1.5rem, 0px);
}
<div class="content">
<div class="rail">
<div class="card-container">
<div class="card">CONTENT</div>
</div>
</div>
</div>

As far as I can see, yes you have to make the rail higher.
However, you can do this and make it look like it is not bigger. See the following CSS:
.content{
margin: 1rem;
/* Just to help show what is happening */
padding: 1rem;
background: pink;
/* Parameterise the work around */
--railPadding: 0.5rem;
--vertTranslate: -1.5rem;
--extraSpace: calc(0px - (var(--railPadding) + var(--vertTranslate)));
}
.rail {
/* The important constraints. */
display: flex;
overflow-x: hidden;
/* Make the extra space without changing the content box of the rail. */
padding: calc(var(--railPadding) + var(--extraSpace)) var(--railPadding) var(--railPadding) var(--railPadding);
/* Offset the extra height by backing over the margin. */
margin-top: calc(0px - var(--extraSpace));
/* Make the rail look like it has not backed over anything by making the overlap transparent. */
background: linear-gradient(to top, #EEE calc(100% - var(--extraSpace)), rgba(0, 0, 0, 0) var(--extraSpace));
}
.card {
padding: 1.0rem;
border: 1px solid gray;
background: #FFF;
}
.card:hover {
transform: translate3d(0px, var(--vertTranslate), 0px);
}

Related

How to make rounded corners in css on different background [duplicate]

This question already has an answer here:
Is there a better way to create convex / concave borders on an element
(1 answer)
Closed 1 year ago.
I want to create rounded corners of the section (I can do it with border-radius), but those sections intersect with each other and besides border radius theres this weird cut from the other section (see image)
Is there any way I can code it without using pictures of those sections?
You can also achieve that using the :after pseudo element for the top section and bring that element back using z-index so it won't overlap the bottom section.
Here's an example:
.container {
width: 50%;
height: 200px;
display: flex;
margin: 0 auto;
overflow: hidden;
border-radius: 5px;
flex-direction: column;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
}
.top-section {
flex-grow: 1;
background-color: #1B2149;
border-radius: 0 0 0 25px;
position: relative;
}
.top-section:after {
content: " ";
z-index: -1;
right: 0;
bottom: -30px;
height: 30px;
width: 40px;
position: absolute;
background-color: inherit;
}
.bottom-section {
flex-grow: 1;
border-radius: 0 25px 0 0;
background-color: #FFFFFF;
}
<div class="container">
<div class="top-section"></div>
<div class="bottom-section"></div>
</div>
Yes, you can create an element with absolute position with a pseudo-element and using a background and transparent combination create a curve and place it using absolute positioning.
however, in this case you can get the result with a much simpler solution.
All you need to do is wrap each area within a div that has the other background and show it with a border radius.
#container {
background-color: #e4e4e4;
width: 400px;
padding: 0 20px;
border: 1px solid #333;
}
.placeholder {
height: 200px;
}
#top_div_back {
background-color: #fff;
}
#top_div_front {
background-color: #1a2048;
border-bottom-left-radius: 25px;
}
#bottom_div_back {
background-color: #1a2048;
}
#bottom_div_front {
background-color: #fff;
border-top-right-radius: 25px;
}
<div id="container">
<div id="top_div_back">
<div id="top_div_front" class="placeholder">
</div>
</div>
<div id="bottom_div_back">
<div id="bottom_div_front" class="placeholder">
</div>
</div>
</div>
This is by far the easiest and most stable solution for your needs.

How can I make this transition work and let the hamburger icon stay on top?

I am new to programming, just started a few months ago, but trying to create a portfolio page, I have watched other peoples examples, and trying to create my own.
My problem is that I am trying to transition the navbar with a hamburger icon, which is working, but I have set the navbar to be fixed(this also works) and span across the viewport, which doesn't work. The width and the height of the element is just as much as my list elements. I cannot see where the problem is, also when I toggle the class, i.e. click the button to close the navbar it does not transition it just disappears. I will past my code here, will be glad if somebody can give me a hint. Also, I have the hamburger icon on the right and title on the left which I want to stay on top always, added z-index but it does not work.. Thanks, and apologies if I did not make my question very clear.
HTML code
<body>
<div>
<!-- create navbar with hamburger icon -->
<nav class="navbar">
<h2 class="myName">this.szabi<span class="braces">( )</span></h2>
<div class="menu-btn">
<div id="menuButtonBurger"></div>
</div>
</nav>
<div class="info">
<ul>
<li>About Me</li>
<li>Projects</li>
<li>Contact</li>
</ul>
</div>
<section id="about"></section>
<!-- create a small introduction place with a picture -->
<!-- create a div for technologies ive learnt -->
<!-- create a div to place my projects -->
<!-- create a div for contact information, social icons -->
<!-- create a footer -->
</div>
<script type="text/javascript" src="script.js"></script>
</body>
CSS code
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.navbar {
background-color: transparent;
width: 100%;
position: fixed;
display: flex;
justify-content: space-between;
}
.myName {
font-family: Comfortaa;
font-weight: 500;
color: #f05454;
z-index: 101;
}
.braces {
font-size: 2rem;
}
.menu-btn {
position: relative;
width: 3rem;
height: 3rem;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
border: 3px solid #f05454;
border-radius: 50%;
z-index: 102;
}
#menuButtonBurger {
width: 2rem;
height: 0.25rem;
background-color: #f05454;
border-radius: 5px;
}
#menuButtonBurger::before,
#menuButtonBurger::after {
content: "";
position: absolute;
width: 2rem;
height: 0.25rem;
background-color: #f05454;
border-radius: 5px;
}
#menuButtonBurger::before {
transform: translateY(-8px);
}
#menuButtonBurger::after {
transform: translateY(8px);
}
.info {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: -webkit-linear-gradient(-45deg, #000000, #434343);
background: linear-gradient(-45deg, #000000, #434343);
display: flex;
justify-content: center;
align-items: center;
color: white;
font-family: Comfortaa, Helvetica, sans-serif;
font-size: 2.5rem;
font-weight: bold;
line-height: 2.5;
z-index: 100;
transform: translateX(1500px);
}
.info .open {
background: -webkit-linear-gradient(-45deg, #000000, #434343);
background: linear-gradient(-45deg, #000000, #434343);
transform: translateX(-1500px);
transition: all 500ms linear;
}
.info ul li {
list-style: none;
}
.info li a,
.info li a:link,
.info li a:visited,
.info li a:active {
text-decoration: none;
color: #fff;
}
.info li a:hover {
color: #f05454;
}
/* change it */
#about {
width: 100%;
height: 1000px;
background-color: teal;
}
JavaScript code
const hamburger = document.querySelector('.menu-btn');
const info = document.querySelector('.info');
const list = document.querySelector('ul');
hamburger.addEventListener('click', menuToggle);
function menuToggle() {
console.log('clicked')
info.classList.toggle('open');
list.classList.toggle('open');
}
The width and the height of the element is just as much as my list elements.
Yes, that is the default behavior of elements in a div.
To change that, either define a custom width for your info div in your existing CSS section, just like that:
.info .open {
background: -webkit-linear-gradient(-45deg, #000000, #434343);
background: linear-gradient(-45deg, #000000, #434343);
transform: translateX(-1500px);
transition: all 500ms linear;
width: 270px; // Defining a custom width for the div
}
Or set a custom padding for the ul elements, like that:
.info ul {
padding-left: 30px; // Defining a padding to every list item, which causes outer div to grow according to that.
padding-right: 30px;
}
Now, regarding the transition. I tried to do something that would not change your code so much. First, We add a html class for handling when the info menu and the ul are closed:
div class="info closed">
<ul class="closed">
<!-- Rest of the code... -->
Then we create a new CSS code for handling the closed transition:
.info .closed {
background: -webkit-linear-gradient(-45deg, #000000, #434343);
background: linear-gradient(-45deg, #000000, #434343);
transition: all 500ms linear;
}

Create line after text with css

Im trying to make a line after each of my h2 tags. I canĀ“t figure out how I should tell the width, cause the lenght of the h2 headlines is differ from h2 to h2.
I use the :after method to create lines
h2:after {
position: absolute;
content: "";
height: 2px;
background-color: #242424;
width: 50%;
margin-left: 15px;
top: 50%;
}
Check code here: http://jsfiddle.net/s9gHf/
As you can see the line get too wide, and make the website too wide.
You could achieve this with an extra <span>:
h2 {
font-size: 1rem;
position: relative;
}
h2 span {
background-color: white;
padding-right: 10px;
}
h2:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 0.5em;
border-top: 1px solid black;
z-index: -1;
}
<h2><span>Featured products</span></h2>
<h2><span>Here is a very long h2, and as you can see the line get too wide</span></h2>
Another solution without the extra <span> but requires an overflow: hidden on the <h2>:
h2 {
font-size: 1rem;
overflow: hidden;
}
h2:after {
content: "";
display: inline-block;
height: 0.5em;
vertical-align: bottom;
width: 100%;
margin-right: -100%;
margin-left: 10px;
border-top: 1px solid black;
}
<h2><span>Featured products</span></h2>
<h2><span>Here is a very long h2, and as you can see the line get too wide</span></h2>
External examples: First, Second
There's no need for extra wrappers or span elements anymore. Flexbox and Grid can handle this easily.
h2 {
display: flex;
align-items: center;
}
h2::after {
content: '';
flex: 1;
margin-left: 1rem;
height: 1px;
background-color: #000;
}
<h2>Heading</h2>
using flexbox:
h2 {
display: flex;
align-items: center;
}
h2 span {
content: "";
flex: 1 1 auto;
border-top: 1px solid #000;
}
<h2>Title <span></span></h2>
Here is another, in my opinion even simpler solution using a flex wrapper:
.wrapper {
display: flex;
align-items: center;
}
.line {
border-top: 1px solid grey;
flex-grow: 1;
margin: 0 10px;
}
<div class="wrapper">
<p>Text</p>
<div class="line"></div>
</div>
External link
I notice that there are some flexbox implementations but they don't explain why and how to use it.
First, we just need one element, for this example h2.
We will change the element's display behavior to display: flex
Then, we center vertically its child elements using align-items: center.
h2 {
...
display: flex;
align-items: center;
}
Then, let's draw the line using the pseudo-element after.
We add '' to the content property to draw the element (we must).
Now lets make it flexible using flex: auto. This means that our element is sized according to its width and height properties. It grows to absorb any extra free space in the flex container, and shrinks to its minimum size to fit the container. This is equivalent to setting flex: 1 1 auto.
Then we add an small gap between the text and the line using margin-left: 1rem.
Finally, we draw a black line using border-top: 1px solid #000.
h2::after {
content: '';
flex: auto;
margin-left: 1rem;
border-top: 1px solid #000;
}
Here is functional snippet.
h2 {
font-size: 1em; /* not needed */
display: flex;
align-items: center;
}
h2::after {
content: '';
flex: auto;
margin-left: 1rem;
border-top: 1px solid #000;
}
<h2>Normal title</h2>
<h2>Very long title to test the behavior of the element when the content is wider</h2>
This is the most easy way I found to achieve the result: Just use hr tag before the text, and set the margin top for text. Very short and easy to understand! jsfiddle
h2 {
background-color: #ffffff;
margin-top: -22px;
width: 25%;
}
hr {
border: 1px solid #e9a216;
}
<br>
<hr>
<h2>ABOUT US</h2>
Here is how I do this:
http://jsfiddle.net/Zz7Wq/2/
I use a background instead of after and use my H1 or H2 to cover the background. Not quite your method above but does work well for me.
CSS
.title-box { background: #fff url('images/bar-orange.jpg') repeat-x left; text-align: left; margin-bottom: 20px;}
.title-box h1 { color: #000; background-color: #fff; display: inline; padding: 0 50px 0 50px; }
HTML
<div class="title-box"><h1>Title can go here</h1></div>
<div class="title-box"><h1>Title can go here this one is really really long</h1></div>
I am not experienced at all so feel free to correct things. However, I tried all these answers, but always had a problem in some screen.
So I tried the following that worked for me and looks as I want it in almost all screens with the exception of mobile.
<div class="wrapper">
<div id="Section-Title">
<div id="h2"> YOUR TITLE
<div id="line"><hr></div>
</div>
</div>
</div>
CSS:
.wrapper{
background:#fff;
max-width:100%;
margin:20px auto;
padding:50px 5%;}
#Section-Title{
margin: 2% auto;
width:98%;
overflow: hidden;}
#h2{
float:left;
width:100%;
position:relative;
z-index:1;
font-family:Arial, Helvetica, sans-serif;
font-size:1.5vw;}
#h2 #line {
display:inline-block;
float:right;
margin:auto;
margin-left:10px;
width:90%;
position:absolute;
top:-5%;}
#Section-Title:after{content:""; display:block; clear:both; }
.wrapper:after{content:""; display:block; clear:both; }

Divider with centred image in CSS?

How can I make this divider with a logo in the centre in CSS? ! I've been trying but didn't even got close yet. What would be the best way to achieve this.
Thank you!
Update
This needs to be placed on top of a bg image so the gaps around the logo must be transparent.
Sorry guys this one is a little tricky I know...
Here's the PNG
Well, if you're background is totally plain then it's relatively straight forward.
The HTML
<header>
<div id="logo">
<img src="http://placehold.it/200x100" alt="Placeholder Image" />
</div>
</header>
The CSS
body {
margin: 0;
background: white;
}
#logo {
width: 200px; /* Width of image */
padding: 40px; /* Creates space around the logo */
margin: 0 auto; /* Centers the logo */
background: white; /* Must be same as body */
position: relative; /* Brings the div above the header:after element */
}
#logo img {
display: block;
}
/* :after pseudo element to create the horizontal line */
header:after {
content: '';
display: block;
width: 100%;
height: 1px;
background: #ccc;
margin-top: -90px; /* Negative margin up by half height of logo + half total top and bottom padding around logo */
}
Working demo here.
EDIT
For situations where the body (or containing div) is not a solid colour, try the following:
HTML
<div id="header">
<div id="logo">
<img src="http://placehold.it/200x100" alt="Placeholder Image" />
</div>
</div>
CSS
body {
margin: 0;
}
#logo {
width: 100%;
}
#logo, #logo:before, #logo:after {
float: left;
}
#logo:before, #logo:after {
content: '';
width: 50%;
min-height: 100px; /* height of image */
border-bottom: 1px solid #ccc;
margin-top: -50px;
}
#logo:before {
margin-left: -120px;
}
#logo:after {
margin-right: -120px;
}
#logo img {
float:left;
padding: 0 20px;
}
Working demo here.
OR even an example based on display: table, but this goes a bit wonky when resizing.
http://jsbin.com/ITAQitAv/10/edit
This would be one approach:
.hr {
height: 50px; /* imageheight */
background: #fff url(http://placekitten.com/100/50) no-repeat center;
}
.hr hr {
top: 50%;
position: relative;
}
<div class="hr"><hr /></div>
This would be another:
.hr2{
display: block;
border-top: 2px solid black;
height: 2px;
}
.hr2 img {
display: block;
margin: auto;
margin-top: -31px; /*img-height /-2 + height / 2 */
/* adjustments for 'margin' to border */
padding: 0 20px;
background: #fff;
}
<div class="hr2"><img src ="http://placekitten.com/100/60"></div>
Demos: http://plnkr.co/edit/DznVp8qB9Yak8VfHVzsA?p=preview

Connect two elements keeping responsive value

I am creating a simple real estate website and am currently creating the listing page. I would like a product very similar to this here. I cannot gain ideas from the code because I am using the skeleton framework. This is my current progress and code or below.
The two elements; photo of property and body of text are apart (there's a gap in the middle).
And also if you resize the browser the listing is not rendered as a vertical rectangle as it is supposed to.
My raw questions are:
1) How do I connect the image and the body text so there is no space inbetween?
2) How do I make the body text and image the same width when the body text needs to collapse underneath the photo? (When resizing browser or on device)
The HTML
<div class="five columns image">
<img src="Properties/9-Walter-Street-Claremont/Listing.jpg" alt="Listing">
</div>
<div class="ten columns body-info">
<h2>Walter Street <span>$2500/wk</span></h2>
<h3>Claremont, 6010</h3>
<p>Lorem Ipsum</p>
<div class="info">
<ul>
<li><img src="img/bedrooms.png"> 5</li>
<li><img src="img/bathrooms.png"> 3</li>
</ul>
</div>
</div>
The CSS
.body-info {
background-color: #fff;
height: 200px;
-webkit-box-shadow: 0px 1px 1px rgba(0,0,0,0.1);
-moz-box-shadow: 0px 1px 1px rgba(0,0,0,0.1);
box-shadow: 0px 1px 1px rgba(0,0,0,0.1);
margin-bottom: 30px;
padding: 0px;
}
.image a img:hover {
background-color: rgba(0,0,0,0.5);
background-image: url("img/eye.png");
background-position: center center;
background-repeat: no-repeat;
}
.body-info h2 a {
transition: color 0.2s ease-in;
-webkit-transition: color 0.2s ease-in;
color: #428f9c;
font-size: 23px;
font-weight: normal;
}
.image {
width: 270px;
float: left;
}
.body-info {
margin-left: 280px;
}
.body-info h2 a:hover {
color: #0b7587;
}
.body-info span {
margin-right: 15px;
color: #444;
}
.body-info p {
color: #777;
font-size: 16px;
}
.body-info ul {
list-style: none;
}
.body-info ul li {
color: #777;
}
Thank you in advance!
To help you a little bit on the way, you could use the #media on CSS.
With that you can change the style when for example the screen is smaller than a specific width.
HTML:
<div class="wrap">
<div class="image">img</div>
<div class="info">info</div>
</div>
CSS:
.wrap {
background: gray;
min-height: 200px;
padding: 10px;
}
.image {
width: 270px;
height: 180px;
background: lightgray;
display: inline-block;
}
.info {
background: lightsteelblue;
display: inline-block;
}
#media only screen and (max-width:600px){
.image, .info {
width: 100%;
display: block;
}
}
So what the style does is when you have a fullscreen it shows .image and .info next to each other (using display: inline-block;.
When the screen gets resized and smaller than 600px, for both the divs the display property will change to block, making them appear under each other.
JSFiddle DEMO
Referring to the example in your post, the only thing you need to do is to make or find a script that resizes your image when the screen gets smaller.
Hope this helps you.

Resources