SVG, static vs absolute vs relative, and coordinates - mobile

I have to begin by apologizing for my inability to grasp what can only be described as logic. I have photoshopped the proposed layout. Here is a snapshot:
Layout:
I do not have example code. This is because I can't write code if I don't know how to approach it. Which brings me to:
I'm trying to design an overlayed SVG navigation menu (achieved as red rectangle + trapezoid polygon) that's always at the bottom of the page and pops out when clicked/touched to show expanded menu options. From what I've read and understand, using absolute (do I mean "static" here?) values to define position (pixels vs percent) is bad design because of wildly varying resolutions and DPI across many devices. I've tried a simple example in W3's Try Me editor just to get a grasp of how I'll position the red rectangle. I used:
<svg>
<rect width="100%" height="10%" x="0%" y="90%" style="fill:#ff0000;" />
</svg>
This places a red rectangle spanning the entire width of the page (regardless of resolution) at the bottom, without clipping the rectangle outside the viewport. Success! Right..? Well.. the menu isnt just a rectangle. There will be a polygon trapezoid "bump" in the center where the hamburger menu icon will go. This led to my problem. The polygon is defined by coordinates. And coordinates are absolute (or static?). Defined in pixels or inches or various other units. It doesn't support percentages from what I've read, and I'm not sure that's what I'd want anyway. Using percentages means that rectangle will stretch to fill whatever "10%" of the viewport height is. On a desktop it will be thinner than on mobile in portrait. It also means that the polygon won't necessarily be centered, as 550px will not always represent 50% (example values).
I'm going about this wrong. Help me find the proper logic for laying out this page. Honestly, after this, dynamically loading content underneath seems like the easy part.
FYI, I'd like to avoid JS and plugins as much as possible. By that I mean, I don't want to use them AT ALL. CLARIFICATION: If it can be avoided.
I'd be more than happy to clarify ad nauseum. Though this is the first time I'm actively using SO, and have only been previously exposed to it via google searches.
EDIT: I'm asking in the context of working with SVG, since this is what I'm having trouble finding proper documentation on. What I find is blog posts and "download this code/plugin to achieve this effect" instead of conceptual descriptions of how to achieve those effects. I've coded websites (personal, not professional) when HTML4 and CSS2 were the tools. Back then, you didn't have to worry about mobile phones. You could work within commonly used resolutions and aspect ratios (16:9 and 4:3 were pretty much it). But now those devices have wildly varying pixel densities and methods of rendering and 2 aspect ratios (portrait and landscape). I'm going from a background in fairly static webpages to mighty morphin' power webpages.
TLDR: How to do SVG? How do I put that trapezoid in the center, and have it retain its width/height regardless of the viewport's. Also, if I'm supposed to avoid absolute values (defining the height of the rectangle in pixels), how do I maintain a consistent height and proper positioning of the absolutely positioned polygon with relative values?
EDIT2: Thank you Paul! This has helped me immensely!! Being able to see the code and have it explained why and under what circumstance it does or does not work allows me to understand how this kind of tool is used. Especially when explained in context to to my own ideas. The CSS version is also very helpful. I've never used it beyond basic styling of elements. Both answers are excellent.

You don't need SVG for this. What you want to achieve is very easy to do with CSS.
var tabcontainer = document.querySelector(".tabcontainer");
var tabbutton = document.querySelector(".tabbutton");
tabbutton.addEventListener("click", function() {
tabcontainer.classList.toggle("open");
});
.container
{
width: 500px;
height: 500px;
position: relative;
background-color: black;
overflow: hidden;
}
.tabcontainer
{
position: absolute;
width: 100%;
bottom: -44px;
}
.tabcontainer.open
{
bottom: 0px;
}
.tabbutton
{
width:100px;
height: 0;
margin: 0 auto;
border-bottom: solid 20px red;
border-left: solid 16px transparent;
border-right: solid 16px transparent;
text-align: center;
cursor: pointer;
}
.tabbutton I
{
color: white;
}
.tabbody
{
width: 100%;
height: 60px;
background-color: red;
}
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet"/>
<div class="container">
<div class="tabcontainer">
<div class="tabbutton"><i class="fa fa-bars"></i></div>
<div class="tabbody"></div>
</div>
</div>
Using SVG
Generally, anything in an SVG gets scaled if the SVG scales. This can cause a problem when people want to create responsive SVG documents on a page.
However, with some particular SVG layouts it is possible to do what you want. In particular it is when you have simple designs with elements that need to sit in the corners, or centred on one of the sides.
Here's a version of the above CSS-only example that uses SVGs for the tab part.
How this works is that we are using the feature where, if the aspect ratio of the contents (defined by the viewBox) is different from the SVG (defined by width and height), the contents will automatically get scaled and centred.
So here we are defining a button that is 132x20, and putting it in an SVG that is 100% x 20. Where "100%" here is the width of the container/page. Because the aspect ratio is different, <polygon> representing the button will get automatically centred horizontally.
var tabcontainer = document.querySelector(".tabcontainer");
var tabbutton = document.querySelector(".tabbutton");
tabbutton.addEventListener("click", function() {
tabcontainer.classList.toggle("open");
});
.container
{
width: 100%;
height: 500px;
position: relative;
background-color: black;
overflow: hidden;
}
.tabcontainer
{
position: absolute;
width: 100%;
bottom: -44px;
}
.tabcontainer.open
{
bottom: 0px;
}
.tabbutton
{
fill: red;
cursor: pointer;
}
.tabbody
{
fill: red;
}
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet"/>
<div class="container">
<svg width="100%" height="80" class="tabcontainer">
<svg width="100%" height="20" viewBox="0 0 132 20" class="tabbutton">
<polygon points="16,0, 116,0, 132,20, 0,20"/>
<g transform="translate(66,0)" fill="white">
<rect x="-8" y="4" width="16" height="3"/>
<rect x="-8" y="9" width="16" height="3"/>
<rect x="-8" y="14" width="16" height="3"/>
</g>
</svg>
<rect y="20" width="100%" height="60" fill="red" class="tabbody"/>
</svg>
</div>

Related

scss and flexbox with logos in two different layouts

I am runnning across an issue in which I am not sure how to solve.
I have a grid system doing the following, BUT I will do a standard "div" solution. But here is my dilemna.
I have a "LogoComponent" That displays my companies logo on the left, and a partner's logo on the right.
I have two headers that display in two different conditions.
Centered Display (just the logos)
Left Aligned Display (left aligned logos, with other content on the right)
Caveats: the "partner logo" needs to confine within the div/space as sometimes the svg's are large, so I "can" offer a height, but not a width.
The image shows the two views. The "LogoComponent" I am having an issue as I was using a flexbox, but not sure that is gonna work since why I try to make it "left" as a component, it moves off the container div. Any ideas how to solve this?
I can solve it, but I feel it will be too generalized, as I'm looking to make this "LogoComponent" be wide enough for the logos, and then appropriately resize if the partner logo is there or not.
As said in the comment, you can center LogoComponent using margin: 0 auto; when it's the :only-child.
If it's not the only child, using margin-right: auto; will push all other content to the right as we are in a flex container.
.parent {
display: flex;
}
.LogoComponent {
margin-right: auto;
}
.LogoComponent:only-child {
margin: 0 auto;
}
/* for styling only */
.LogoComponent {
width: 50px;
height: 50px;
background-color: lightblue;
}
/* for styling only */
.OtherContent {
min-width: 200px;
background-color: lightgreen;
}
<div class="parent">
<div class="LogoComponent"></div>
</div>
<hr>
<div class="parent">
<div class="LogoComponent"></div>
<div class="OtherContent"></div>
</div>

Scaling all content in a div as if one element

I have two images placed on top of each other in a div with a caption underneath. I would like all of these elements to scale proportionally and together as the browser window shrinks.
Currently, the position of the two images shifts and does not look the same on mobile.
.highlightimg {
max-width: 700px;
height: auto;
width: 100%;
display: block;
position: relative;
z-index: 1;
padding-top: 10vh;
margin-right: 0;
}
.showcase {
max-width: 750px;
margin:auto;
position: relative;
margin-top: 8vh;
margin-bottom: 8vh;
}
.logo {
left:0;
max-width: 400px;
width: 100%;
height: auto;
position: absolute;
z-index: 3;
left: 0px;
}
.caption {
margin-top: 10px;
margin-bottom: 0;
padding: 0;
text-align: right;
}
<div class="showcase">
<img src="logo.png" class="logo">
<img src="highlight.jpg" class="highlightimg">
<p class="caption">Caption text here.</p>
</div>
The best analogy for the product I'm trying to receive is grouping multiple layers in Photoshop which allows you to scale all the layers together as if it was one single image. I am new to HTML/CSS, so I hope this makes sense and is not asked too often. Thanks for your help.
The position of the logo relative to the image under it will definitely shift. One of the reason for this is that you use vh unit for some properties, including the padding-top of the .highlightimg. 10vh in desktop and in mobile is different (they both have different viewport sizes). If you want both elements to stay the same, anchor both of them to the left and top by setting at least constant padding-top, margin-top, or the top properties (including the left padding and margin).
Maybe adding top: 18vh; to .logo could help. Using top: 10vh; instead of 18vh while also removing margin-top: 8vh from .showcase could also help. This is to ensure the top offset of the .highlightimg provided by its padding-top property scales proportionally with the top offset of the .logo. These solutions assume that there are no other elements in the page that will surely alter the location of these elements especially the ones without absolute position.
position: absolute; anchors your element to the screen. While position: relative; keep the element original rendered position and move the element itself relative to its original rendered position. Both have radically different impacts on where your elements get rendered on the screen. If you want both element to be exactly at the same location, use absolute for both and use same top and left properties.
Point is, don't rely on CSS properties to determine the exact location of your objects. If you want behavior like the one you describe in your Photoshop analogy you could find a way by using canvas.

How to make React Flexbox stretch to full screen height

I'm trying to create a React app that is optimized for mobile and am doing most of the layout using flexbox. I'm having trouble forcing the main container of my app to automatically expand to the full device height.
What rules can I apply, specifically to my html container <div id="react-app"></div> and my main app container <App></App> so that they will always stretch to the full screen height, even when their children wouldn't force them to do so?
You can use
height:100vh
for your App component, but it can looks not perfect on iOS Safari. Also you can set
html, body, #reactapp, .App {
height: 100%;
}
.App {
display: flex;
}
patelarpan's answer here seems to be the most concise solution:
You can achieve this by using "vh" units, and it's a more effective way than using percentages because you don't need to set every parent height to 100% if you want the child's height to be 100%.
.columnContainer {
display: flex;
height: calc(100vh - 60px);
}
Here is an example of the 60px app bar height being excluded from the viewport height.
I replaced the height line in patelarpan's example with this, since I don't have an app bar:
height: 100vh;
root > [data-reactroot] { height: 100% } in your CSS should work.
Or just the tag itself:
[data-reactroot] { ... }

Google maps markers labelClass animation not working properly

I am working on this project. I have an angular-google-map directive. I am overwritting defaults markers with labelClass.
CSS is working fine but does not hover.
.marker {
color: white;
border: 2px white solid;
border-radius: 50px;
text-align: center;
font-size: 20px;
letter-spacing: 0.1em;
font-weight: bold;
}
.marker:hover {
background-color: #C52183;
animation: pulse 1s;
}
/* ANIMATIONS */
#keyframes pulse {
50% {
transform: scale(4);
}
100% {
transform: scale(1);
}
}
If you check the example you can see an animation but not with real color. I sometimes get the real animation.
The full project is here.
pd: The problem can't be the animation, if i just try to change some css properties i dont get effect, so i think that the problem is with google maps and css.
I finally fixed this "bug".
The problem was on the MarkerWithLabel library but really isn't a bug, its just an impossibility (with this library). Checking the library we see :
// Set up the DIV for handling mouse events in the label. This DIV forms a transparent veil
// in the "overlayMouseTarget" pane, a veil that covers just the label. This is done so that
// events can be captured even if the label is in the shadow of a google.maps.InfoWindow.
// Code is included here to ensure the veil is always exactly the same size as the label.
this.eventDiv_ = document.createElement("div");
this.eventDiv_.style.cssText = this.labelDiv_.style.cssText;
I just modified the library so i don't create invisible div anymore and also i intercept events with real label. Now it's working under my requirements.
more info about the problem
demo working

Responsive website images the same height

I am trying to figure out how to make vertical and horizontal images at the same height. The height I need by vertical image. any ideas..
I was thinking to make the same height, but when I resize it shows like above...
css: max-height: 375px!important;
Update:
http://jsfiddle.net/LG2B8/
use min-height for horizontal image
min-height: height of vertical image;
as mention above, just give
css: height: 375px!important;
or
css: height: 4%0!important; //give in percent which is good for responsive ui
Some basic rule is
Height - apply when you need / know proper height
Max-height - apply when you want to restrict image height when exceed, this is good to used for images, you can also use for all other content too.
Min -height - apply when you want to minimum height should be, this is used for div/table/tr/td for responsive ui
I rectify and only change in css. just remove everything and add this. I added width for understand.
img
{
display: inline-block;
height: 300px;
width:200px;
}
img is html tag and all images will work as per "img" css attributes
Here is my solution:
Html:
<div class="w">
<div class="img"><img src="http://i.imgur.com/4OAz0Cf.jpg"/></div>
<div class="img o"><img src="http://i.imgur.com/EJsmCmT.jpg"/></div>
</div>
Css:
.w {
display: table-row;
}
.img{
width: 50%;
display: table-cell;
}
.img img{
min-height: 500px;
max-height: 500px;
}
.img.o img {
width: 100%;
}
Example

Resources